Catalogs
Catalogs are all the ingredients you give sellers so they can assemble great outcomes for your brand. An e-commerce brand pushes its product catalog — SKUs, prices, images — so platforms can build sponsored product carousels. A travel advertiser pushes flights, hotels, and destination guides. An employer pushes job openings. A retailer pushes store locations and real-time inventory. A brand pushes its offerings, services, and seasonal campaigns. The richer the ingredients, the better the result. On AI platforms especially, your catalog data IS the creative input — the platform’s LLM assembles ads from your products, offerings, and brand context rather than serving a pre-built banner. But catalogs matter beyond AI media too: any seller that dynamically assembles ads from your data — retail media networks, commerce platforms, native ad networks — benefits from richer catalog feeds. Catalogs also connect directly to measurement. Push your store catalog and a seller can correlate ad delivery to store-level foot traffic. Push your product catalog and a retail media network can close the loop on purchase attribution. The same data that enables better creative also enables better measurement.How it works
- Formats declare what catalog types they need as
catalogasset types in theirassetsarray - Buyers sync catalogs to seller accounts via
sync_catalogs, with platform review and approval - Creatives reference synced catalogs by
catalog_idin the manifest’sassetsmap instead of embedding items inline
Which catalog type should I use?
Pick the catalog type that matches what you’re advertising.| I’m advertising… | Catalog type | Item schema | Required fields |
|---|---|---|---|
| Physical products / ecommerce SKUs | product | (your existing feed — Google Merchant, Shopify, etc.) | Depends on feed format |
| Job openings / recruitment | job | JobItem | job_id, title, company_name, description |
| Hotels / lodging | hotel | HotelItem | hotel_id, name, location |
| Vehicles (new or used) | vehicle | VehicleItem | vehicle_id, title, make, model, year |
| Flights / air travel | flight | FlightItem | flight_id, origin, destination |
| Real estate listings | real_estate | RealEstateItem | listing_id, title, address |
| University programs / courses | education | EducationItem | program_id, name, school |
| Travel destinations | destination | DestinationItem | destination_id, name |
| Mobile apps | app | AppItem | app_id, name, platform |
| Store locations | store | StoreItem | store_id, name, location |
| Campaigns, services, events, asset groups | offering | Offering | offering_id, name |
| Stock levels per location | inventory | (your existing feed format) | Depends on feed format |
| Sales, deals, pricing | promotion | (your existing feed format) | Depends on feed format |
feed_format and feed_field_mappings.
Where sync_catalogs fits
sync_catalogs is a buyer-to-seller task. The buyer pushes catalog feeds to the seller’s account, and the seller reviews and approves them before they can be used in campaigns.
The actors
| Actor | Role |
|---|---|
| Buyer | Calls sync_catalogs to push catalog feeds to the seller account. Owns the feed data (product URLs, inline items, inventory feeds). |
| Seller | Receives catalogs, validates items, runs content policy review, and returns per-item approval status. May also have existing catalogs from other sources (e.g., a retailer’s commerce platform). |
| Orchestrator | Coordinates the sequence — discovers format requirements, syncs catalogs, then submits creatives that reference them. |
Lifecycle position
sync_catalogs sits between format discovery and creative submission. The buyer must know what catalog types a format needs before syncing, and must have approved catalogs before creatives can reference them.
This is the same dependency order documented in Account state: sync_catalogs → sync_creatives → create_media_buy.
When to use sync_catalogs vs inline
Not every workflow requiressync_catalogs. Use it when:
- Platform review is needed — product catalogs that go through content policy checks (like Google Merchant Center)
- Feeds change frequently — point to a URL and let the platform re-fetch on a schedule
- Multiple creatives share the same feed — sync once, reference by
catalog_idfrom many creatives - The seller may already have the data — use discovery mode to see what’s already on the account
assets map work fine — no sync step needed.
Catalog types
Catalog types fall into two categories: structural types that describe the data’s role, and vertical types that define industry-specific item schemas.Structural types
| Type | Item Schema | Description |
|---|---|---|
offering | Offering | AdCP Offering objects — campaigns, vacancies, events, services |
product | (your existing feed format) | Ecommerce product entries (Google Merchant Center, Shopify, etc.) |
inventory | (your existing feed format) | Stock and availability per product per location |
store | StoreItem | Physical locations with addresses and catchment areas |
promotion | (your existing feed format) | Sales, deals, and promotional pricing |
Vertical types
Each vertical type has a defined AdCP item schema, so formats can declarecatalog_type: "hotel" and both sides know the required fields without consulting platform-specific documentation.
| Type | Item Schema | Maps To |
|---|---|---|
hotel | HotelItem | Google Hotel Center, Meta hotel catalogs |
flight | FlightItem | Google DynamicFlightsAsset, Meta flight catalogs |
job | JobItem | LinkedIn Jobs XML, Google DynamicJobsAsset, schema.org JobPosting |
vehicle | VehicleItem | Meta Automotive Inventory, Microsoft Auto Inventory feeds |
real_estate | RealEstateItem | Google DynamicRealEstateAsset, Meta home listing catalogs |
education | EducationItem | Google DynamicEducationAsset, schema.org Course |
destination | DestinationItem | Meta destination catalogs, Google travel ads |
app | AppItem | Google App Campaigns, Apple Search Ads, Meta App Ads, TikTok App Campaigns, Snapchat App Install Ads |
Typed catalog assets
Vertical catalog items support anassets array using the same OfferingAssetGroup structure as offering-type catalogs. This solves a concrete problem: standard catalog feeds have a single image_url field, but a hotel ad on Snap needs a 1080×1920 vertical image, a display banner needs a 1920×1080 landscape hero, and the advertiser’s logo goes in a separate slot. Without typed pools, a creative agent has to guess which image to use for which slot.
By providing assets grouped by role, each catalog item self-describes the images it carries:
asset_group_id vocabulary is not standardized at the protocol level — each format defines which group IDs it uses via offering_asset_constraints in the catalog asset’s requirements. Common conventions: images_landscape (16:9), images_vertical (9:16), images_square (1:1), logo, video.
Formats use field_bindings (see Format catalog requirements) to explicitly declare which template slot maps to which asset group.
The Catalog object
Schema URL:/schemas/core/catalog.json
test=false
| Field | Type | Required | Description |
|---|---|---|---|
catalog_id | string | For sync | Buyer’s identifier. Required for sync_catalogs. When used in creatives, references a synced catalog. |
name | string | No | Human-readable name |
type | CatalogType | Yes | Structural: "offering", "product", "inventory", "store", "promotion". Vertical: "hotel", "flight", "job", "vehicle", "real_estate", "education", "destination", "app". |
url | uri | No | External feed URL. Mutually exclusive with items. |
feed_format | FeedFormat | No | Format of external feed (google_merchant_center, facebook_catalog, shopify, linkedin_jobs, custom) |
update_frequency | string | No | Re-fetch schedule (realtime, hourly, daily, weekly) |
items | object[] | No | Inline catalog data. Item schema depends on type — each vertical type has a defined schema (HotelItem, JobItem, etc.). Mutually exclusive with url. |
ids | string[] | No | Filter to specific item IDs (offering_id or SKU) |
gtins | string[] | No | Filter product catalogs by GTIN (cross-retailer matching) |
tags | string[] | No | Filter to items with these tags (OR logic) |
category | string | No | Filter to items in this category |
query | string | No | Natural language filter |
conversion_events | EventType[] | No | Event types that represent conversions for items in this catalog (e.g., submit_application for job catalogs, purchase for product catalogs) |
content_id_type | ContentIdType | No | Identifier type for matching conversion event content_ids to catalog items. Values: sku, gtin, or vertical-specific IDs (job_id, hotel_id, etc.). Omit for custom identifier schemes. |
feed_field_mappings | CatalogFieldMapping[] | No | Normalization rules for external feeds. Maps non-standard field names, date formats, price encodings, and image URLs to the AdCP catalog item schema. See Feed field mappings. |
Conversion events
Theconversion_events field creates an explicit link between catalog items and the conversion tracking system. When a buyer syncs a catalog with conversion events declared, the platform knows which events to attribute to which catalog items. The event’s content_ids field carries the item IDs that connect back.
The content_id_type field declares what identifier type content_ids values represent — for example, gtin for cross-retailer product matching or job_id for job postings. This tells the platform which field on catalog items to match against. Omit content_id_type when using a custom identifier scheme.
Natural mappings by vertical:
| Catalog type | Primary event types |
|---|---|
product | purchase, add_to_cart |
hotel | purchase (booking) |
flight | purchase (booking) |
job | submit_application |
vehicle | lead, schedule (test drive) |
real_estate | lead, schedule (viewing) |
education | submit_application, complete_registration |
destination | purchase (booking) |
app | app_install, app_launch |
lead events alongside submit_application is perfectly valid.
Sourcing catalogs
There are three ways to provide catalog data, each suited to a different stage of maturity:Inline items
Any catalog type can embed items directly via theitems array. The item schema depends on the catalog type:
External feed URL
For feeds managed outside AdCP, point to a URL and let the platform fetch:Reference to synced catalog
For catalogs already on the account viasync_catalogs, reference by catalog_id:
Syncing catalogs
For catalogs that change frequently or require platform review, usesync_catalogs to give them a managed lifecycle on the account. This is the same pattern as sync_creatives — upsert semantics, async approval, per-item status.
Why sync?
- Platform review: Product catalogs go through content policy checks (like Google Merchant Center reviewing product listings).
sync_catalogsreturns per-item approval status. - Feed management: Point to an external feed URL and the platform re-fetches on a schedule, rather than the buyer re-syncing on every change.
- Multi-feed creatives: Formats can require multiple catalog types (product + inventory + store). Syncing catalogs separately lets creatives reference them by
catalog_id. - Approval workflow: Async responses notify the buyer when items are approved, rejected, or flagged for issues.
Sync request
Sync response with item-level review
Discovery mode
Omitcatalogs to list all catalogs on the account without modification:
Feed field mappings
External feeds rarely match the AdCP catalog item schema exactly. Field names differ, dates use platform-specific formats, prices may be encoded as integer cents, and images arrive as untyped URLs.feed_field_mappings provides a declarative normalization layer — included on the catalog object in the sync_catalogs request — so buyers can describe the translation without preprocessing every feed.
| Pattern | What it does |
|---|---|
feed_field + catalog_field | Renames a feed field to its schema equivalent (dot notation for nested fields) |
feed_field + asset_group_id | Places a URL into a typed asset pool on the item’s assets array |
value + catalog_field | Injects a static literal — useful for fields the feed omits (e.g., currency when always USD) |
Any of the above + transform | Applies a named coercion before writing |
Any of the above + default | Fallback when the feed field is absent or null |
Supported transforms
| Transform | Parameters | Example |
|---|---|---|
date | format (input date pattern), timezone (IANA, default UTC) | "YYYYMMDD" → "2025-03-01" |
divide | by (divisor, must be > 0) | 1000 ÷ 100 → 10.00 |
boolean | — | "yes" / "1" / "true" → true |
split | separator (default ,) | "spa,pool,wifi" → ["spa", "pool", "wifi"] |
price.amount and price.currency mappings above each write one field of the price object independently.
Item schema reference
Each vertical catalog type has a defined item schema with field tables, required fields, and starter templates. See Catalog item schemas for the complete reference with minimal and full examples for every vertical type.Format catalog requirements
Formats that render product listings, store locators, or promotional content declare what catalog feeds they need ascatalog asset types in their assets array. Each catalog asset carries requirements with fields like catalog_type, min_items, and required_fields. This tells buying agents which catalogs to sync before submitting creatives.
assets array after discovering formats, sync the required catalogs via sync_catalogs, then submit creatives that reference those catalogs.
Field bindings
Formats can declarefield_bindings inside the catalog asset’s requirements to explicitly map template slots to catalog item fields or asset pools. This makes the format self-describing — creative agents don’t have to guess which catalog field maps to which template slot.
format_group_id with catalog_item: true inside the catalog asset’s requirements.field_bindings:
kind | Required fields | What it does |
|---|---|---|
"scalar" | asset_id + catalog_field | Maps individual template asset to catalog item field (dot notation) |
"asset_pool" | asset_id + asset_group_id | Maps individual template asset to typed asset pool on the catalog item |
"catalog_group" | format_group_id + catalog_item: true | Iterates a format repeatable_group over catalog items |
Catalogs in creatives
Creatives reference catalogs as entries in the manifest’sassets map. Each catalog asset is keyed by the asset_id declared in the format (e.g., product_catalog). This is a data reference — it tells the creative what items to render (products for a carousel, locations for a store locator). It is not a campaign expansion directive; campaign structure and budget allocation are handled by create_media_buy packages.
When a format declares catalog asset types, the buying agent syncs the required catalogs to the account, then populates the corresponding asset keys in the creative’s assets map to reference the synced data.
Workflow
-
Discover format requirements — Call
list_creative_formatsand check the format’sassetsarray forcatalogasset types and theirrequirements. -
Sync catalogs — Use
sync_catalogsto push the required feeds to the account. Wait for approval. -
Submit the creative — Reference the synced catalog by
catalog_idin the corresponding asset key:
Offerings
Schema URL:/schemas/core/offering.json
An Offering is an individual promotable item within an offering-type catalog — a campaign, product, service, promotion, or vacancy. Each offering is a semantic unit with its own name, validity window, landing URL, creative assets, and geographic scope.
test=false
| Field | Type | Required | Description |
|---|---|---|---|
offering_id | string | Yes | Unique identifier |
name | string | Yes | Human-readable name |
description | string | No | Detailed description |
tagline | string | No | Short promotional tagline |
valid_from | datetime | No | When offering becomes available |
valid_to | datetime | No | When offering expires |
checkout_url | uri | No | URL for purchase flow |
landing_url | uri | No | Per-item click-through URL. For catalog-driven formats, this is the destination platforms map to the ad’s link-out. Every offering should have one. |
assets | OfferingAssetGroup[] | No | Structured asset groups for this offering |
geo_targets | object | No | Geographic scope — where this offering is relevant |
keywords | string[] | No | Keywords for intent matching |
categories | string[] | No | Categories for filtering |
OfferingAssetGroup
Schema URL:/schemas/core/offering-asset-group.json
A typed pool of creative assets within an offering. Uses the same asset_group_id vocabulary as format-level asset definitions, enabling formats to declare per-group constraints on what each offering must provide.
test=false
| Field | Type | Required | Description |
|---|---|---|---|
asset_group_id | string | Yes | Matches format-level vocabulary (e.g., headlines, descriptions, images_landscape) |
asset_type | AssetContentType | Yes | Content type of all items in this group |
items | Asset[] | Yes | The assets; each item must match the declared asset_type |
OfferingAssetConstraint
Schema URL:/schemas/core/requirements/offering-asset-constraint.json
Declared by a format to specify what asset groups each offering must provide. Used within a catalog asset’s requirements to constrain what offerings in a catalog must provide.
test=false
| Field | Type | Required | Description |
|---|---|---|---|
asset_group_id | string | Yes | The group this constraint applies to |
asset_type | AssetContentType | Yes | Expected content type |
required | boolean | No | Whether the group must be present. Defaults to true. |
min_count | integer | No | Minimum items required |
max_count | integer | No | Maximum items allowed |
asset_requirements | object | No | Technical requirements per item (e.g., max_length for text, min_width for images) |
Format requirements for offerings
Calllist_creative_formats and check the format’s assets array for catalog asset types to see what catalog types are needed and what each offering must provide:
Stores
Schema URL:/schemas/core/store-item.json
A StoreItem represents a physical location within a store-type catalog. Each store carries coordinates, an optional address, and one or more catchment areas that define the geographic reach around that location.
test=false
| Field | Type | Required | Description |
|---|---|---|---|
store_id | string | Yes | Unique identifier for targeting, inventory, and creative references |
name | string | Yes | Human-readable store name |
location | object | Yes | Lat/lng coordinates (WGS 84) |
address | object | No | Structured address for display and geocoding fallback |
catchments | Catchment[] | No | Catchment areas for proximity targeting |
phone | string | No | Phone number (E.164) |
url | uri | No | Store-specific page URL |
hours | object | No | Operating hours by day of week |
tags | string[] | No | Tags for filtering in targeting and creative selection |
Catchment areas
Schema URL:/schemas/core/catchment.json
A catchment defines the geographic area a store serves. Three methods are supported — provide exactly one per catchment:
Isochrone inputs — the platform resolves the shape from travel time and transport mode, accounting for road networks, transit routes, and terrain:
catchment_id is what targeting references — a campaign can target the walk catchment of specific stores or the drive catchment of all stores in the catalog.
Inline store catalog
SI integration
Offerings in a catalog can be promoted through Sponsored Intelligence conversations. The brand’s SI agent URL is declared on the brand identity, not on the catalog — SI is a brand-level capability. Theoffering_id connects a catalog item to a conversation:
- User expresses intent — “I need flights to LA next week”
- Publisher matches to offering — Uses
keywordsto find relevant offerings, checksvalid_from/valid_to - Publisher initiates SI session — Passes
offering_idand user context to the brand’s SI agent - Brand agent responds — With contextual information, UI elements, and a conversational experience
Use cases
Universal format (asset pool)
The buyer provides multiple offerings, each with their own creative asset pool. The publisher picks the most relevant offering and assembles the best headline/image combination:Product catalog with synced feeds
For retail media, sync product and inventory feeds, then reference them in creatives:Conversational-only
No pre-built creatives — just offerings available for SI conversations. The brand’s SI agent URL is discovered from the brand identity:Location-specific offerings
For brands with multiple physical locations — restaurants, retail chains, job vacancies — each offering declares its geographic scope viageo_targets:
targeting_overlay in the package.
Catalogs in the media buy lifecycle
Catalogs flow through the entire media buy lifecycle — from product discovery to delivery reporting.Catalog-driven discovery
Pass acatalog on get_products to find products that match your catalog items. The seller matches catalog items against its inventory and returns products where matches exist. Products declare which catalog types they support via catalog_types.
Catalog-driven packages
Include acatalog field on a package in create_media_buy to make it catalog-driven. One budget envelope promotes the entire catalog — the platform optimizes delivery across items based on performance. This is the AdCP equivalent of catalog-based campaign types like Google Performance Max or Meta Dynamic Product Ads.
Variants as catalog items
For catalog-driven packages, each catalog item rendered as a distinct ad execution is a creative variant. The variant’s manifest includes the catalog reference with the specific item rendered.Per-item delivery reporting
get_media_buy_delivery returns by_catalog_item breakdowns within each package, showing per-item impressions, spend, clicks, conversions, and ROAS.
Conversion attribution
Conversion events carrycontent_ids that identify which catalog items were involved. The catalog’s content_id_type declares the identifier type. Attribution is broad — a user might click item A but convert on item B. The event fires with the actual content_id. See conversion tracking.
Item-level tracking via macros
For impression-level attribution (which item was clicked, which was viewed), use catalog item macros in your creative’s tracker pixel URLs. The macros mirror thecontent_id_type enum — the same identifiers used at serve time that appear in conversion events:
{OFFERING_ID} with the specific offering being rendered. For a carousel showing 5 offerings, each item’s impression fires with that item’s identifier.
Use the macro matching your catalog’s content_id_type:
content_id_type | Macro |
|---|---|
sku | {SKU} |
gtin | {GTIN} |
offering_id | {OFFERING_ID} |
job_id | {JOB_ID} |
hotel_id | {HOTEL_ID} |
flight_id | {FLIGHT_ID} |
vehicle_id | {VEHICLE_ID} |
listing_id | {LISTING_ID} |
store_id | {STORE_ID} |
program_id | {PROGRAM_ID} |
destination_id | {DESTINATION_ID} |
app_id | {APP_ITEM_ID} |
content_ids at event time).
Best practices
Match asset_group_id to the format’s vocabulary
Read the format definition from list_creative_formats before building offerings. The asset_group_id values must match exactly what the format declares in offering_asset_constraints within each catalog asset’s requirements. Group IDs like headlines, images, or videos are format-defined vocabulary, not protocol constants — each format chooses its own IDs. The protocol provides the container and constraint mechanism; the format defines the vocabulary.
Provide more assets than the minimum
Formats that use asset pools select the best-performing combination. Providing the maximum allowed items gives the publisher more to work with.Set validity windows
For time-limited promotions, always setvalid_from and valid_to. Publishers filter expired offerings automatically.
Use geo_targets for inherently location-specific offerings
When an offering’s identity is tied to a geographic location — a job vacancy, an in-store promotion, a local event — declare its scope with geo_targets. This is not ad targeting; it’s a property of what the offering IS.
Always provide landing_url on catalog offerings
For catalog-driven creatives, landing_url is the per-item click-through destination that platforms map to the ad’s link-out URL (swipe-up, CTA button, carousel card link). Every offering in a catalog should have a landing_url. Include checkout_url as well when direct conversion is supported.
Budget distribution across catalog items
Budget allocation across catalog items is a platform optimization decision — some platforms distribute evenly, others allocate based on performance signals. The protocol does not prescribe a specific distribution method. Budget lives oncreate_media_buy packages, not on individual offerings. If your campaign requires specific per-item budget caps, use separate packages per offering.
Related documentation
- Account state — How catalogs fit into account state and the setup sequence
- Brand identity — Brand identity and assets
- SI Chat Protocol — Conversational brand experiences
- sync_creatives — Submitting creative manifests
- list_creative_formats — Discovering format requirements