Skip to main content
A catalog is a feed of items (products, jobs, stores, offers) that belongs to an advertiser. Semi reads it on a schedule, keeps a version each time the items change, and can fan it out into campaigns, creative and seller feeds.

Supported formats

Every item needs an id. The first of id, sku, offer_id, item_id, product_id, job_id, store_id or guid is used. Field names are normalized to snake_case and the g: prefix is dropped. A feed can hold up to 5,000 items and 20 MB.

Connecting a feed

Ask Semi to connect a feed URL, or call sync_catalogs:
The feed is fetched right away. Each fetch is a refresh run (status, HTTP status, item count). When the items changed, a new version is stored with its change summary (added, updated, removed, unchanged). Inline items (items: [...]) work the same way without a URL. A feed is stale once twice its update frequency has passed without a successful refresh.

Transform and activation

A transform says how to fan the catalog out:
  • groupBy: item fields that split items into campaign groups (for example category)
  • creativePrompt: the creative brief per group; {field} placeholders take the group’s values
  • budgetPerGroup: the budget each campaign group starts with, in the advertiser’s currency
preview_catalog_activation_plan shows the campaign groups, creative assets and seller targets. execute_catalog_activation_plan creates one draft campaign per group (nothing is booked or spent), queues creative generation, and shares the catalog over AdCP sync_catalogs with the catalog-driven sellers you buy from. Sellers that take assembled creative wait for the creative; sellers without a catalog or creative handoff are skipped. Sellers with Audiences turned off in Connections are skipped too, with the reason “Audiences is turned off for this seller in Connections, so no feed data is shared with it.” The preview shows it, and execution checks the switch again.

Find and read catalogs

search with kind: "catalog" lists an advertiser’s live catalogs. Pass filter.advertiserId, and optionally filter.type and a query matched against the name and platform id. get with kind: "catalog", the catalogId and the advertiserId reads one catalog. Add include: ["items"] to get a page of its latest items too: up to 50, or fewer with limit. Narrow the items with filter: ids, gtins and tags (lists; an item matches any value), category (matched against the item’s category or product type) and query (contained in the id, title, name or description). itemsPage returns nextCursor, hasMore and how many items matched; pass cursor: itemsPage.nextCursor for the next page. Items here aren’t content-reviewed, so filter.status is refused with CAPABILITY_NOT_SUPPORTED. Any other include is listed in unavailableIncludes.

REST