@adcp/sdk API Reference - v14.0.0-beta.6
    Preparing search index...

    Interface LegacyGetProductsRequest

    AdCP 3.x compatibility request for discovering and changing advertising products and proposals. Buyers SHOULD express every campaign constraint that has a structured field in that field rather than relying on prose: structured input is cheaper to transmit, deterministic to process, and avoids lossy inference. Exact targeting_overlay values scope returned products, pricing, and forecasts; required_overlay_support identifies targeting dimensions whose values will be supplied on packages later. Explicit hard targeting stated only in a brief remains binding. AdCP 3.2 introduces the narrower list_products, request_proposals, refine_proposals, and decline_proposals tasks; new callers SHOULD use those tasks while existing get_products payloads remain valid throughout 3.x.

    interface LegacyGetProductsRequest {
        adcp_version?: string;
        adcp_major_version?: number;
        idempotency_key?: string;
        buying_mode: "brief" | "wholesale" | "refine";
        brief?: string;
        refine?: (
            | { scope: "request"; ask: string }
            | {
                scope: "product";
                product_id: string;
                action?: "include" | "omit" | "more_like_this";
                ask?: string;
            }
            | {
                scope: "proposal";
                proposal_id: string;
                action?: "include"
                | "omit"
                | "finalize";
                ask?: string;
            }
        )[];
        brand?: BrandReference;
        catalog?: Catalog;
        account?: AccountReference;
        preferred_delivery_types?: DeliveryType[];
        filters?: ProductFilters;
        targeting_overlay?: {
            geo_countries?: [string, ...string[]];
            geo_countries_exclude?: [string, ...string[]];
            geo_regions?: [string, ...string[]];
            geo_regions_exclude?: [string, ...string[]];
            geo_metros?: [
                { system: MetroAreaSystem; values: [string, ...string[]] },
                ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
            ];
            geo_metros_exclude?: [
                { system: MetroAreaSystem; values: [string, ...string[]] },
                ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
            ];
            geo_postal_areas?: [PostalArea, ...PostalArea[]];
            geo_postal_areas_exclude?: [PostalArea, ...PostalArea[]];
            geo_places?: [GeographicPlaceArea, ...GeographicPlaceArea[]];
            geo_places_exclude?: [GeographicPlaceArea, ...GeographicPlaceArea[]];
            daypart_targets?: [DaypartTarget, ...DaypartTarget[]];
            axe_include_segment?: string;
            axe_exclude_segment?: string;
            audience_include?: [string, ...string[]];
            audience_exclude?: [string, ...string[]];
            signal_targeting_groups?: PackageSignalTargetingGroups;
            signal_targeting?: [{}, ...{}[]];
            demographics?: DemographicTargetingIntent;
            frequency_cap?: {
                suppress?: Duration;
                suppress_minutes?: number;
                max_impressions?: number;
                per?: ReachUnit;
                window?: Duration;
            };
            property_list?: PropertyListReference;
            property_list_exclude?: PropertyListReference;
            collection_list?: CollectionListReference;
            collection_list_exclude?: CollectionListReference;
            placement_selection?: PlacementSelection;
            age_restriction?: {
                min: number;
                verification_required?: boolean;
                accepted_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
            };
            device_platform?: [DevicePlatform, ...DevicePlatform[]];
            device_platform_exclude?: [DevicePlatform, ...DevicePlatform[]];
            device_type?: [DeviceType, ...DeviceType[]];
            device_type_exclude?: [DeviceType, ...DeviceType[]];
            browser?: [BrowserFamily, ...BrowserFamily[]];
            browser_exclude?: [BrowserFamily, ...BrowserFamily[]];
            store_catchments?: [
                {
                    catalog_id: string;
                    store_ids?: [string, ...string[]];
                    catchment_ids?: [string, ...string[]];
                },
                ...{
                    catalog_id: string;
                    store_ids?: [string, ...string[]];
                    catchment_ids?: [string, ...string[]];
                }[],
            ];
            geo_proximity?: [{}, ...{}[]];
            language?: [string, ...string[]];
            keyword_targets?: [
                { keyword: string; match_type: MatchType; bid_price?: number },
                ...{ keyword: string; match_type: MatchType; bid_price?: number }[],
            ];
            negative_keywords?: [
                { keyword: string; match_type: MatchType },
                ...{ keyword: string; match_type: MatchType }[],
            ];
        };
        required_overlay_support?: TargetingOverlayRequirements;
        property_list?: PropertyListReference;
        fields?: (
            | "name"
            | "forecast"
            | "description"
            | "publisher_properties"
            | "audience_evidence"
            | "product_id"
            | "channels"
            | "video_placement_types"
            | "audio_distribution_types"
            | "sponsored_placement_types"
            | "social_placement_surfaces"
            | "format_options"
            | "placements"
            | "delivery_type"
            | "exclusivity"
            | "pricing_options"
            | "reporting_capabilities"
            | "catalog_types"
            | "signal_targeting_allowed"
            | "signal_targeting_rules"
            | "demographic_targeting"
            | "audience_evidence_selections"
            | "max_optimization_goals"
            | "catalog_match"
            | "brief_relevance"
            | "expires_at"
            | "product_card"
            | "format_ids"
            | "outcome_measurement"
            | "delivery_measurement"
            | "creative_policy"
            | "metric_optimization"
            | "conversion_tracking"
            | "data_provider_signals"
            | "included_signals"
            | "signal_targeting_options"
            | "overlay_support"
            | "targeting_resolution"
            | "collections"
            | "collection_targeting_allowed"
            | "installments"
            | "is_custom"
            | "product_card_detailed"
            | "enforced_policies"
            | "trusted_match"
        )[];
        time_budget?: Duration;
        push_notification_config?: PushNotificationConfig;
        pagination?: PaginationRequest;
        if_wholesale_feed_version?: string;
        if_pricing_version?: string;
        context?: ContextObject;
        required_policies?: string[];
        ext?: ExtensionObject;
    }
    Index

    Properties

    adcp_version?: string

    Release-precision AdCP version (VERSION.RELEASE, e.g. "3.0", "3.1", "3.1-beta"). On a request: the buyer's release pin — the seller validates against its supported_versions and returns VERSION_UNSUPPORTED on cross-major mismatch, or downshifts to the highest supported release within the same major. On a response: the release the seller actually served — clients SHOULD validate the response against that release's schema, not against their pin. Patches are not negotiated; surface them as build_version on capabilities for operational visibility. When omitted, falls back to adcp_major_version (deprecated) or server default. Buyers SHOULD emit both adcp_version and adcp_major_version through 3.x to remain compatible with sellers that only read the legacy field. NORMALIZATION: SDKs that read full-semver values from bundle metadata (e.g. ComplianceIndex.published_version = "3.1.0-beta.1") MUST normalize to release-precision ("3.1-beta.1") before emitting on the wire — meta-field values are NOT valid wire values.

    adcp_major_version?: number

    DEPRECATED in favor of adcp_version (release-precision string). Servers MUST continue to honor this field through 3.x. Removed in 4.0. Original semantics: the AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.

    idempotency_key?: string

    Optional client-generated key for retry-safe use of the AdCP 3.x compatibility facade. New callers SHOULD use the compact 3.2 tasks; each stateful split task has its own idempotency identity, so callers MUST retry with the same tool name. Keys MUST be unique per seller and logical request.

    16

    255

    ^[A-Za-z0-9_.:-]{16,255}$

    buying_mode: "brief" | "wholesale" | "refine"

    Declares buyer intent for this request. 'brief': publisher curates product recommendations from the provided brief. 'wholesale': buyer requests raw product inventory to apply their own audiences — brief must not be provided, and proposals are omitted. 'refine': iterate on products and proposals from a previous get_products response using the refine array of change requests. v3 clients MUST include buying_mode. Sellers receiving requests from pre-v3 clients without buying_mode SHOULD default to 'brief'. Timing semantics: 'wholesale' is a wholesale product feed read — sellers SHOULD return a synchronous response and MUST NOT route a 'wholesale' request through the async/Submitted arm; partial completion is signalled via the response's incomplete[] field (with optional estimated_wait), not via a task-handoff envelope. 'brief' and 'refine' MAY complete synchronously, or MAY return a Submitted envelope (see get-products-async-response-submitted.json) when curation requires upstream-system queries or HITL review the seller cannot complete inside time_budget. Buyers needing predictable fast wholesale product feed access MUST use 'wholesale'; buyers open to slower curation use 'brief' or 'refine'.

    brief?: string

    Natural language description of campaign requirements. Required when buying_mode is 'brief'. Must not be provided when buying_mode is 'wholesale' or 'refine'. Buyers SHOULD use structured fields for every requirement that can be expressed structurally, and reserve brief prose for goals, context, preferences, and requirements without a structured representation. Sellers MUST apply explicit hard requirements stated in the brief even when the buyer did not duplicate them in a structured field. When a seller translates hard prose into structured targeting that materially affects product eligibility, pricing, or forecasting, it MUST confirm that interpretation once in GetProductsResponse.targeting_resolution.brief_targeting; otherwise confirmation remains a best practice. If hard prose contradicts a structured field, sellers MUST reject the request with INVALID_REQUEST rather than choose one interpretation or return an unexplained empty result.

    refine?: (
        | { scope: "request"; ask: string }
        | {
            scope: "product";
            product_id: string;
            action?: "include" | "omit" | "more_like_this";
            ask?: string;
        }
        | {
            scope: "proposal";
            proposal_id: string;
            action?: "include"
            | "omit"
            | "finalize";
            ask?: string;
        }
    )[]

    Array of change requests for iterating on products and proposals from a previous get_products response. Each entry declares a scope (request, product, or proposal) and what the buyer is asking for. Only valid when buying_mode is 'refine'. The seller responds to each entry via refinement_applied in the response, matched by position.

    Finalize-exclusivity rule: if any entry has action: 'finalize', ALL entries in the array MUST be proposal-scoped with action: 'finalize' — mixing finalize entries with include/omit entries or with request- / product-scoped entries MUST be rejected by the seller with INVALID_REQUEST. Finalize is a commit, not a refinement; the buyer expressing intent to commit means refinements have already converged. Buyers needing to refine AND commit in close succession sequence the calls: first a refine call (no finalize), then a finalize call against the resulting proposal_id(s).

    Multi-finalize semantics: multiple finalize entries against different proposal_id values in a single call are allowed and MUST be atomic at the observation point — sellers MUST NOT return a success response unless every named proposal has both completed and been persisted as committed. Pre-commit validation runs before any side-effects (inventory pull, terms lock, governance attestation); if any proposal fails validation, the seller MUST reject the entire call without committing any of the named proposals. There is no rollback operation in the spec — an unfinalize would itself be a new mutation surface; the atomicity guarantee runs entirely on the seller's pre-commit validation gate, not on post-commit reversal. Sellers that cannot guarantee atomic pre-commit validation MUST reject multi-finalize arrays with MULTI_FINALIZE_UNSUPPORTED (preferred — distinguishes seller-side capability gap from a malformed request) or INVALID_REQUEST (acceptable fallback for sellers on a pre-3.1 error catalog). If a mid-commit failure occurs after validation passed but before all proposals persist (e.g., a downstream ad server fails between commits one and two), the seller MUST return INTERNAL_ERROR with refinement_applied[] carrying per-position outcomes — the spec does NOT define a recovery path for this case, and buyers SHOULD treat the resulting state as undefined and re-read via get_media_buys / equivalent before retrying. Buyers MUST NOT assume multi-finalize support without a successful first attempt — there is no capability flag for this; the failure response is the discovery surface. Buyers whose intent specifically requires atomic commit (e.g., budget-shared proposals where one finalizing without the other is incoherent) MUST be prepared to abandon the intent if the seller returns MULTI_FINALIZE_UNSUPPORTED — there is no recovery for that loss of buyer intent beyond sequencing single-finalize calls and accepting the looser commit guarantee.

    Type Declaration

    • { scope: "request"; ask: string }
      • scope: "request"

        Change scoped to the overall request — direction for the selection as a whole.

      • ask: string

        What the buyer is asking for at the request level (e.g., 'more video options and less display', 'suggest how to combine these products').

        1

    • {
          scope: "product";
          product_id: string;
          action?: "include" | "omit" | "more_like_this";
          ask?: string;
      }
      • scope: "product"

        Change scoped to a specific product.

      • product_id: string

        Product ID from a previous get_products response.

        1

      • Optionalaction?: "include" | "omit" | "more_like_this"

        'include' (default): return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned). Optional — when omitted, the seller treats the entry as action: 'include'.

      • Optionalask?: string

        What the buyer is asking for on this product. For 'include': specific changes to request (e.g., 'add 16:9 format'). For 'more_like_this': what 'similar' means (e.g., 'same audience but video format'). Ignored when action is 'omit'.

        1

    • {
          scope: "proposal";
          proposal_id: string;
          action?: "include" | "omit" | "finalize";
          ask?: string;
      }
      • scope: "proposal"

        Change scoped to a specific proposal.

      • proposal_id: string

        Proposal ID from a previous get_products response.

        1

      • Optionalaction?: "include" | "omit" | "finalize"

        'include' (default): return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold. New callers use refine_proposals with action revise for a draft successor or action finalize for a committed held successor; terminal feedback is available through decline_proposals.

        Legacy finalize is exclusive within the parent refine[] array: see the array-level description for the finalize-exclusivity rule (mixing finalize with non-finalize entries is rejected) and multi-finalize atomicity contract.

      • Optionalask?: string

        What the buyer is asking for on this proposal (e.g., 'shift more budget toward video', 'reduce total by 10%'). Ignored when action is omit.

        1

    catalog?: Catalog
    preferred_delivery_types?: DeliveryType[]

    Delivery types the buyer prefers, in priority order. Unlike filters.delivery_type which excludes non-matching products, this signals preference for curation — the publisher may still include other delivery types when they match the brief well.

    filters?: ProductFilters
    targeting_overlay?: {
        geo_countries?: [string, ...string[]];
        geo_countries_exclude?: [string, ...string[]];
        geo_regions?: [string, ...string[]];
        geo_regions_exclude?: [string, ...string[]];
        geo_metros?: [
            { system: MetroAreaSystem; values: [string, ...string[]] },
            ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
        ];
        geo_metros_exclude?: [
            { system: MetroAreaSystem; values: [string, ...string[]] },
            ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
        ];
        geo_postal_areas?: [PostalArea, ...PostalArea[]];
        geo_postal_areas_exclude?: [PostalArea, ...PostalArea[]];
        geo_places?: [GeographicPlaceArea, ...GeographicPlaceArea[]];
        geo_places_exclude?: [GeographicPlaceArea, ...GeographicPlaceArea[]];
        daypart_targets?: [DaypartTarget, ...DaypartTarget[]];
        axe_include_segment?: string;
        axe_exclude_segment?: string;
        audience_include?: [string, ...string[]];
        audience_exclude?: [string, ...string[]];
        signal_targeting_groups?: PackageSignalTargetingGroups;
        signal_targeting?: [{}, ...{}[]];
        demographics?: DemographicTargetingIntent;
        frequency_cap?: {
            suppress?: Duration;
            suppress_minutes?: number;
            max_impressions?: number;
            per?: ReachUnit;
            window?: Duration;
        };
        property_list?: PropertyListReference;
        property_list_exclude?: PropertyListReference;
        collection_list?: CollectionListReference;
        collection_list_exclude?: CollectionListReference;
        placement_selection?: PlacementSelection;
        age_restriction?: {
            min: number;
            verification_required?: boolean;
            accepted_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
        };
        device_platform?: [DevicePlatform, ...DevicePlatform[]];
        device_platform_exclude?: [DevicePlatform, ...DevicePlatform[]];
        device_type?: [DeviceType, ...DeviceType[]];
        device_type_exclude?: [DeviceType, ...DeviceType[]];
        browser?: [BrowserFamily, ...BrowserFamily[]];
        browser_exclude?: [BrowserFamily, ...BrowserFamily[]];
        store_catchments?: [
            {
                catalog_id: string;
                store_ids?: [string, ...string[]];
                catchment_ids?: [string, ...string[]];
            },
            ...{
                catalog_id: string;
                store_ids?: [string, ...string[]];
                catchment_ids?: [string, ...string[]];
            }[],
        ];
        geo_proximity?: [{}, ...{}[]];
        language?: [string, ...string[]];
        keyword_targets?: [
            { keyword: string; match_type: MatchType; bid_price?: number },
            ...{ keyword: string; match_type: MatchType; bid_price?: number }[],
        ];
        negative_keywords?: [
            { keyword: string; match_type: MatchType },
            ...{ keyword: string; match_type: MatchType }[],
        ];
    }

    Type Declaration

    • Optionalgeo_countries?: [string, ...string[]]

      Restrict delivery to specific countries. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').

      1

    • Optionalgeo_countries_exclude?: [string, ...string[]]

      Exclude specific countries from delivery. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').

      1

    • Optionalgeo_regions?: [string, ...string[]]

      Restrict delivery to exact canonical ISO 3166-2 subdivisions (states, provinces, regions, departments, or other subdivision categories). Unknown identifiers are invalid. At create or update, sellers MUST reject unsupported identifiers and MUST NOT silently widen, drop, or partially apply the list. During get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome. Exact internal translation preserves accepted identifiers in package readback.

      1

    • Optionalgeo_regions_exclude?: [string, ...string[]]

      Exclude exact canonical ISO 3166-2 subdivisions. Support is independent from geo_regions inclusion support. Unknown identifiers and values also present in geo_regions are invalid. At create or update, sellers MUST reject unsupported identifiers and partial application; during get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome.

      1

    • Optionalgeo_metros?: [
          { system: MetroAreaSystem; values: [string, ...string[]] },
          ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
      ]

      Restrict delivery to specific metro areas. Each entry specifies the classification system and target values. Seller must declare supported systems in get_adcp_capabilities.

      1

    • Optionalgeo_metros_exclude?: [
          { system: MetroAreaSystem; values: [string, ...string[]] },
          ...{ system: MetroAreaSystem; values: [string, ...string[]] }[],
      ]

      Exclude specific metro areas from delivery. Each entry specifies the classification system and excluded values. Seller must declare supported systems in get_adcp_capabilities.

      1

    • Optionalgeo_postal_areas?: [PostalArea, ...PostalArea[]]

      Restrict delivery to specific postal areas. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.

      1

    • Optionalgeo_postal_areas_exclude?: [PostalArea, ...PostalArea[]]

      Exclude specific postal areas from delivery. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.

      1

    • Optionalgeo_places?: [GeographicPlaceArea, ...GeographicPlaceArea[]]

      Restrict delivery to catalog-backed named places. Values MUST be stable identifiers in the declared system, not display names. Sellers must declare supported systems, countries, and place types in get_adcp_capabilities and reject unsupported entries rather than silently dropping them.

      1

    • Optionalgeo_places_exclude?: [GeographicPlaceArea, ...GeographicPlaceArea[]]

      Exclude catalog-backed named places. Uses the same identifier-based shape as geo_places. Sellers MUST reject overlap with geo_places for the same country, system, place_type, and value.

      1

    • Optionaldaypart_targets?: [DaypartTarget, ...DaypartTarget[]]

      Restrict delivery to specific time windows. Each entry specifies days of week and an hour range.

      1

    • Optionalaxe_include_segment?: string

      Deprecated: Use TMP provider fields instead. AXE segment ID to include for targeting.

    • Optionalaxe_exclude_segment?: string

      Deprecated: Use TMP provider fields instead. AXE segment ID to exclude from targeting.

    • Optionalaudience_include?: [string, ...string[]]

      Restrict delivery to members of these first-party CRM audiences. Only users present in the uploaded lists are eligible. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Not for lookalike expansion — express that intent in the campaign brief. Seller must declare support in get_adcp_capabilities.

      1

    • Optionalaudience_exclude?: [string, ...string[]]

      Suppress delivery to members of these first-party CRM audiences. Matched users are excluded regardless of other targeting. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Seller must declare support in get_adcp_capabilities.

      1

    • Optionalsignal_targeting_groups?: PackageSignalTargetingGroups
    • Optionalsignal_targeting?: [{}, ...{}[]]

      DEPRECATED. Use signal_targeting_groups for package-level signal targeting. Legacy flat signal_targeting remains accepted during the SignalRef migration window but cannot express grouped include/exclude composition or product-scoped pricing.

      1

    • Optionaldemographics?: DemographicTargetingIntent
    • Optionalfrequency_cap?: {
          suppress?: Duration;
          suppress_minutes?: number;
          max_impressions?: number;
          per?: ReachUnit;
          window?: Duration;
      }
      • Optionalsuppress?: Duration

        Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.

      • Optionalsuppress_minutes?: number

        Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).

      • Optionalmax_impressions?: number

        Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.

      • Optionalper?: ReachUnit

        Entity granularity for impression counting. Required when max_impressions is set.

      • Optionalwindow?: Duration

        Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.

    • Optionalproperty_list?: PropertyListReference
    • Optionalproperty_list_exclude?: PropertyListReference
    • Optionalcollection_list?: CollectionListReference
    • Optionalcollection_list_exclude?: CollectionListReference
    • Optionalplacement_selection?: PlacementSelection
    • Optionalage_restriction?: {
          min: number;
          verification_required?: boolean;
          accepted_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
      }

      Age restriction for compliance. Use for legal requirements (alcohol, gambling), not audience targeting.

      • min: number

        Minimum age required

      • Optionalverification_required?: boolean

        Whether verified age (not inferred) is required for compliance

      • Optionalaccepted_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]]

        Accepted verification methods. If omitted, any method the platform supports is acceptable.

        1

    • Optionaldevice_platform?: [DevicePlatform, ...DevicePlatform[]]

      Restrict to specific platforms. Use for technical compatibility (app only works on iOS). Values from Sec-CH-UA-Platform standard, extended for CTV.

      1

    • Optionaldevice_platform_exclude?: [DevicePlatform, ...DevicePlatform[]]

      Exclude specific operating-system platforms from delivery. When a platform appears in both device_platform and device_platform_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.

      1

    • Optionaldevice_type?: [DeviceType, ...DeviceType[]]

      Restrict to specific device form factors. Use for campaigns targeting hardware categories rather than operating systems (e.g., mobile-only promotions, CTV campaigns).

      1

    • Optionaldevice_type_exclude?: [DeviceType, ...DeviceType[]]

      Exclude specific device form factors from delivery (e.g., exclude CTV for app-install campaigns).

      1

    • Optionalbrowser?: [BrowserFamily, ...BrowserFamily[]]

      Restrict delivery to specific canonical browser families in the impression delivery and rendering environment, not the post-click landing-page browser. Values MUST NOT be inferred solely from operating system, device, web/mobile-web inventory, or placement. Values in this array use OR semantics. When browser is supplied, families not listed are ineligible: other includes a seller-recognized family that is not explicitly enumerated, while unknown includes a browser the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Browser and device constraints intersect; a seller that cannot enforce the exact combination MUST exclude or explicitly reconfigure the product during discovery and MUST reject it at create or update rather than silently widening delivery. Browser versions and seller-native IDs are intentionally unsupported.

      1

    • Optionalbrowser_exclude?: [BrowserFamily, ...BrowserFamily[]]

      Exclude specific canonical browser families from delivery. other excludes seller-recognized families that are not explicitly enumerated; unknown excludes browsers the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.

      1

    • Optionalstore_catchments?: [
          {
              catalog_id: string;
              store_ids?: [string, ...string[]];
              catchment_ids?: [string, ...string[]];
          },
          ...{
              catalog_id: string;
              store_ids?: [string, ...string[]];
              catchment_ids?: [string, ...string[]];
          }[],
      ]

      Target users within store catchment areas from a synced store catalog. Each entry references a store-type catalog and optionally narrows to specific stores or catchment zones.

      1

    • Optionalgeo_proximity?: [{}, ...{}[]]

      Target users within travel time, distance, or a custom boundary around arbitrary geographic points. Multiple entries use OR semantics — a user within range of any listed point is eligible. For campaigns targeting 10+ locations, consider using store_catchments with a location catalog instead. Seller must declare support in get_adcp_capabilities.

      1

    • Optionallanguage?: [string, ...string[]]

      Restrict to users with specific language preferences using canonical BCP 47 language ranges. Each buyer range is evaluated against a user's language-preference tag with RFC 4647 section 3.3.1 Basic Filtering: 'fr' matches 'fr', 'fr-CA', and 'fr-FR', while 'fr-CA' matches 'fr-CA' and more-specific descendants but not 'fr' or 'fr-FR'. Values use OR logic.

      1

    • Optionalkeyword_targets?: [
          { keyword: string; match_type: MatchType; bid_price?: number },
          ...{ keyword: string; match_type: MatchType; bid_price?: number }[],
      ]

      Keyword targeting for search and retail media platforms. Restricts delivery to queries matching the specified keywords. Each keyword is identified by the tuple (keyword, match_type) — the same keyword string with different match types are distinct targets. Sellers SHOULD reject duplicate (keyword, match_type) pairs within a single request. Seller must declare support in get_adcp_capabilities.

      1

    • Optionalnegative_keywords?: [
          { keyword: string; match_type: MatchType },
          ...{ keyword: string; match_type: MatchType }[],
      ]

      Keywords to exclude from delivery. Queries matching these keywords will not trigger the ad. Each negative keyword is identified by the tuple (keyword, match_type). Seller must declare support in get_adcp_capabilities.

      1

    required_overlay_support?: TargetingOverlayRequirements
    property_list?: PropertyListReference
    fields?: (
        | "name"
        | "forecast"
        | "description"
        | "publisher_properties"
        | "audience_evidence"
        | "product_id"
        | "channels"
        | "video_placement_types"
        | "audio_distribution_types"
        | "sponsored_placement_types"
        | "social_placement_surfaces"
        | "format_options"
        | "placements"
        | "delivery_type"
        | "exclusivity"
        | "pricing_options"
        | "reporting_capabilities"
        | "catalog_types"
        | "signal_targeting_allowed"
        | "signal_targeting_rules"
        | "demographic_targeting"
        | "audience_evidence_selections"
        | "max_optimization_goals"
        | "catalog_match"
        | "brief_relevance"
        | "expires_at"
        | "product_card"
        | "format_ids"
        | "outcome_measurement"
        | "delivery_measurement"
        | "creative_policy"
        | "metric_optimization"
        | "conversion_tracking"
        | "data_provider_signals"
        | "included_signals"
        | "signal_targeting_options"
        | "overlay_support"
        | "targeting_resolution"
        | "collections"
        | "collection_targeting_allowed"
        | "installments"
        | "is_custom"
        | "product_card_detailed"
        | "enforced_policies"
        | "trusted_match"
    )[]

    Specific product fields to include in the response. When omitted, all fields are returned. Use for lightweight discovery calls where only a subset of product data is needed. product_id and name are always included. format_ids is a deprecated 3.x compatibility projection; new integrations request canonical format_options. Safety-critical request-specific fields override projection: Product.targeting_resolution and expires_at MUST be included whenever the seller returns modifications, overlay_support MUST be included when required_overlay_support was requested, and audience_evidence_selections MUST be included when filters.audience_evidence_requirements affects eligibility or ranking. fields controls the optional audience_evidence payload, not the evidence decision receipt. Response-level brief targeting confirmation is not a projected product field.

    time_budget?: Duration

    Maximum time the buyer will commit to this request. The seller returns the best results achievable within this budget and does not start processes (human approvals, expensive external queries) that cannot complete in time. When omitted, the seller decides timing.

    push_notification_config?: PushNotificationConfig
    pagination?: PaginationRequest
    if_wholesale_feed_version?: string

    Opaque wholesale_feed_version token returned by a prior wholesale-mode get_products response from this agent. Only valid when buying_mode is wholesale. When provided, the seller compares against its current wholesale product feed version for the buyer's cache_scope and MAY return an unchanged: true response (with products omitted) if nothing has changed. The token is scope-keyed: buyers cache (cache_scope, wholesale_feed_version) pairs. Scoping dimensions: (agent, buying_mode, filters, targeting_overlay, required_overlay_support, deprecated property_list, catalog) for cache_scope: 'public'; that tuple plus account identity for cache_scope: 'account'. pagination.cursor is NOT part of the scoping tuple. Backward-compatible: pre-v3.1 agents that ignore this field simply return the full payload, same as the unchanged-server path. See specs/wholesale-feed-webhooks.md for the full sync pattern.

    if_pricing_version?: string

    Opaque pricing_version token from a prior get_products response. MUST only be sent together with if_wholesale_feed_version — pricing version has no structural baseline to compare against on its own. Evaluation order: (1) if_wholesale_feed_version mismatch → seller returns the full payload (pricing is implicitly stale); (2) if_wholesale_feed_version matches but if_pricing_version mismatches → seller returns the full payload so the buyer sees updated pricing_options; (3) both match → seller MAY return unchanged: true. Agents that don't track pricing separately ignore if_pricing_version and fall back to if_wholesale_feed_version semantics. Useful for storefronts that re-price compositions far more often than they re-render product mirrors.

    context?: ContextObject
    required_policies?: string[]

    Registry policy IDs that the buyer requires to be enforced for products in this response. Sellers filter products to only those that comply with or already enforce the requested policies.