Opaque identifier for this buyable product. For a non-custom wholesale product, sellers MUST reuse the ID for the same logical catalog offer within the seller and declared cache_scope across reads and wholesale-feed webhooks; feed and pricing versions communicate temporal catalog mutation, while retirement or replacement may end the identity. Concurrent or request-bound configurations whose effective targeting, disclosed targeting modifications, forecast assumptions, terms, or overlay support differ MUST use distinguishable configured product IDs. For is_custom: true, the ID identifies only the request-specific discovery/refinement lineage and is not stable across independent contexts. Sellers MUST keep every issued configured ID resolvable for its promised lifetime. Pricing variants within one logical product are distinguished by pricing_option_id: a seller MUST mint a new pricing_option_id whenever a binding fixed price, floor, currency, model, or priced applicability changes, and MUST NOT reinterpret an issued option ID at a new price. Selecting product_id plus pricing_option_id in create_media_buy accepts that returned configuration and commercial option.
Human-readable product name
Detailed description of the product and its inventory
SDK implementers MUST enforce singular-only at runtime: each entry uses the singular publisher_domain form; the compact publisher_domains[] form is rejected on products. Codegen toolchains (json-schema-to-typescript, quicktype, datamodel-code-generator, openapi-typescript-codegen) often flatten the allOf + $ref + not.required restriction below poorly and may drop the rejection constraint silently, emitting an unrestricted type — runtime enforcement is the safety net. Publisher properties covered by this product. Buyers fetch actual property definitions from each publisher's adagents.json and validate agent authorization. Selection patterns mirror the authorization patterns in adagents.json for consistency. The compact publisher_domains[] form is reserved for adagents.json authorized_agents[].publisher_properties[] so that buy-side traffic-and-pricing flatteners can always treat each entry as exactly one publisher.
Optionalchannels?: MediaChannel[]Advertising channels this product is sold as. Products inherit from their properties' supported_channels but may narrow the scope. For example, a product covering YouTube properties might be sold as ['ctv'] even though those properties support ['olv', 'social', 'ctv'].
Optionalformat_ids?: LegacyFormatReferenceStructuredObject[]Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format compatibility path. Products MUST carry format_ids, format_options, or both during the 3.x migration window. New products MUST author canonical format_options[]; sellers MAY additionally project those declarations to format_ids for legacy buyers. When both fields are present they MUST describe the same underlying formats, and buyers MUST prefer format_options. Do not author a new product from format_ids alone.
Optionalformat_options?: [ProductFormatDeclaration, ...ProductFormatDeclaration[]]Canonical format-option path: one or more inline format declarations the product accepts. Each element narrows a canonical format with parameters, slots, platform_extensions, and optional locale_policy. New 3.2 products MUST carry format_options; a seller MAY additionally project the same declarations to deprecated format_ids for older 3.x peers. A declaration carrying locale_policy is canonical-only because legacy format_ids cannot preserve locale eligibility; no product or placement format_id may project to an effective locale-constrained option.
When placements are published, product-level format_options are the union of formats deliverable somewhere in the product and the upper bound for every placement. A placement's effective accepted set is the intersection of every applicable layer: (1) the product format_options; (2) the product placement's inline format_options, when present; and (3) for kind publisher_ref, the named publisher's adagents.json catalog narrowing. Resolve layer 3 by locating the matching placements[] entry: use its format_options when present, resolving bare format_option_id references against that same file's top-level formats[]; otherwise use top-level formats[] applicable to the placement's property_ids/property_tags. An omitted optional layer is unconstrained, but an unresolved publisher placement or format-option reference MUST fail closed. A publisher-referenced placement without inline product format_options therefore does NOT inherit the full product union when the publisher catalog supplies narrower placement or property-scoped acceptance.
Match publisher-declared options by {publisher_domain, format_option_id}, match product-local options by format_option_id when publisher_domain is omitted, and otherwise match declarations with the same format_kind whose narrower parameters satisfy the broader declaration. A product- or placement-level declaration MUST NOT introduce a format outside the product upper bound. Locale policy follows the same intersection. If the product locale policy is absent, a placement may introduce any concrete policy as a narrowing of an unconstrained option; when both are present, every placement range must be contained by a product range under RFC 4647 Basic Filtering. Locale eligibility is checked independently for every placement where an assignment may serve.
For a product or package containing multiple included placements, a single creative intended for every placement MUST lie in the intersection of every selected placement's effective set. Distinct per-placement creatives MAY use the union, but the selected creative set MUST cover every included placement; uncovered inventory MUST be rejected or refined, never silently omitted. If a product spans multiple publishers but omits placements[], there is no public routing key for per-placement creatives: its format_options MUST therefore be the common intersection accepted across every selected publisher/property scope. A seller that needs a union of publisher-specific formats MUST publish placements[] with publisher-scoped identities and narrowing. Commercial terms such as price, floor, availability, and deal eligibility are product facts, not format parameters.
Optionalplacements?: [LegacyPlacement, ...LegacyPlacement[]]Optional array of specific public placements within this product. Placement IDs are scoped by publisher domain. Product placements declare kind to distinguish publisher-referenced placements (publisher_ref) from seller-defined inline placements (seller_inline). Publisher-referenced placements carry publisher_domain plus placement_id and may omit name because buyers resolve the name from the publisher's adagents.json placement declarations. Seller-inline placements carry buyer-facing name directly; when publisher_domain is omitted, buyers MAY interpret the placement ID relative to the seller agent's own publisher domain only during the legacy single-publisher transition. Community-maintained fallback files are resolver/source metadata, not a distinct placement kind. Each placement MUST declare mode: 'targetable' (buyer may purchase it through targeting_overlay.placement_selection) or mode: 'included' (part of fixed/default product composition and not independently selectable). Creative assignments route creatives only after placement inventory is purchased. Placement-level format declarations narrow the product-level creative contract and MUST NOT broaden it. Seller-private delivery objects, source/origin details, and ad-server mappings MUST NOT be exposed here.
Optionalvideo_placement_types?: [VideoPlacementType, ...VideoPlacementType[]]Declared video placement types that may be included in this product, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. Use on OLV, CTV, and other video products when buyers need to distinguish instream, accompanying-content, interstitial, and standalone/no-content inventory. Aggregate products and ad-network products MAY declare multiple values. When placements[] also carry video_placement_types, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.
Optionalaudio_distribution_types?: [AudioDistributionType, ...AudioDistributionType[]]Declared audio distribution types that may be included in this product, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. Use on radio, streaming-audio, podcast, gaming, and other audio products when buyers need to distinguish music streaming services, FM/AM broadcast, podcasts, catch-up radio, web radio, video-game audio, and text-to-speech inventory without changing the buyer-facing channel or adagents.json property type. Aggregate products and ad-network products MAY declare multiple values. When placements[] also carry audio_distribution_types, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.
Optionalsponsored_placement_types?: [SponsoredPlacementType, ...SponsoredPlacementType[]]Declared sponsored-placement types that may be included in this product, distinguishing where catalog-driven retail-media placements render on the retailer surface (sponsored search, sponsored display, or sponsored native). Use on retail-media products when buyers need to distinguish search-keyed, display, and native in-grid sponsored inventory. Aggregate products and ad-network products MAY declare multiple values. When placements[] also carry sponsored_placement_types, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.
Optionalsocial_placement_surfaces?: [SocialPlacementSurface, ...SocialPlacementSurface[]]Declared social-placement surfaces that may be included in this product, distinguishing the in-app surface where social placements render (feed, stories, short_video, explore, or search). Use on social products when buyers need to distinguish feed, story, short-video, and discovery surfaces. Aggregate products and ad-network products MAY declare multiple values. When placements[] also carry social_placement_surfaces, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.
Optionalexclusivity?: ExclusivityAvailable pricing models for this product. Fixed prices and auction floors are binding for every later targeting selection permitted by this product's overlay_support; price_guidance remains non-binding. Declaring broad overlay support alongside a binding option is therefore a uniform-price promise, not permission to calculate a different price at create time. A seller with value-dependent rates MUST return a request-specific configured product after rediscovery with concrete targeting, split the inventory into separately priced products, or expose only non-binding guidance until it can issue a binding option. The seller MUST mint a new pricing_option_id whenever a binding price, floor, currency, model, or priced applicability changes. It MUST NOT silently reprice a create request or reuse the selected option ID with different terms.
Optionalforecast?: DeliveryForecastOptionaloutcome_measurement?: OutcomeMeasurementOptionaldelivery_measurement?: {Measurement vendors and methodology for delivery metrics. The buyer accepts the declared vendors as the source of truth for the buy. When absent, buyers should apply their own measurement defaults. Senders SHOULD populate vendors (structured BrandRef array) for new implementations; the legacy provider string field is deprecated and retained for one-minor backwards compatibility.
Optionalvendors?: [BrandReference, ...BrandReference[]]Measurement vendors used for this product, as structured BrandRef identities. Multiple entries when multiple vendors play different roles (e.g., the ad server plus a separate viewability vendor like IAS or DV; or a retail-media seller plus a third-party retail measurement vendor like Circana or NielsenIQ). Each vendor's brand.json agents[type='measurement'] is the discovery anchor; metric definitions live on the agent's get_adcp_capabilities.measurement.metrics[] block. Distinct from performance_standards[].vendor which carries vendor identity for committed metrics with thresholds — this field carries vendor identity for the overall measurement story, including non-committed-but-reported metrics.
Optionalprovider?: stringDeprecated as of this minor. Free-form measurement provider description (e.g., 'Google Ad Manager with IAS viewability', 'Nielsen DAR', 'Geopath for DOOH impressions'). New implementations SHOULD use the structured vendors field instead. Retained for one-minor backwards compatibility; removed at the next major. When both vendors and provider are present, consumers MUST use vendors for vendor identity and treat provider as informational text.
Optionalnotes?: stringAdditional details about measurement methodology in plain language (e.g., 'MRC-accredited viewability. 50% in-view for 1s display / 2s video', 'Panel-based demographic measurement updated monthly'). Free-form prose for context that doesn't fit the structured vendors field.
Optionalmeasurement_terms?: MeasurementTermsOptionalperformance_standards?: [PerformanceStandard, ...PerformanceStandard[]]Seller's default performance standards for this product: viewability, IVT, completion rate, brand safety, attention score. Buyers may propose different standards at media buy creation. When absent, no structured performance standards apply.
Optionalcancellation_policy?: CancellationPolicyOptionalallowed_actions?: [ProductAllowedAction, ...ProductAllowedAction[]]Actions buyers may perform on buys created against this product, scoped to statuses and modes. Advisory template — the authoritative per-buy capability is available_actions[] on the buy response, which resolves modes against current buy state, account tier, and negotiated terms. Buyers SHOULD use this for pre-flight product selection ("which products let me self-serve cancel within 72hr?") and read available_actions[] for runtime decisions. The array is uniquely keyed by action — sellers MUST NOT emit two entries with the same action value. Absence means the seller has not declared a structured action surface for this product — buyers fall back to valid_actions[] on buy responses for the flat string vocabulary.
Optionalcreative_policy?: CreativePolicyOptionalis_custom?: booleanWhether this product is a request-specific configured offer rather than a reusable baseline product. Sellers MUST set true when targeting, disclosed resolution, pricing, forecast assumptions, inventory, or terms are bound for a particular discovery/refinement lineage. Products issued through targeting-aware discovery include expires_at even when exact acceptance omits targeting_resolution. For backward compatibility, is_custom alone does not make expires_at schema-required.
Optionalproperty_targeting_allowed?: booleanWhether buyers can select a subset of this product's publisher_properties through targeting_overlay.property_list. When false, the product is fixed inventory: it matches requested property targeting only when its inherent property set already satisfies the request, or when a configured product discloses additional inventory through targeting_resolution.
Optionaldata_provider_signals?: DataProviderSignalSelector[]Deprecated. Legacy/non-selectable metadata for data-provider signals already bundled into or associated with this product. This field does not provide buyer-selectable options, prices, or seller activation handles. Use included_signals for non-selectable product signal metadata, or signal_targeting_options for selectable package-level signal groups.
Optionalincluded_signals?: [SignalListing, ...SignalListing[]]Non-selectable signal metadata for signals already included in, bundled with, or planned into this product. These signals describe what the product is; buyers do not select them in packages[].targeting_overlay.signal_targeting_groups and this field does not imply package-level signal targeting. Use signal_ref scope 'data_provider' or 'signal_source' to reference externally defined signals without redefining their name or value_type. Use signal_ref scope 'product' with name and value_type when the included signal is defined only by this product.
Optionalsignal_targeting_options?: [ProductSignalTargetingOption, ...ProductSignalTargetingOption[]]Inline seller-offered signals that may be applied to packages for this product at create_media_buy time. Each entry references a named signal definition with signal_ref scope 'product' for a product-local signal option, scope 'data_provider' for an external signal definition published in adagents.json signals[] that the seller is authorized to apply, or scope 'signal_source' for a source-native signal. Product-local options define name and value_type inline; data-provider and signal-source options may omit those fields when the referenced definition or source is authoritative. Use this field when the selectable menu is product-specific, has product-specific pricing or activation handles, is the relevant subset for a brief/refine result, or should be rendered without an additional get_signals call. Wholesale products may omit this field and rely on get_signals for the selectable signal feed. Buyers select eligible signals through packages[].targeting_overlay.signal_targeting_groups when signal_targeting_rules allow; fixed/default entries are applied by the seller and echoed on the package state. Sellers MUST set signal_targeting_allowed to true whenever this field is present. Bundled, non-selectable signal metadata belongs in included_signals; legacy data_provider_signals may appear only for backwards compatibility.
Optionalsignal_targeting_rules?: SignalTargetingRulesOptionalsignal_targeting_allowed?: booleanWhether this product has a package-level signal_targeting_groups surface. When false (default), signals are bundled into the product terms and cannot be selected or explicitly echoed as package signal groups. When true, eligible signals from inline signal_targeting_options or from get_signals may be buyer-selected or seller-applied according to signal_targeting_rules and are represented through packages[].targeting_overlay.signal_targeting_groups. Editability is controlled by signal_targeting_rules; fixed/default-only products still set this to true when applied signal groups are echoed.
Optionaldemographic_targeting?: DemographicTargetingCapabilityOptionaloverlay_support?: TargetingOverlaySupportOptionaltargeting_resolution?: ProductTargetingResolutionOptionalaudience_evidence?: [AudienceEvidence, ...AudienceEvidence[]]Immutable population-level evidence explaining why this inventory may suit an audience. This supports discovery, comparison, and planning only. It does not imply exact demographic targeting, user-level signal membership, or legal-age verification. Sellers MUST publish each distinct snapshot with a new snapshot_id and content_digest.
Optionalaudience_evidence_selections?: [AudienceEvidenceSelection, ...AudienceEvidenceSelection[]]Exact evidence snapshots that satisfied required eligibility or affected seller ranking for this get_products result. When audience_evidence_requirements was supplied and evidence influenced inclusion or rank, sellers MUST return the relevant selections; an absent-evidence match under evidence_presence when_available has no selection. Product selections use decision_use recommendation or eligibility.
Optionalcatalog_types?: [CatalogType, ...CatalogType[]]Catalog types this product supports for catalog-driven campaigns. A sponsored product listing declares ["product"], a job board declares ["job", "offering"]. Buyers match synced catalogs to products via this field.
Optionalmetric_optimization?: {Metric optimization capabilities for this product. Presence indicates the product supports optimization_goals with kind: 'metric'. No event source or conversion tracking setup required — the seller tracks these metrics natively.
Metric kinds this product can optimize for. Buyers should only request metric goals for kinds listed here. DEPRECATED values (slated for removal at next major): attention_seconds and attention_score — declare vendor-attested attention/quality metrics via vendor_metric_optimization.supported_metrics[] with an explicit vendor binding instead. Sellers MAY reject the deprecated values with TERMS_REJECTED and a suggestion to use the vendor_metric kind.
Optionalsupported_reach_units?: [ReachUnit, ...ReachUnit[]]Reach units this product can optimize for. Required when supported_metrics includes 'reach'. Buyers must set reach_unit to a value in this list on reach optimization goals — sellers reject unsupported values.
Optionalsupported_view_durations?: number[]Video view duration thresholds (in seconds) this product supports for completed_views goals. Only relevant when supported_metrics includes 'completed_views'. When absent, the seller uses their platform default. Buyers must set view_duration_seconds to a value in this list — sellers reject unsupported values.
Optionalsupported_targets?: ("cost_per" | "threshold_rate")[]Target kinds available for metric goals on this product. Values match target.kind on the optimization goal. Only these target kinds are accepted — goals with unlisted target kinds will be rejected. When omitted, buyers can set target-less metric goals (maximize volume within budget) but cannot set specific targets.
Optionalvendor_metric_optimization?: VendorMetricOptimizationOptionalmax_optimization_goals?: numberMaximum number of optimization_goals this product accepts on a package. When absent, no limit is declared. Most social platforms accept only 1 goal — buyers sending arrays longer than this value should expect the seller to use only the highest-priority (lowest priority number) goal.
Optionalmeasurement_readiness?: MeasurementReadinessOptionalconversion_tracking?: {Conversion event tracking for this product. Presence indicates the product supports optimization_goals with kind: 'event'. Seller-level capabilities (supported event types, UID types, attribution windows) are declared in get_adcp_capabilities.
Optionalaction_sources?: [ActionSource, ...ActionSource[]]Action sources relevant to this product (e.g. a retail media product might have 'in_store' and 'website', while a display product might only have 'website')
Optionalsupported_targets?: [Target kinds available for event goals on this product. Values match target.kind on the optimization goal. cost_per: target cost per conversion event. per_ad_spend: target return on ad spend (requires value_field on event sources). maximize_value: maximize total conversion value without a specific ratio target (requires value_field). Only these target kinds are accepted — goals with unlisted target kinds will be rejected. A goal without a target implicitly maximizes conversion count within budget — no declaration needed for that mode. When omitted, buyers can still set target-less event goals.
Optionalplatform_managed?: booleanWhether the seller provides its own always-on measurement (e.g. Amazon sales attribution for Amazon advertisers). When true, sync_event_sources response will include seller-managed event sources with managed_by='seller'.
Optionalcatalog_match?: {When the buyer provides a catalog on get_products, indicates which catalog items are eligible for this product. Only present for products where catalog matching is relevant (e.g., sponsored product listings, job boards, hotel ads).
Optionalmatched_gtins?: string[]GTINs from the buyer's catalog that are eligible on this product's inventory. Standard GTIN formats (GTIN-8 through GTIN-14). Only present for product-type catalogs with GTIN matching.
Optionalmatched_ids?: string[]Item IDs from the buyer's catalog that matched this product's inventory. The ID type depends on the catalog type and content_id_type (e.g., SKUs for product catalogs, job_ids for job catalogs, offering_ids for offering catalogs).
Optionalmatched_count?: numberNumber of catalog items that matched this product's inventory.
Total catalog items evaluated from the buyer's catalog.
Optionalbrief_relevance?: stringExplanation of why this product matches the brief (only included when brief is provided)
Optionalexpires_at?: stringExpiration timestamp. Required for request-specific configured products whose targeting resolution, price, forecast, inventory, or terms are time-bound. After this time, a seller that still recognizes the issued configured ID within the authenticated account and referenced discovery/refinement lineage rejects create_media_buy with PRODUCT_EXPIRED and the buyer re-runs get_products. Once the seller no longer retains an expiry tombstone, or whenever the ID belongs to another account or lineage, PRODUCT_NOT_FOUND applies instead; sellers are not required to retain tombstones indefinitely and MUST NOT disclose cross-tenant existence through error choice.
Optionalproduct_card?: {Optional standard visual card for displaying this product in user interfaces (catalog browsers, dashboards, agent UIs). Distinct from format — product_card describes the UI rendering of the product itself, not the ad creative the product accepts. Typed inline; no format_id indirection. Receivers render the card directly from these fields.
Optionalimage?: ImageAssetOptionaltitle?: stringCard title (typically the product name).
Optionaldescription?: stringShort descriptive blurb shown below the title.
Optionalprice_label?: stringFormatted price or pricing summary (e.g., 'From $5 CPM', 'Auction floor $0.50 CPC'). Free-text — receivers render verbatim.
Optionalcta_label?: stringCall-to-action button label (e.g., 'View details', 'Get proposal').
Optionalproduct_card_detailed?: {Optional detailed card with hero + carousel + structured specifications, for rich product presentation (media-kit-style pages, full product detail views). Distinct from format — describes the UI rendering of the product itself, not the ad creative the product accepts. Typed inline; no format_id indirection.
Optionalhero_image?: ImageAssetOptionalcarousel_images?: ImageAsset[]Additional images for a swipeable carousel below the hero.
Optionaltitle?: stringPage title (typically the product name).
Optionaldescription?: stringFull descriptive copy. Markdown allowed in client renderers that support it; otherwise treat as plain text.
Optionalspecifications?: { label: string; value: string }[]Structured key/value specifications (e.g., 'Aspect ratio: 9:16', 'Duration: 30s'). Each item is a labeled fact about the product.
Optionalprice_label?: stringFormatted price or pricing summary.
Optionalcta_label?: stringCall-to-action button label.
Optionalreference_assets?: ProductCardReferenceAsset[]Typed seller collateral for buyer planning — coverage maps, sample renders, environment photos, media kits. Distinct from hero_image/carousel_images, which are display-oriented.
Optionalcollections?: [CollectionSelector, ...CollectionSelector[]]Collections available in this product. Each entry references collections declared in an adagents.json by domain and collection ID. Buyers resolve full collection objects from the referenced adagents.json.
Optionalcollection_targeting_allowed?: booleanWhether buyers can select a subset of this product's collections through targeting_overlay.collection_list. When false, the product is a fixed bundle; when true, collection selection is a product-scoped overlay capability.
Optionalinstallments?: Installment[]Specific installments included in this product. Each installment references its parent collection via collection_id when the product spans multiple collections. When absent with collections present, the product covers the collections broadly (run-of-collection).
Optionalenforced_policies?: string[]Registry policy IDs the seller enforces for this product. Enforcement level comes from the policy registry. Buyers can filter products by required policies.
Optionaltrusted_match?: {Trusted Match Protocol capabilities for this product. When present, the product supports real-time contextual and/or identity matching via TMP. Buyers use this to determine what response types the publisher can accept and whether brands can be selected dynamically at match time.
Whether this product supports Context Match requests. When true, the publisher's TMP router will send context match requests to registered providers for this product's inventory.
Optionalidentity_match?: booleanWhether this product supports Identity Match requests. When true, the publisher's TMP router will send identity match requests to evaluate user eligibility.
Optionalresponse_types?: [TMPResponseType, ...TMPResponseType[]]What the publisher can accept back from context match.
Optionaldynamic_brands?: booleanWhether the buyer can select a brand at match time. When false (default), the brand must be specified on the media buy/package. When true, the buyer's offer can include any brand — the publisher applies approval rules at match time. Enables multi-brand agreements where the holding company or buyer agent selects brand based on context.
Optionalproviders?: [TMP providers integrated with this product's inventory. Each entry identifies a provider by agent_url (from the registry) and declares what match types it supports for this product. The product-level context_match and identity_match booleans declare what the product supports overall; the per-provider booleans declare which provider handles each match type. Enables buyer discovery: 'find products where a specific provider does context matching.'
Optionalmaterial_submission?: { url?: string; email?: string; instructions?: string; ext?: ExtensionObject }Instructions for submitting physical creative materials (print, static OOH, cinema). Present only for products requiring physical delivery outside the digital creative assignment flow. Buyer agents MUST validate url and email domains against the seller's known domains (from adagents.json) before submitting materials. Never auto-submit without human confirmation.
Optionalurl?: stringHTTPS URL for uploading or submitting physical creative materials
Optionalemail?: stringEmail address for creative material submission
Optionalinstructions?: stringHuman-readable instructions for material submission (file naming conventions, shipping address, etc.)
Optionalext?: ExtensionObjectOptionalext?: ExtensionObject
Represents available advertising inventory