openapi: 3.2.0 info: title: Scope3 Storefront API version: 2.0.0 description: 'REST API for partners to manage storefronts, inventory sources, and billing. ## Authentication All endpoints require a Bearer token in the Authorization header: ``` Authorization: Bearer your-api-key ``` ## Base URL `https://api.interchange.io/api/v2/storefront` ## For AI Agents AI agents can use the MCP endpoint at `/mcp/v2/storefront` with three tools: - `initialize`: Start an MCP session - `api_call`: Make REST API calls - `ask_about_capability`: Learn about API features' servers: - url: https://api.interchange.io/api/v2/storefront description: Production server tags: - name: Storefront description: Manage storefront and inventory sources paths: /account-mappings/summary: get: operationId: getSellerAccountMappingSummary summary: Get seller account mapping summary description: Get seller-owned relationship and active inventory-source coverage counts for the Buyer Account Mapping Page. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get seller account mapping summary content: application/json: schema: $ref: '#/components/schemas/SellerAccountMappingSummary' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings: get: operationId: listSellerAccountRelationships summary: List seller account relationships description: List the seller-owned operator-and-brand relationships and their private coverage across active inventory sources. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: offset schema: default: 0 type: integer minimum: 0 maximum: 9007199254740991 - in: query name: limit schema: default: 50 type: integer minimum: 1 maximum: 100 - in: query name: search schema: type: string maxLength: 200 responses: '200': description: List seller account relationships content: application/json: schema: $ref: '#/components/schemas/SellerAccountMappingList' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/export: get: operationId: exportSellerAccountMappings summary: Export seller account mappings description: Export the normalized source-mapping template, current healthy mappings, and active source-account choices as formula-safe, byte-bounded CSV documents. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Export seller account mappings content: application/json: schema: $ref: '#/components/schemas/SellerAccountMappingExport' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/reviews: get: operationId: listSellerAccountGrantReviews summary: List pending buyer account requests description: List buyer account requests awaiting a seller decision, including the optimistic-lock version required for each decision. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: offset schema: default: 0 type: integer minimum: 0 maximum: 9007199254740991 - in: query name: limit schema: default: 50 type: integer minimum: 1 maximum: 100 responses: '200': description: List pending buyer account requests content: application/json: schema: $ref: '#/components/schemas/SellerAccountGrantReviewList' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/reviews/{grantId}/decision: post: operationId: decideSellerAccountGrantReview summary: Decide a pending buyer account request description: Approve a pending buyer account request for Interchange-cleared billing, or reject it with a required reason. The expected version prevents decisions against stale review state. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: grantId schema: anyOf: - type: integer format: int64 - type: string - type: number required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DecideSellerAccountGrantReviewBody' responses: '200': description: Decide a pending buyer account request content: application/json: schema: $ref: '#/components/schemas/SellerAccountGrantReviewDecision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/sources/{inventorySourceId}/refresh: post: operationId: refreshSellerAccountSourceAccounts summary: Refresh managed ad-server account choices description: Refresh the authenticated, bounded advertiser roster for one managed Google Ad Manager or FreeWheel inventory source. Other managed providers and modular sources fail closed. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: inventorySourceId schema: anyOf: - type: integer format: int64 - type: string - type: number required: true responses: '200': description: Refresh managed ad-server account choices content: application/json: schema: $ref: '#/components/schemas/ManagedSourceAccountRefreshResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Inventory source not found for this storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/imports/prepare: post: operationId: prepareSellerAccountBindingFeed summary: Prepare a private seller account mapping feed upload description: ADMIN-only. Reserve an immutable feed revision and return a short-lived signed PUT capability for exactly one source_account_bindings.csv. The upload bucket is private and lifecycle-deleted. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PrepareSellerAccountBindingFeed' responses: '200': description: Prepare a private seller account mapping feed upload content: application/json: schema: $ref: '#/components/schemas/SellerAccountBindingFeedPrepareResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Admin role required. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/imports/{revisionId}/preview: post: operationId: previewSellerAccountBindingFeed summary: Validate and preview a seller account mapping feed description: ADMIN-only. Verify the immutable uploaded object, quarantine invalid rows, and issue a short-lived preview token tied to the exact mapping state and impact. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: revisionId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true responses: '200': description: Validate and preview a seller account mapping feed content: application/json: schema: $ref: '#/components/schemas/SellerAccountBindingFeedPreviewResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Admin role required. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/imports/{revisionId}/commit: post: operationId: commitSellerAccountBindingFeed summary: Atomically commit a seller account mapping feed description: ADMIN-only. Apply the exact reviewed mapping set with compare-and-swap guards. Manual mappings and mappings owned by another feed are never overwritten; snapshot omissions affect only mappings owned by this feed. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: revisionId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommitSellerAccountBindingFeed' responses: '200': description: Atomically commit a seller account mapping feed content: application/json: schema: $ref: '#/components/schemas/SellerAccountBindingFeedCommitResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Admin role required. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /account-mappings/imports/{revisionId}: get: operationId: getSellerAccountBindingFeedRevision summary: Get seller account mapping feed revision status description: ADMIN-only. Read the tenant-scoped lifecycle, diagnostics, and impact of one source-account mapping feed revision. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: revisionId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true responses: '200': description: Get seller account mapping feed revision status content: application/json: schema: $ref: '#/components/schemas/SellerAccountBindingFeedRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Admin role required. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /storefront: servers: - url: https://api.interchange.io/api/v2 description: Production server get: operationId: getStorefront summary: Get storefront description: Get the authenticated customer's storefront. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get storefront content: application/json: schema: $ref: '#/components/schemas/StorefrontResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createStorefront summary: Create storefront description: 'Create the authenticated customer''s storefront. A name and a publisher domain are required — the publisher domain is the identity buyers and partners look the storefront up by. Idempotent: when a storefront already exists for the customer, it is returned unchanged (200) instead of creating a duplicate.' tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateStorefrontBody' responses: '200': description: A storefront already exists for this account — returned unchanged (idempotent create; the request body is not applied). content: application/json: schema: $ref: '#/components/schemas/StorefrontResponse' '201': description: Create storefront content: application/json: schema: $ref: '#/components/schemas/StorefrontResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: updateStorefront summary: Update storefront description: Update the storefront configuration. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: description: Updated display name example: Acme Media Network type: string minLength: 1 maxLength: 255 publisherDomain: description: Deprecated legacy singular publisher domain. Use businessProfile.publisherDomains / publisher-domain sync state for the storefront publisher-domain set. type: string minLength: 1 maxLength: 255 plan: description: Updated plan tier type: string enum: - basic transacting: description: Deprecated compatibility alias for the inverse of `isPaused`. It is not effective transaction availability. type: boolean isPaused: description: Compatibility-named seller intake hold. True hides product discovery and blocks new media buys and buyer edits; approved unsent buys wait until it is false. It does not pause existing ad-server delivery. New storefronts default to false; effective transaction availability also depends on readiness and archival state. type: boolean sellsThirdPartyInventory: description: Set to `true` to also resell third-party inventory from other Interchange storefronts; `false` to sell only the storefront’s own inventory sources. type: boolean defaultCurrency: description: Seller-confirmed settlement currency (ISO-4217). Required before go-live for Interchange-cleared storefronts; never defaulted silently. Direct sales adapter storefronts run by our expert agents skip settlement-currency readiness checks because Interchange does not pay the seller on that path. example: EUR type: string pattern: ^[A-Z]{3}$ paymentCurrencies: description: ISO-4217 currencies this storefront will be paid in (the payout set). A media buy settles in one of these (the primary defaultCurrency is always included). The buyer payment currency is the seller payout currency unless the marketplace accepts the buyer currency via cross-currency FX, in which case the source cost is converted to the buyer currency at the platform spot rate while the source is still paid in one of these currencies. A pricing option may not use a settlement currency outside this set. Empty falls back to defaultCurrency, so a single-currency storefront need not set it. Duplicates are ignored. example: - USD - GBP maxItems: 25 type: array items: type: string pattern: ^[A-Z]{3}$ acceptedCountries: description: Replace the operator-confirmed exhaustive country allowlist used to route briefs. This is acceptance policy, not Media Kit merchandising. Pass null to mark the scope unconfigured. example: - FR minItems: 1 maxItems: 249 type: - array - 'null' items: type: string pattern: ^[A-Z]{2}$ acceptsAllCountries: description: 'Set true to accept briefs from every country. Set false with acceptedCountries: null to clear routing scope to unconfigured.' type: boolean advertisingPolicyDisclosure: description: Business Rules sections to publish as Advertising Policies on the Discovery Card. Empty hides the disclosure. Approval routing, review mode, and revision notes are never published. Read-only for pass-through storefronts, whose policy comes from upstream AdCP capabilities. maxItems: 2 type: array items: description: A Business Rules section the seller elects to disclose publicly as Advertising Policies on its Discovery Card. type: string enum: - brief_acceptance - creative_policy supportedLanguages: description: Languages (BCP-47) the co-branded join/signup surface may localize within. example: - nl - fr - en type: array items: type: string minLength: 2 maxLength: 35 operatorDomain: description: Canonical operator domain for AAO registry lookup. Changing it invalidates description, channels, membershipStatus, and website values curated for the prior identity. Resupply valid values in the same request or acknowledge their removal with confirmOperatorDomainProfileReset. example: scope3.com type: string minLength: 1 maxLength: 255 confirmOperatorDomainProfileReset: description: 'Required when changing operatorDomain would clear profile fields curated for the previous identity: description, channels, membershipStatus, or website. Fields explicitly resupplied in the same request are preserved/replaced. Ignored when the domain is unchanged or no populated fields would be cleared.' type: boolean brandName: description: Brand name resolved from AAO registry example: Scope3 type: string maxLength: 255 logoUrl: description: Logo URL resolved from brand.json type: string maxLength: 2048 format: uri logoBackground: description: Backdrop the resolved logo is designed for, from brand.json. Drives the storefront card tile color. Pass null to clear. type: - string - 'null' enum: - dark-bg - light-bg - transparent-bg membershipStatus: description: AAO membership tier displayed on the storefront card. Use `NONE` to hide the badge. type: string enum: - AAO_FOUNDING_MEMBER - AAO_MEMBER - NONE regions: description: Compatibility write alias for legacy businessProfile.regions merchandising context. It does not route briefs or define Discovery Card country coverage. Prefer businessProfile.regions when maintaining legacy context. example: - NL - BE - WORLDWIDE maxItems: 64 type: array items: type: string pattern: ^[A-Z0-9_-]{2,32}$ description: description: Operator-curated description shown on the storefront card. Overrides brand.json when set. type: - string - 'null' maxLength: 2000 channels: description: ADCP channel codes the storefront offers. Surfaced on the storefront card. example: - display - olv - ctv maxItems: 16 type: array items: description: Legacy V2 storefront channel code. Values round-trip unchanged; the Discovery Card projection, Marketplace filters, and outbound AdCP capabilities normalize `audio` to canonical `streaming_audio`. type: string enum: - display - olv - ctv - social - audio - dooh website: description: Operator-curated website URL shown on the storefront card. Overrides brand.json when set. type: string maxLength: 2048 format: uri demandContactName: description: Name of the person at the publisher who fields buyer inquiries (RFPs, prospective briefs, weekly digests). Must be set together with `demandContactEmail`. Pass null to clear (both fields must be cleared together). example: Pia Eberhardt type: - string - 'null' minLength: 1 maxLength: 255 demandContactEmail: description: Email address for the demand contact. Must be set together with `demandContactName`. Pass null to clear (both fields must be cleared together). example: pia@nrcmediagroep.com type: - string - 'null' maxLength: 320 format: email pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$ capabilities: description: Legacy v2 capability object. All flags remain persisted for compatibility, but the effective `offersProductComposition` response and runtime behavior are derived from merchandising access and ready Source product paths. V3 publishes the optional deprecated boolean as a typed no-op, strips it before dispatch, and reports it as ignored. type: object properties: offersCreativeReview: description: Surfaces the creative review protocol surface to buyers. `sync_creatives` returns review-status fields; inline creatives in `create_media_buy` / `update_media_buy` flow through the storefront review gate. The operator policy (auto-approve vs manual queue) is separate config — this flag only governs whether the capability is advertised. default: false type: boolean offersCampaignApproval: description: Surfaces the campaign approval protocol surface to buyers. `create_media_buy` and material-change `update_media_buy` may return a submitted-task envelope until the operator decides. The operator policy (auto-approve vs manual queue, material-change threshold) is separate config. default: false type: boolean offersProductComposition: deprecated: true description: Read-only compatibility projection. True only while the customer has merchandising access and at least one active Source has a ready Storefront-built product path (`WHOLESALE`). default: false type: boolean setupIntent: description: 'Record the operator''s declared selling intent. This is descriptive state only: it does not change Source product paths or effective capabilities. Both ''sell_through_scope3'' and ''third_party_connect'' are accepted regardless of current Source types.' type: string enum: - third_party_connect - sell_through_scope3 compositionPricing: description: 'Replace storefront composition pricing settings: fallback pricing percentile plus seller pricing facts extracted from rate cards, media kits, or operator instructions.' allOf: - $ref: '#/components/schemas/StorefrontCompositionPricing' creativeApproval: description: 'Operator setting: how creatives buyers submit are handled on ad-server-backed inventory sources. `manual` queues each for review; `auto` approves without review. External sales agents and linked Storefronts keep their own approval settings.' type: string enum: - auto - manual mediaBuyApproval: description: 'Operator setting: how new media buys are handled on ad-server-backed inventory sources. `manual` queues each for review; `auto` lets the buy start without review. External sales agents and linked Storefronts keep their own approval settings.' type: string enum: - auto - manual businessProfile: description: Whole-document replacement for the operator-supplied business profile captured during Murph-led setup. New evidence URLs must use HTTP(S); a previously stored legacy URI may be submitted unchanged so read/modify/write clients can round-trip the profile. Pass null to clear. allOf: - $ref: '#/components/schemas/BusinessProfile' confirmCurrencyCatalogImpact: description: Required when changing `defaultCurrency` on a `transacting` storefront would hide products currently visible to buyers (operator fixed prices are only shown in the storefront's settlement currency). The request is rejected with the affected product count unless this is `true`. Ignored when the storefront is not transacting or the currency change has no buyer-visible impact. type: boolean acknowledgeNoHumanReview: description: Required to move `creativeApproval` or `mediaBuyApproval` to `auto`. In `auto`, work proceeds without human review. Brief Acceptance qualifies product discovery; automatic media-buy creation adds no second evaluator gate. The request is rejected unless this is `true`. Ignored when tightening to `manual`, or when the setting is already `auto`. type: boolean responses: '200': description: Update storefront content: application/json: schema: $ref: '#/components/schemas/StorefrontResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: updateStorefrontCapabilities summary: Patch storefront capabilities description: Patch legacy capability configuration without sending the rest of the storefront. V2 persists offersProductComposition as configured compatibility state, while its effective response and runtime behavior derive from merchandising access and ready Source product paths. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PatchStorefrontCapabilitiesBody' responses: '200': description: Patch storefront capabilities content: application/json: schema: $ref: '#/components/schemas/StorefrontResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo: get: operationId: getDemoStorefront summary: Get Demo Storefront description: Get the customer-owned Demo Storefront lease and synthetic profile status, or demo=null when none exists. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get Demo Storefront content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createDemoStorefront summary: Create Demo Storefront description: Create a seven-day Demo Storefront from a versioned synthetic profile. This creates no external side effects and never accepts terms on behalf of a user. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: profileId: default: sample-publisher-display type: string enum: - sample-publisher-display profileVersion: type: string minLength: 1 additionalProperties: false responses: '201': description: Create Demo Storefront content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteDemoStorefront summary: Delete Demo Storefront description: Delete only the Demo Storefront and its synthetic resources. The customer account remains. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Delete Demo Storefront content: application/json: schema: type: object properties: deleted: type: boolean storefrontId: type: - string - 'null' required: - deleted - storefrontId additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo/reset: post: operationId: resetDemoStorefront summary: Reset Demo Storefront description: Rebuild the Demo Storefront from its pinned synthetic profile without extending its lease. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Reset Demo Storefront content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo/source-recipes: get: operationId: listDemoSourceRecipes summary: List Demo source recipes description: List immutable synthetic modular-source recipes and composition presets available to Demo Storefronts. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List Demo source recipes content: application/json: schema: type: object properties: recipes: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media version: type: string displayName: type: string description: type: string channel: type: string enum: - display - ctv - retail-media sourceId: type: string disclosure: type: string synthetic: type: boolean enum: - true required: - recipeId - version - displayName - description - channel - sourceId - disclosure - synthetic additionalProperties: false presets: type: array items: type: object properties: presetId: type: string enum: - mixed-publisher displayName: type: string description: type: string recipeIds: type: array items: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media required: - presetId - displayName - description - recipeIds additionalProperties: false required: - recipes - presets additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo/sources: post: operationId: addDemoStorefrontSources summary: Attach Demo sources description: Attach one or more versioned synthetic modular inventory sources to the active Demo Storefront. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: recipeIds: minItems: 1 maxItems: 3 type: array items: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media required: - recipeIds additionalProperties: false responses: '200': description: Attach Demo sources content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo/sources/{sourceId}: delete: operationId: removeDemoStorefrontSource summary: Remove a Demo source description: Remove an optional synthetic modular source and its generated inventory from the active Demo Storefront. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: type: string minLength: 1 required: true responses: '200': description: Remove a Demo source content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demo/extend: post: operationId: extendDemoStorefront summary: Extend Demo Storefront description: Extend the Demo Storefront lease by one to seven days. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: days: default: 7 type: integer minimum: 1 maximum: 7 additionalProperties: false responses: '200': description: Extend Demo Storefront content: application/json: schema: type: object properties: demo: type: - object - 'null' properties: mode: type: string enum: - DEMO storefrontId: type: string customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 profileId: type: string enum: - sample-publisher-display profileVersion: type: string profileDisplayName: type: string fixturePackId: type: string fixturePackVersion: type: string generation: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - ACTIVE - CLEANUP_PENDING - CLEANUP_FAILED expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastResetAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cleanupAttemptCount: type: integer minimum: 0 maximum: 9007199254740991 cleanupError: type: - string - 'null' disclosure: type: string sourceId: type: string sources: type: array items: type: object properties: recipeId: type: string enum: - sample-publisher-display - sample-publisher-ctv - sample-retail-media recipeVersion: type: string sourceId: type: string displayName: type: string channel: type: string enum: - display - ctv - retail-media synthetic: type: boolean enum: - true required: - recipeId - recipeVersion - sourceId - displayName - channel - synthetic additionalProperties: false synthetic: type: boolean enum: - true required: - mode - storefrontId - customerId - profileId - profileVersion - profileDisplayName - fixturePackId - fixturePackVersion - generation - status - expiresAt - lastResetAt - cleanupAttemptCount - cleanupError - disclosure - sourceId - sources - synthetic additionalProperties: false required: - demo additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /readiness: get: operationId: getStorefrontReadiness summary: Get storefront readiness description: Check if the storefront is ready to go live. Returns blocking checks for inventory sources, agent status, and agent auth. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get storefront readiness content: application/json: schema: $ref: '#/components/schemas/StorefrontReadinessResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /readiness/compliance: get: operationId: getStorefrontCompliance summary: Get storefront compliance status description: Get the most recent compliance readiness check for the storefront. Returns null when no compliance check has run yet. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get storefront compliance status content: application/json: schema: allOf: - $ref: '#/components/schemas/ReadinessCheck' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /readiness/compliance/refresh: post: operationId: refreshStorefrontCompliance summary: Re-run the storefront compliance check description: Re-run the live compliance check across the storefront's testable agents (optionally scoped to a single agent with `agentId`) and return the refreshed readiness check. This is the endpoint behind the `recheck` action on source-health diagnoses. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RefreshComplianceBody' responses: '200': description: Re-run the storefront compliance check content: application/json: schema: allOf: - $ref: '#/components/schemas/ReadinessCheck' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /resolve-brand: post: operationId: resolveBrand summary: Resolve brand profile description: Look up a brand profile on agenticadvertising.org by domain. Returns brand name, logo URL, and profile metadata when found; returns resolved=false plus a builderUrl when no profile exists. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResolveBrandBody' responses: '200': description: Resolve brand profile content: application/json: schema: $ref: '#/components/schemas/ResolveBrandResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '503': description: The AAO registry could not complete the required fresh authoritative lookup. Existing storefront identity is left unchanged. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /discover-agents: get: operationId: discoverAgents summary: Discover agents for a domain description: Query the agenticadvertising.org registry (with an adagents.json fallback) for the operator and publisher agents authorized for a domain. Server-side cached for 2 minutes; pass refresh=true to bypass. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: domain schema: description: Operator domain to discover agents for type: string minLength: 1 required: true description: Operator domain to discover agents for - in: query name: refresh schema: description: Set to "true" to bypass the 2-minute server-side cache and refetch anyOf: - type: string enum: - 'true' - type: string enum: - 'false' description: Set to "true" to bypass the 2-minute server-side cache and refetch responses: '200': description: Discover agents for a domain content: application/json: schema: $ref: '#/components/schemas/DiscoverAgentsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources: get: operationId: listInventorySources summary: List inventory sources description: List all inventory sources for the storefront. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List inventory sources content: application/json: schema: type: array items: $ref: '#/components/schemas/InventorySourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createInventorySource summary: Create inventory source description: Create an inventory source and optionally register an agent for it. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: connectionContract: description: Pinned connection contract used to validate this setup. Omit only for integrations that have not migrated to connection contracts yet. type: object properties: id: type: string minLength: 1 maxLength: 128 pattern: ^[a-z][a-z0-9_-]*$ version: type: integer maximum: 9007199254740991 minimum: 1 authenticationMethod: type: string enum: - none - bearer_token - api_key - credential_exchange - basic_auth - oauth2 - jwt - platform_service_account required: - id - version - authenticationMethod additionalProperties: false sourceId: description: Unique identifier for this source within the storefront. Defaults to a slugified version of the name if not provided. example: retail-network-agent type: string minLength: 1 maxLength: 255 name: description: Display name for the inventory source example: Retail Network Agent type: string minLength: 1 maxLength: 255 executionType: description: Only external `AGENT` inventory sources can be created through this endpoint. `MANAGED_SALES_AGENT` and `MODULAR_SOURCE` rows are created by their dedicated provisioning flows; `LINKED_STOREFRONT` sources are never created or persisted — storefront interchange is resolved at runtime from the ambient wholesale pool. Storefront-level `ADAPTER` dispatch is configured on the storefront, not as an inventory source. default: AGENT type: string enum: - AGENT type: description: Agent type — required when executionType is "AGENT" type: string enum: - SALES - SIGNAL - CREATIVE - OUTCOME endpointUrl: description: Agent endpoint URL — required when executionType is "AGENT" type: string maxLength: 2048 format: uri protocol: description: Agent protocol — required when executionType is "AGENT" type: string enum: - MCP - A2A authenticationType: description: Auth method for the agent — required when executionType is "AGENT" type: string enum: - API_KEY - NO_AUTH - JWT - OAUTH - BASIC_AUTH auth: description: 'Optional for most schemes. NO_AUTH sources need no credentials at all, and OAUTH sources are authorized through their own flow — neither carries an `auth` payload. BASIC_AUTH and API_KEY sources may include credentials here, or be created without them and start PENDING, with the secret collected later through the secure credential form rather than at create time (for BASIC_AUTH use { type: "basic", username, password }). JWT is the exception: its secret must be supplied here at create time, because the secure credential form cannot collect JWT yet.' anyOf: - type: object properties: type: type: string enum: - jwt privateKey: type: string minLength: 1 issuer: type: string minLength: 1 subject: type: string minLength: 1 keyId: type: string minLength: 1 scope: type: string minLength: 1 tokenEndpointUrl: type: string format: uri audienceUrl: type: string format: uri algorithm: type: string enum: - ES256 - RS256 environment: type: string required: - type - privateKey - issuer - subject - keyId - scope - tokenEndpointUrl - audienceUrl - type: object properties: type: type: string enum: - bearer - apikey - api_key token: type: string minLength: 1 required: - type - token - type: object properties: type: type: string enum: - basic username: type: string minLength: 1 password: type: string required: - type - username - password - type: object properties: {} additionalProperties: false oauthAudience: description: OAuth audience / resource indicator for OAUTH agents (the protected-resource URI the agent gateway validates, e.g. "https://platform.example.com"). When set, the OAuth flow requests a token whose `aud` claim targets this resource (sent as both Auth0 `audience` and RFC 8707 `resource`). Leave unset to auto-discover it from the agent's RFC 9728 protected-resource metadata. example: https://platform.example.com type: string maxLength: 2048 format: uri description: description: Agent description type: string maxLength: 2000 required: - name responses: '201': description: Create inventory source content: application/json: schema: $ref: '#/components/schemas/InventorySourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}: get: operationId: getInventorySource summary: Get inventory source description: Get a specific inventory source by its source ID. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get inventory source content: application/json: schema: $ref: '#/components/schemas/InventorySourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: updateInventorySource summary: Update inventory source description: Update an inventory source. Status transitions manage the linked agent lifecycle. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateInventorySourceBody' responses: '200': description: Update inventory source content: application/json: schema: $ref: '#/components/schemas/InventorySourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteInventorySource summary: Delete inventory source description: Delete an inventory source. The linked agent is disabled before removal. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '204': description: No content '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/diagnostics: get: operationId: getInventorySourceDiagnostics summary: Get inventory source diagnostics description: Get recent call health, latency, timeout, failure, and prior-window movement diagnostics for a storefront inventory source. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: windowHours schema: description: Number of trailing hours to analyze for the current diagnostics window. The previous comparison window uses the same duration immediately before it. type: integer maximum: 720 minimum: 1 description: Number of trailing hours to analyze for the current diagnostics window. The previous comparison window uses the same duration immediately before it. - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get inventory source diagnostics content: application/json: schema: $ref: '#/components/schemas/InventorySourceDiagnosticsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/mapping-workspace: get: operationId: getInventorySourceMappingWorkspace summary: Get an inventory source mapping workspace description: Project shared Storefront identities through one exact inventory Source, with independent Storefront-built and Agent-supplied ownership, readiness, and retained inactive product-path state. This preview is hidden unless source-mapping-workspaces is enabled. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get an inventory source mapping workspace content: application/json: schema: $ref: '#/components/schemas/InventorySourceMappingWorkspaceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: FEATURE_NOT_ENABLED (the source-mapping-workspaces preview is off for this customer). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: NOT_FOUND (the inventory source does not exist or is not visible to this customer). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '503': description: SERVICE_UNAVAILABLE (the rollout evaluation or mapping workspace read is temporarily unavailable). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/tests/discovery: post: operationId: runInventorySourceDiscoveryTest summary: Run an inventory source discovery test description: Call the selected external sales agent's get_products operation with a read-only diagnostic brief. This test creates no media buy, spends nothing, and records a durable result with available trace identifiers. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InventorySourceDiscoveryTestBody' responses: '200': description: Run an inventory source discovery test content: application/json: schema: $ref: '#/components/schemas/InventorySourceDiscoveryTestResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/wholesale-pricing/template: get: operationId: downloadWholesalePricingTemplate summary: Download wholesale pricing template description: 'Download a pre-filled CSV template (text/csv) for the wholesale avails & pricing feed: one row per ad-server selector referenced by the source''s products, with selector ids, names, settlement currency, pricing model, and an effective window already filled in. Fill in the CPM percentiles and monthly impressions, then upload the file to the wholesale-pricing endpoint.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Download wholesale pricing template '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Inventory source not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/property-mappings: get: operationId: listInventoryPropertyMappings summary: List inventory property mappings description: List seller-authored property and tag mappings for a managed sales-agent inventory source. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: List inventory property mappings content: application/json: schema: type: array items: type: object properties: grain: default: property type: string enum: - property - tag propertyExternalId: type: string minLength: 1 publisherDomain: type: string minLength: 1 tag: type: string minLength: 1 targetKind: default: key_value type: string enum: - key_value - ad_unit - placement signalKey: type: string minLength: 1 signalValue: type: string minLength: 1 selectorExternalId: type: string minLength: 1 id: type: string sourceId: type: string provenance: type: object properties: source: type: string enum: - operator - import reference: type: string minLength: 1 maxLength: 500 required: - source additionalProperties: false operatorConfirmedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ operatorConfirmedBy: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastValidatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - grain - targetKind - id - sourceId - provenance - operatorConfirmedAt - operatorConfirmedBy - createdAt - lastValidatedAt additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Inventory source not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: replaceInventoryPropertyMappings summary: Replace inventory property mappings description: Dry-run or atomically replace all seller-authored property and tag mappings for a managed sales-agent inventory source. Use the preview body only with dry_run=true. When dry_run is false or omitted, the replacement body requires confirmed=true and provenance. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: dry_run schema: default: 'false' type: string enum: - 'true' - 'false' - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: anyOf: - description: Preview body; valid only when the dry_run query parameter is true type: object properties: mappings: maxItems: 5000 type: array items: type: object properties: grain: default: property type: string enum: - property - tag propertyExternalId: type: string minLength: 1 publisherDomain: type: string minLength: 1 tag: type: string minLength: 1 targetKind: default: key_value type: string enum: - key_value - ad_unit - placement signalKey: type: string minLength: 1 signalValue: type: string minLength: 1 selectorExternalId: type: string minLength: 1 provenance: type: object properties: source: type: string enum: - operator - import reference: type: string minLength: 1 maxLength: 500 required: - source additionalProperties: false required: - mappings - description: Replacement body; required when dry_run is false or omitted and requires confirmed=true plus provenance type: object properties: mappings: maxItems: 5000 type: array items: type: object properties: grain: default: property type: string enum: - property - tag propertyExternalId: type: string minLength: 1 publisherDomain: type: string minLength: 1 tag: type: string minLength: 1 targetKind: default: key_value type: string enum: - key_value - ad_unit - placement signalKey: type: string minLength: 1 signalValue: type: string minLength: 1 selectorExternalId: type: string minLength: 1 provenance: type: object properties: source: type: string enum: - operator - import reference: type: string minLength: 1 maxLength: 500 required: - source additionalProperties: false confirmed: type: boolean enum: - true required: - mappings - provenance - confirmed responses: '200': description: Replace inventory property mappings content: application/json: schema: anyOf: - type: object properties: dryRun: type: boolean enum: - true valid: type: boolean mapped: type: array items: type: object properties: rowIndex: type: integer maximum: 9007199254740991 minimum: 1 grain: type: string enum: - property - tag targetKind: type: string enum: - key_value - ad_unit - placement propertyExternalId: type: - string - 'null' tag: type: - string - 'null' mapped: type: boolean reason: type: - string - 'null' required: - rowIndex - grain - targetKind - propertyExternalId - tag - mapped - reason additionalProperties: false unmapped: type: array items: type: object properties: rowIndex: type: integer maximum: 9007199254740991 minimum: 1 grain: type: string enum: - property - tag targetKind: type: string enum: - key_value - ad_unit - placement propertyExternalId: type: - string - 'null' tag: type: - string - 'null' mapped: type: boolean reason: type: - string - 'null' required: - rowIndex - grain - targetKind - propertyExternalId - tag - mapped - reason additionalProperties: false keyValueValidation: type: array items: type: object properties: rowIndex: type: integer maximum: 9007199254740991 minimum: 1 signalKey: type: string signalValue: type: string valid: type: boolean reason: type: - string - 'null' required: - rowIndex - signalKey - signalValue - valid - reason additionalProperties: false selectorValidation: type: array items: type: object properties: rowIndex: type: integer maximum: 9007199254740991 minimum: 1 targetKind: type: string enum: - key_value - ad_unit - placement selectorExternalId: type: string valid: type: boolean reason: type: - string - 'null' required: - rowIndex - targetKind - selectorExternalId - valid - reason additionalProperties: false required: - dryRun - valid - mapped - unmapped - keyValueValidation - selectorValidation additionalProperties: false - type: object properties: dryRun: type: boolean enum: - false replacedCount: type: integer minimum: 0 maximum: 9007199254740991 mappings: type: array items: type: object properties: grain: default: property type: string enum: - property - tag propertyExternalId: type: string minLength: 1 publisherDomain: type: string minLength: 1 tag: type: string minLength: 1 targetKind: default: key_value type: string enum: - key_value - ad_unit - placement signalKey: type: string minLength: 1 signalValue: type: string minLength: 1 selectorExternalId: type: string minLength: 1 id: type: string sourceId: type: string provenance: type: object properties: source: type: string enum: - operator - import reference: type: string minLength: 1 maxLength: 500 required: - source additionalProperties: false operatorConfirmedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ operatorConfirmedBy: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastValidatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - grain - targetKind - id - sourceId - provenance - operatorConfirmedAt - operatorConfirmedBy - createdAt - lastValidatedAt additionalProperties: false required: - dryRun - replacedCount - mappings additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Inventory source not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/ad-servers/citrusad: post: operationId: connectCitrusAdAdServer summary: Connect CitrusAd description: Connect CitrusAd as an ad server using the standard sponsored-products composition. The connection appears as one inventory source; its internal modules are implementation details. Store credentials separately through the CitrusAd ad-server credential endpoint. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCitrusAdModularSourceBody' responses: '201': description: Connect CitrusAd content: application/json: schema: $ref: '#/components/schemas/CitrusAdModularSourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/ad-servers/citrusad/credentials/{credentialKind}: post: operationId: saveCitrusAdAdServerCredential summary: Save CitrusAd credentials description: Save a storefront-scoped CitrusAd credential in Secret Manager. Credential values are never returned or stored in module configuration. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: credentialKind schema: description: CitrusAd credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: CitrusAd credential kind requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SaveModularSourceModuleCredentialBody' responses: '201': description: Save CitrusAd credentials content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: rotateCitrusAdAdServerCredential summary: Rotate CitrusAd credentials description: Rotate a storefront-scoped CitrusAd credential in Secret Manager without exposing or storing the credential in source configuration. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: credentialKind schema: description: CitrusAd credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: CitrusAd credential kind requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SaveModularSourceModuleCredentialBody' responses: '200': description: Rotate CitrusAd credentials content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: revokeCitrusAdAdServerCredential summary: Revoke CitrusAd credentials description: Revoke the live storefront-scoped CitrusAd credential and delete its stored secret. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: credentialKind schema: description: CitrusAd credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: CitrusAd credential kind responses: '200': description: Revoke CitrusAd credentials content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/modular/feed: post: operationId: createFeedModularInventorySource summary: Create a modular source with an avails-feed module description: Create a real seller modular inventory source backed by the uploaded/static avails-feed module and, by default, the built-in booking ledger. Execution, reporting, and creative backend details are stored as non-secret setup metadata until matching modules are configured. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateFeedModularSourceBody' responses: '201': description: Create a modular source with an avails-feed module content: application/json: schema: $ref: '#/components/schemas/FeedModularSourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/modular/cadent-demo: post: operationId: createCadentDemoModularInventorySource summary: Create Cadent demo modular source description: Create or reset a demo modular inventory source backed by static avails, a booking ledger, and Cadent execution. Intended for operator-driven live demos. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCadentDemoModularSourceBody' responses: '201': description: Create Cadent demo modular source content: application/json: schema: $ref: '#/components/schemas/CadentDemoModularSourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/modular/freewheel-sandbox: post: operationId: createFreeWheelSandboxModularInventorySource summary: Create FreeWheel sandbox modular source description: Create or update a FreeWheel sandbox modular inventory source backed by static avails, a booking ledger, and live FreeWheel taxonomy selector discovery. Credentials are platform-managed sandbox env vars; callers never supply credential values or env var names. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateFreeWheelSandboxModularSourceBody' responses: '201': description: Create FreeWheel sandbox modular source content: application/json: schema: $ref: '#/components/schemas/FreeWheelSandboxModularSourceResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular: get: operationId: getModularInventorySourceReadiness summary: Get modular inventory source readiness description: Read the runtime projection for a modular inventory source, including module contracts, lifecycle stages, missing setup fields, issues, and open source-side work item counts. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get modular inventory source readiness content: application/json: schema: $ref: '#/components/schemas/InventorySourceRuntimeProjection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/avails-feed: post: operationId: ingestModularInventorySourceAvailsFeed summary: Ingest modular avails feed description: Upsert operator-confirmed normalized avails into a modular inventory source static feed and return the refreshed lifecycle projection and product projections. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/IngestModularAvailsFeedBody' responses: '200': description: Ingest modular avails feed content: application/json: schema: $ref: '#/components/schemas/IngestModularAvailsFeedResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/avails-feed/upload: post: operationId: previewModularInventorySourceAvailsUpload summary: Preview a modular avails file description: Parse a CSV, JSON, XLS, or XLSX modular avails file and return normalized rows and stable row-level diagnostics. This endpoint never commits inventory; submit the returned avails to the JSON avails-feed endpoint with confirmed=true after operator review. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/UploadModularAvailsFeedBody' responses: '200': description: Preview a modular avails file content: application/json: schema: $ref: '#/components/schemas/ModularAvailsPreview' '400': description: Unsupported, oversized, or malformed upload content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/products: get: operationId: listModularInventorySourceProducts summary: List modular inventory products description: List product-like projections from normalized avails on a modular inventory source. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: List modular inventory products content: application/json: schema: $ref: '#/components/schemas/ModularInventoryProductsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/work-items: get: operationId: listModularInventorySourceWorkItems summary: List modular source work items description: List source-side work items for one modular inventory source. Defaults to open, in-progress, and blocked work items. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: status schema: description: Optional comma-separated statuses. Defaults to OPEN, IN_PROGRESS, and BLOCKED. type: array items: type: string enum: - OPEN - IN_PROGRESS - BLOCKED - COMPLETED - CANCELLED description: Optional comma-separated statuses. Defaults to OPEN, IN_PROGRESS, and BLOCKED. - in: query name: kind schema: type: string enum: - APPROVE_MEDIA_BUY - APPROVE_MEDIA_BUY_CANCELLATION - REVIEW_CREATIVE - CONFIRM_AVAILS - APPROVE_RATE_EXCEPTION - MAP_CREATIVE_REF - SYNC_UPSTREAM_CREATIVE - EXECUTE_UPSTREAM_BOOKING - TRAFFIC_TO_CADENT - RESOLVE_TRAFFICKING_ERROR - UPLOAD_FINAL_REPORT - RESOLVE_SOURCE_HEALTH - GENERAL - in: query name: resourceType schema: type: string minLength: 1 - in: query name: resourceId schema: type: string minLength: 1 - in: query name: mediaBuyId schema: type: string minLength: 1 - in: query name: buyerCustomerId schema: type: integer maximum: 9007199254740991 minimum: 1 - in: query name: limit schema: type: integer minimum: 1 maximum: 100 - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: List modular source work items content: application/json: schema: $ref: '#/components/schemas/InventorySourceWorkItemsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/work-items/{workItemId}: get: operationId: getModularInventorySourceWorkItem summary: Get modular source work item description: Fetch a source-side modular inventory work item and its event history. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: workItemId schema: description: Inventory source work item id type: string minLength: 1 required: true description: Inventory source work item id responses: '200': description: Get modular source work item content: application/json: schema: $ref: '#/components/schemas/InventorySourceWorkItemDetailResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: updateModularInventorySourceWorkItem summary: Update modular source work item description: Update assignment, status, notes, or intermediate result metadata for a modular inventory source work item. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: workItemId schema: description: Inventory source work item id type: string minLength: 1 required: true description: Inventory source work item id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateInventorySourceWorkItemBody' responses: '200': description: Update modular source work item content: application/json: schema: $ref: '#/components/schemas/InventorySourceWorkItemMutationResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/work-items/{workItemId}/complete: post: operationId: completeModularInventorySourceWorkItem summary: Complete modular source work item description: Complete a modular inventory source work item and apply any completion side effects required by the module contract. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: workItemId schema: description: Inventory source work item id type: string minLength: 1 required: true description: Inventory source work item id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CompleteInventorySourceWorkItemBody' responses: '200': description: Complete modular source work item content: application/json: schema: $ref: '#/components/schemas/InventorySourceWorkItemMutationResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/inventory/capabilities: get: operationId: getModularInventoryCapabilities summary: Get modular inventory capabilities description: Return selector and targeting capabilities exposed by a modular inventory source taxonomy module, currently FreeWheel sandbox taxonomy selectors. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get modular inventory capabilities content: application/json: schema: $ref: '#/components/schemas/FreeWheelInventoryCapabilitiesResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/inventory/selectors: get: operationId: searchModularInventorySelectors summary: Search modular inventory selectors description: Search upstream taxonomy selectors for a modular inventory source. For FreeWheel sandbox sources this reads live selector taxonomy, not avails or forecasted capacity. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: selectorType schema: type: string enum: - site - site_section - site_group - series - video_group - ad_unit_package - ad_unit_node - standard_attribute required: true - in: query name: q schema: type: string - in: query name: query schema: type: string - in: query name: parentId schema: type: string - in: query name: cursor schema: type: string - in: query name: limit schema: type: integer minimum: 1 maximum: 100 - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Search modular inventory selectors content: application/json: schema: $ref: '#/components/schemas/FreeWheelInventorySelectorPageResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/reservations: post: operationId: reserveModularInventoryProduct summary: Reserve modular inventory product description: Hold capacity against one modular inventory product projection without overbooking. One of productId or availId is required. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReserveModularInventoryProductBody' responses: '200': description: Reserve modular inventory product content: application/json: schema: $ref: '#/components/schemas/ReserveModularInventoryProductResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/bookings/finalize: post: operationId: finalizeModularInventoryBooking summary: Prepare modular booking handoff description: 'Prepare a held modular inventory reservation for source execution: render Cadent XML for Cadent demo sources or create FreeWheel source-side HITL work items for FreeWheel modular sources. The ledger remains HELD until upstream booking work succeeds.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FinalizeModularInventoryBookingBody' responses: '200': description: Prepare modular booking handoff content: application/json: schema: $ref: '#/components/schemas/FinalizeModularInventoryBookingResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/bookings/release: post: operationId: releaseModularInventoryBooking summary: Release modular inventory booking description: Release a held modular inventory reservation or cancel a locally booked reservation, returning capacity to the avail. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReleaseModularInventoryBookingBody' responses: '200': description: Release modular inventory booking content: application/json: schema: $ref: '#/components/schemas/ReserveModularInventoryProductResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/modules/{moduleInstanceId}/config: patch: operationId: updateModularInventorySourceModuleConfig summary: Update modular source module config description: Update non-secret configuration for one module on a modular inventory source. Nested config objects are deep-merged by default; pass merge=false to replace the module config. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: moduleInstanceId schema: description: Seller-local module instance id type: string minLength: 1 required: true description: Seller-local module instance id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateModularSourceModuleConfigBody' responses: '200': description: Update modular source module config content: application/json: schema: $ref: '#/components/schemas/InventorySourceRuntimeProjection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/modular/modules/{moduleInstanceId}/credentials/{credentialKind}: post: operationId: createModularInventorySourceModuleCredential summary: Create modular source module credential description: Store a storefront-scoped provider credential for one private modular source module. Raw auth is written to secret storage and never returned. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: moduleInstanceId schema: description: Seller-local module instance id type: string minLength: 1 required: true description: Seller-local module instance id - in: path name: credentialKind schema: description: Module credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: Module credential kind requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SaveModularSourceModuleCredentialBody' responses: '201': description: Create modular source module credential content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: rotateModularInventorySourceModuleCredential summary: Rotate modular source module credential description: Replace the live credential for one private modular source module and revoke its previous secret. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: moduleInstanceId schema: description: Seller-local module instance id type: string minLength: 1 required: true description: Seller-local module instance id - in: path name: credentialKind schema: description: Module credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: Module credential kind requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SaveModularSourceModuleCredentialBody' responses: '200': description: Rotate modular source module credential content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: revokeModularInventorySourceModuleCredential summary: Revoke modular source module credential description: Revoke the live credential for one private modular source module and delete its stored secret. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID - in: path name: moduleInstanceId schema: description: Seller-local module instance id type: string minLength: 1 required: true description: Seller-local module instance id - in: path name: credentialKind schema: description: Module credential kind type: string enum: - API_KEY - BEARER - OAUTH required: true description: Module credential kind responses: '200': description: Revoke modular source module credential content: application/json: schema: $ref: '#/components/schemas/ModularSourceModuleCredentialResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/feed/preview: post: operationId: previewInventoryFeed summary: Preview a feed revision (HITL) description: Parse and catalog-resolve an inventory feed payload to produce a PREVIEW revision and a signed baseline token. Both static-avails-feed:v1 (JSON rows) and wholesale-avails-pricing:v1 are supported. Pass the returned revision and previewBaseline to POST /feed/commit to commit it. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FeedPreviewBody' responses: '200': description: Preview a feed revision (HITL) content: application/json: schema: $ref: '#/components/schemas/FeedPreviewResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Ambiguous module match — multiple active feed modules found for this source and contract. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/feed/upload: post: operationId: uploadInventoryFeed summary: Upload a feed file (HITL, multipart) description: Multipart form-data variant of POST /feed/preview. Send a CSV, JSON, XLS, or XLSX file as the `file` part alongside the metadata fields. Produces the same PREVIEW revision and signed baseline as the JSON preview endpoint. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/FeedUploadBody' responses: '200': description: Upload a feed file (HITL, multipart) content: application/json: schema: $ref: '#/components/schemas/FeedPreviewResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Ambiguous module match — multiple active feed modules found for this source and contract. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/feed/commit: post: operationId: commitInventoryFeed summary: Commit a previewed feed revision (HITL) description: Atomically promote a signed PREVIEW baseline to a COMMITTED revision. The previewBaseline encodes the expected active_revision_id — if another commit advanced the head since the preview, this call returns 422 STALE_PREVIEW_BASELINE. Pass feedId, previewBaseline, and revision exactly as returned by POST /feed/preview or POST /feed/upload. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FeedCommitBody' responses: '200': description: Commit a previewed feed revision (HITL) content: application/json: schema: $ref: '#/components/schemas/FeedCommitResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': description: STALE_PREVIEW_BASELINE — the feed head advanced since the preview. Re-preview and re-commit. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/feed/push: post: operationId: pushInventoryFeed summary: Push a feed revision (API_PUSH, no preview step) description: 'One-shot API_PUSH ingest: parse, validate, and commit in a single call. No preview or baseline is required. Set dryRun: true to validate without committing. The HITL and API_PUSH transports share the same canonical feed head, so an API_PUSH commit fences subsequent HITL commits that hold a stale baseline.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FeedPushBody' responses: '200': description: Push a feed revision (API_PUSH, no preview step) content: application/json: schema: $ref: '#/components/schemas/FeedPushResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Ambiguous module match — multiple active feed modules found for this source and contract. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/esa: get: operationId: getInventorySourceEsa summary: Get ad-server source connection description: Read the connection state for an ad-server-backed inventory source. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get ad-server source connection content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/status: get: operationId: getInventorySourceEsaStatus summary: Get ad-server source status description: Fetch the upstream managed-source operational snapshot (adapter health, syncs, workflows, packages, creatives, webhooks, setup tasks). tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: includeSyncHistory schema: type: boolean - in: query name: syncHistoryLimit schema: default: 5 type: integer minimum: 1 maximum: 10 - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Get ad-server source status content: application/json: schema: $ref: '#/components/schemas/EsaTenantStatus' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/sync-history: get: operationId: listInventorySourceEsaSyncHistory summary: List ad-server source sync history description: List historical sync runs for an ad-server-backed inventory source. Use this for drill-down after reading the coarse source-status sync blocks. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: syncType schema: type: string - in: query name: status schema: type: string - in: query name: limit schema: type: integer minimum: 1 maximum: 500 - in: query name: cursor schema: type: string - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: List ad-server source sync history content: application/json: schema: $ref: '#/components/schemas/EsaSyncHistoryResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/launch: post: operationId: launchInventorySourceEsa summary: Mint a launch URL into the managed source admin UI description: Sign a one-time URL that drops the caller into the upstream managed-source admin UI. Pass an optional deep-link `path` to land on a specific page. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LaunchEsaBody' responses: '200': description: Mint a launch URL into the managed source admin UI content: application/json: schema: $ref: '#/components/schemas/LaunchEsaResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/ad-server: put: operationId: putInventorySourceAdServer summary: Replace ad-server source config description: Set the ad-server configuration on an ad-server-backed inventory source. The body is a full replacement (PUT semantics); PATCH is accepted as an alias for backwards compatibility with the legacy /esa/ad-server route. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AdServerConfig' responses: '200': description: Replace ad-server source config content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: patchInventorySourceAdServer summary: Replace ad-server source config (alias) description: Alias of PUT /inventory-sources/{sourceId}/ad-server. Accepts the same body and emits the same response — exists so existing clients of the legacy /esa/ad-server route can migrate without changing HTTP method. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AdServerConfig' responses: '200': description: Replace ad-server source config (alias) content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/adapter-config: put: operationId: rotateInventorySourceAdapterCredentials summary: Rotate ad-server source credentials description: In-place credential rotation for an already-provisioned ad-server source. Products, principals, and sync history survive. Required for FreeWheel and SpringServe whose credentials rotate; Google Ad Manager rotation uses the ad-server endpoint above since Scope3 manages those credentials. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AdServerConfig' responses: '200': description: Rotate ad-server source credentials content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/test-connection: post: operationId: testInventorySourceEsaConnection summary: Test the ad-server source connection description: Probe the upstream adapter for reachability against the provisioned ad-server credentials. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Test the ad-server source connection content: application/json: schema: $ref: '#/components/schemas/EsaTestConnectionResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/refresh: post: operationId: refreshInventorySourceEsa summary: Refresh the ad-server source snapshot description: Start upstream ad-server sync runs for this source. Returns `started` or `already_running` plus the upstream sync run ids for correlation. Source-id alias of `POST /esa/{esaId}/refresh`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Refresh the ad-server source snapshot content: application/json: schema: $ref: '#/components/schemas/EsaRefreshResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/deactivate: post: operationId: deactivateInventorySourceEsa summary: Deactivate the ad-server source description: Soft-delete the ad-server source. The connection row stays so the storefront can re-provision later. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Deactivate the ad-server source content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /inventory-sources/{sourceId}/reactivate: post: operationId: reactivateInventorySourceEsa summary: Reactivate a deactivated ad-server source description: Re-enable a previously deactivated ad-server source. Returns the connection in `active` state. If the upstream managed source is gone (TENANT_NOT_FOUND), the caller must create a fresh connection instead. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: sourceId schema: description: Inventory source ID type: string minLength: 1 required: true description: Inventory source ID responses: '200': description: Reactivate a deactivated ad-server source content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/service-account: post: operationId: ensureEsaServiceAccount summary: Ensure ad server source service account description: Ensure the platform service account used to manage ad server sources exists for this customer. Returns the service account email (null when provisioning is not applicable). tags: - Storefront security: - bearerAuth: [] responses: '200': description: Ensure ad server source service account content: application/json: schema: $ref: '#/components/schemas/EsaServiceAccountResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa: get: operationId: listEsaConnections summary: List ad server sources description: List the customer's ad server source connections with their ad-server type and status. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List ad server sources content: application/json: schema: $ref: '#/components/schemas/EsaConnectionList' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}: get: operationId: getEsaConnection summary: Get an ad server source description: Get a single ad server source by its connection id. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Get an ad server source content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/test-connection: post: operationId: testEsaConnection summary: Test an ad server source description: Probe the connection's ad-server credentials and report whether the upstream agent can reach the ad server. Connection-id alias of `POST /inventory-sources/{sourceId}/test-connection`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Test an ad server source content: application/json: schema: $ref: '#/components/schemas/EsaTestConnectionResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/refresh: post: operationId: refreshEsa summary: Refresh an ad server source description: Start upstream ad-server sync runs for this connection. Returns `started` or `already_running` plus the upstream sync run ids for correlation. Connection-id alias of `POST /inventory-sources/{sourceId}/refresh`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Refresh an ad server source content: application/json: schema: $ref: '#/components/schemas/EsaRefreshResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/capabilities/{capability}/recheck: post: operationId: recheckEsaCapability summary: Re-check an ad server capability description: Explicitly re-check a separately provisioned reporting or forecasting capability. Use this after the ad-server vendor confirms the permission is live. A successful check may resume the paused capability sync. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. - in: path name: capability schema: description: Separately provisioned ad-server capability to re-check. example: reporting allOf: - $ref: '#/components/schemas/EsaCapability' required: true description: Separately provisioned ad-server capability to re-check. responses: '200': description: Re-check an ad server capability content: application/json: schema: $ref: '#/components/schemas/EsaCapabilityRecheckResult' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Another source operation conflicts with the re-check. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '503': description: The managed source is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/deactivate: post: operationId: deactivateEsa summary: Deactivate an ad server source description: Soft-delete the ad server source. The connection row stays so the storefront can re-provision later. Connection-id alias of `POST /inventory-sources/{sourceId}/deactivate`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Deactivate an ad server source content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/reactivate: post: operationId: reactivateEsa summary: Reactivate an ad server source description: Re-enable a previously deactivated ad server source. Returns the connection in `active` state. If the upstream managed source is gone (TENANT_NOT_FOUND), the caller must create a fresh connection instead. Connection-id alias of `POST /inventory-sources/{sourceId}/reactivate`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Reactivate an ad server source content: application/json: schema: $ref: '#/components/schemas/EsaConnection' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/status: get: operationId: getEsaStatus summary: Get ad server source status description: Fetch the upstream managed-source operational snapshot (adapter health, syncs, workflows, packages, creatives, webhooks, setup tasks). Connection-id alias of `GET /inventory-sources/{sourceId}/status`. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: includeSyncHistory schema: type: boolean - in: query name: syncHistoryLimit schema: default: 5 type: integer minimum: 1 maximum: 10 - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: Get ad server source status content: application/json: schema: $ref: '#/components/schemas/EsaTenantStatus' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/sync-history: get: operationId: getEsaSyncHistory summary: List ad server source sync history description: List historical sync runs for an ad-server-backed connection. Use this for drill-down after reading the coarse source-status sync blocks. Connection-id alias of `GET /inventory-sources/{sourceId}/sync-history`. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: syncType schema: type: string - in: query name: status schema: type: string - in: query name: limit schema: type: integer minimum: 1 maximum: 500 - in: query name: cursor schema: type: string - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. responses: '200': description: List ad server source sync history content: application/json: schema: $ref: '#/components/schemas/EsaSyncHistoryResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No ad server source with this id. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /esa/{esaId}/launch: post: operationId: mintEsaLaunchUrl summary: Mint an ad server source launch URL description: Sign a one-time URL that drops the caller into the managed-source admin UI. Pass an optional deep-link `path` to land on a specific page. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: esaId schema: description: Ad server source connection id. The wire field remains `esaId` for API compatibility. example: 123 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Ad server source connection id. The wire field remains `esaId` for API compatibility. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LaunchEsaBody' responses: '200': description: Mint an ad server source launch URL content: application/json: schema: $ref: '#/components/schemas/LaunchEsaResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /operating-instructions: get: operationId: listOperatingInstructions summary: List operating-instructions versions description: List all operating-instructions versions for the storefront, newest first. The active version (if any) is flagged via `isActive` on each row. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List operating-instructions versions content: application/json: schema: $ref: '#/components/schemas/OperatingInstructionsListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createOperatingInstructions summary: Create a new operating-instructions version description: Author a new operating-instructions version. The new version number is computed atomically as MAX(version)+1 for the storefront. Does not auto-activate — call the activate endpoint to swap the storefront's active pointer. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateOperatingInstructionsBody' responses: '201': description: Create a new operating-instructions version content: application/json: schema: $ref: '#/components/schemas/OperatingInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /operating-instructions/active: get: operationId: getActiveOperatingInstructions summary: Get the active operating-instructions version description: Return the version currently advertised as active for the storefront. Returns 404 when no version has been activated. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get the active operating-instructions version content: application/json: schema: $ref: '#/components/schemas/OperatingInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /operating-instructions/{version}: get: operationId: getOperatingInstructionsVersion summary: Get a specific operating-instructions version description: Fetch a single operating-instructions version by its version number. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: version schema: description: Per-storefront version number (monotone, starts at 1, never reused). example: 3 type: integer minimum: 1 maximum: 9007199254740991 required: true description: Per-storefront version number (monotone, starts at 1, never reused). responses: '200': description: Get a specific operating-instructions version content: application/json: schema: $ref: '#/components/schemas/OperatingInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /operating-instructions/{version}/activate: post: operationId: activateOperatingInstructions summary: Activate an operating-instructions version description: Set the storefront's active operating-instructions pointer to the specified version. Subsequent compositions consume this version. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: version schema: description: Per-storefront version number (monotone, starts at 1, never reused). example: 3 type: integer minimum: 1 maximum: 9007199254740991 required: true description: Per-storefront version number (monotone, starts at 1, never reused). responses: '200': description: Activate an operating-instructions version content: application/json: schema: $ref: '#/components/schemas/OperatingInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /acceptance-policy: get: operationId: listAcceptancePolicies summary: List acceptance-policy versions description: List all acceptance-policy versions for the storefront, newest first. The active version, if any, is flagged via `isActive` on each row. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List acceptance-policy versions content: application/json: schema: $ref: '#/components/schemas/AcceptancePolicyListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createAcceptancePolicy summary: Create a new acceptance-policy version description: 'Author a new immutable acceptance-policy version. Version allocation is serialized per storefront. Pass `activate: true` to create the version and swap the storefront''s active-policy pointer atomically; otherwise the active version is unchanged.' tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateAcceptancePolicyBody' responses: '201': description: Create a new acceptance-policy version content: application/json: schema: $ref: '#/components/schemas/AcceptancePolicyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /acceptance-policy/active: get: operationId: getActiveAcceptancePolicy summary: Get the active acceptance-policy version description: Return the active acceptance policy used by storefront creative and media-buy approval workflows. Returns 404 when no policy has been activated. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get the active acceptance-policy version content: application/json: schema: $ref: '#/components/schemas/AcceptancePolicyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /acceptance-policy/{version}: get: operationId: getAcceptancePolicyVersion summary: Get a specific acceptance-policy version description: Fetch a single acceptance-policy version by its version number. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: version schema: description: Per-storefront acceptance policy version number. Monotone, starts at 1, and is never reused. example: 3 type: integer minimum: 1 maximum: 9007199254740991 required: true description: Per-storefront acceptance policy version number. Monotone, starts at 1, and is never reused. responses: '200': description: Get a specific acceptance-policy version content: application/json: schema: $ref: '#/components/schemas/AcceptancePolicyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /acceptance-policy/{version}/activate: post: operationId: activateAcceptancePolicy summary: Activate an acceptance-policy version description: Set the storefront's active acceptance-policy pointer to the specified version. Approval workflows use this version. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: version schema: description: Per-storefront acceptance policy version number. Monotone, starts at 1, and is never reused. example: 3 type: integer minimum: 1 maximum: 9007199254740991 required: true description: Per-storefront acceptance policy version number. Monotone, starts at 1, and is never reused. responses: '200': description: Activate an acceptance-policy version content: application/json: schema: $ref: '#/components/schemas/AcceptancePolicyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /learned-default-posture: put: operationId: setLearnedDefaultPosture summary: Pin or clear the learned default posture description: 'Pin a negotiation posture as the storefront''s learned default, or clear it (send posture: null). The learned default is a fallback the Merchandising Agent uses only when it has no fresher read for a buyer; operating instructions and buyer-specific rules always take precedence. The storefront is resolved from auth context.' tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SetLearnedDefaultPostureBody' responses: '200': description: Pin or clear the learned default posture content: application/json: schema: $ref: '#/components/schemas/LearnedDefaultPostureResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the authenticated caller. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /buyer-instructions: get: operationId: listBuyerInstructions summary: List buyer-instructions rows description: List every buyer-instructions row configured on the storefront. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List buyer-instructions rows content: application/json: schema: $ref: '#/components/schemas/BuyerInstructionsListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createBuyerInstructions summary: Create a buyer-instructions row description: Create a new buyer-instructions row. The (operatorDomain, brandDomain) tuple is unique per storefront — duplicate scopes return 409; use PATCH to update an existing row. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateBuyerInstructionsBody' responses: '201': description: Create a buyer-instructions row content: application/json: schema: $ref: '#/components/schemas/BuyerInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: A buyer-instructions row already exists for this (operatorDomain, brandDomain) on the storefront. Use PATCH to update it. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /buyer-instructions/{id}: patch: operationId: updateBuyerInstructions summary: Update a buyer-instructions row description: Partially update a buyer-instructions row. Scope columns (operatorDomain, brandDomain) are immutable — delete and recreate to change them. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the buyer-instruction row. example: 17 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the buyer-instruction row. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateBuyerInstructionsBody' responses: '200': description: Update a buyer-instructions row content: application/json: schema: $ref: '#/components/schemas/BuyerInstructionsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteBuyerInstructions summary: Delete a buyer-instructions row description: Delete a buyer-instructions row by id. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the buyer-instruction row. example: 17 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the buyer-instruction row. responses: '204': description: No content '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /house-discounts: get: operationId: listHouseDiscounts summary: List rate-card discount rows description: List every rate-card discount row (brand- and operator-scoped) configured on the storefront. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List rate-card discount rows content: application/json: schema: $ref: '#/components/schemas/HouseDiscountListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createHouseDiscount summary: Create a rate-card discount row description: Create a discount keyed to a buyer brand or operator (scope), resolved up its corporate hierarchy. (house_domain, scope) is unique per storefront — a duplicate returns 409; use PATCH to update an existing row. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateHouseDiscountBody' responses: '201': description: Create a rate-card discount row content: application/json: schema: $ref: '#/components/schemas/HouseDiscountResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: A house discount already exists for this house_domain on the storefront. Use PATCH to update it. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /house-discounts/resolve: get: operationId: resolveHouseHierarchy summary: Resolve a domain up its corporate hierarchy (authoring preview) description: 'Read-only helper for the authoring UI: resolves a brand or operator domain up its published corporate hierarchy (e.g. converse.com → nike.com) so you can preview where a discount would key before saving it. Creates and matches nothing.' tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: domain schema: description: The brand or operator domain to resolve up its corporate hierarchy. example: converse.com type: string minLength: 1 maxLength: 253 required: true description: The brand or operator domain to resolve up its corporate hierarchy. responses: '200': description: Resolve a domain up its corporate hierarchy (authoring preview) content: application/json: schema: $ref: '#/components/schemas/ResolveHouseResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /house-discounts/{id}: patch: operationId: updateHouseDiscount summary: Update a rate-card discount row description: Partially update a rate-card discount row. Only discountPercent and notes are mutable; house_domain and scope are immutable — delete and recreate to change either. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the house-discount row. example: 17 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the house-discount row. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateHouseDiscountBody' responses: '200': description: Update a rate-card discount row content: application/json: schema: $ref: '#/components/schemas/HouseDiscountResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No house discount with this id exists on the storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteHouseDiscount summary: Delete a rate-card discount row description: Delete a rate-card discount row by id. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the house-discount row. example: 17 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the house-discount row. responses: '204': description: No content '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No house discount with this id exists on the storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /buyer-auto-approvals: get: operationId: listBuyerAutoApprovals summary: List per-buyer media-buy auto-approve overrides description: List the per-buyer media-buy auto-approve overrides on the storefront (enabled and disabled rows), with each buyer's resolved name. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List per-buyer media-buy auto-approve overrides content: application/json: schema: $ref: '#/components/schemas/BuyerAutoApproveListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /buyer-auto-approvals/{buyerCustomerId}: put: operationId: setBuyerAutoApprove summary: Enable or disable per-buyer media-buy auto-approve description: Opt one trusted buyer into (enabled:true) or out of (enabled:false) automatic approval for their media buys. While enabled, that buyer's media buys bypass acceptance-policy screening and human review. The override affects media buys only (not creative review), and only takes effect while the storefront's mediaBuyApproval is manual. The buyer must have transacted with the storefront — an unknown id returns 404. The storefront is resolved from auth context; the row is kept on disable for audit. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: buyerCustomerId schema: description: Customer id of the buyer to opt into (or out of) auto-approve. example: 804 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Customer id of the buyer to opt into (or out of) auto-approve. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SetBuyerAutoApproveBody' responses: '200': description: Enable or disable per-buyer media-buy auto-approve content: application/json: schema: $ref: '#/components/schemas/BuyerAutoApproveResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the authenticated caller, or the buyer has no media buys on this storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /simulator/scenarios: get: operationId: listMerchandisingSimulationScenarios summary: List merchandising simulation scenarios description: List the authenticated seller Storefront’s immutable Simulator scenarios. Runnable status reflects the 30-day replay-material window; expired scenario evidence remains readable. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: limit schema: default: 50 type: integer minimum: 1 maximum: 100 - in: query name: offset schema: default: 0 type: integer minimum: 0 maximum: 9007199254740991 responses: '200': description: List merchandising simulation scenarios content: application/json: schema: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ storefrontId: type: string latestTitle: type: string latestRevisionNumber: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object latestRunnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - latestTitle - latestRevisionNumber - sourceScope - latestRunnableUntil - isRunnable - createdByUserId - createdAt additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: createMerchandisingSimulationScenario summary: Create a merchandising simulation scenario description: Create an immutable scenario and baseline revision from a sample, a seller-provided brief, or a same-Storefront observed decision. The server captures configuration and replay provenance; clients cannot submit authoritative snapshots. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: title: type: string minLength: 1 maxLength: 120 sourceId: type: string minLength: 1 maxLength: 500 source: oneOf: - type: object properties: sourceKind: type: string enum: - sample sourceRef: type: string minLength: 1 maxLength: 500 required: - sourceKind - sourceRef additionalProperties: false - type: object properties: sourceKind: type: string enum: - live_observed sourceRef: type: string pattern: ^\d+$ required: - sourceKind - sourceRef additionalProperties: false - type: object properties: sourceKind: type: string enum: - seller_provided sourceRef: type: string minLength: 1 maxLength: 500 brief: type: string minLength: 1 maxLength: 10000 required: - sourceKind - sourceRef - brief additionalProperties: false type: object required: - title - source additionalProperties: false responses: '201': description: Create a merchandising simulation scenario content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ storefrontId: type: string latestTitle: type: string latestRevisionNumber: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object latestRunnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ revisions: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ scenarioId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionNumber: type: integer maximum: 9007199254740991 minimum: 1 title: type: string sourceKind: type: string enum: - sample - seller_provided - live_observed sourceRef: type: string briefSnapshot: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' observedDecisionSnapshot: type: - object - 'null' additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputSummary: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputDigest: type: string pattern: ^[a-f0-9]{64}$ schemaVersion: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object runnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean replayAvailableUntil: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ variants: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ slotIndex: type: integer minimum: 0 maximum: 3 generation: type: integer maximum: 9007199254740991 minimum: 1 label: type: string isBaseline: type: boolean overrides: anyOf: - type: object properties: {} additionalProperties: false - type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false overrideDigest: type: string pattern: ^[a-f0-9]{64}$ supersedesVariantId: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ executions: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ decisionRecord: $ref: '#/components/schemas/SellerDecisionRecord' sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - decisionRecord - sourceScope - createdByUserId - createdAt additionalProperties: false executionHistory: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - sourceScope - createdByUserId - createdAt additionalProperties: false required: - id - revisionId - slotIndex - generation - label - isBaseline - overrides - overrideDigest - supersedesVariantId - createdByUserId - createdAt - executions - executionHistory additionalProperties: false createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - scenarioId - revisionNumber - title - sourceKind - sourceRef - briefSnapshot - observedDecisionSnapshot - inputSummary - inputDigest - schemaVersion - sourceScope - runnableUntil - isRunnable - replayAvailableUntil - variants - createdByUserId - createdAt additionalProperties: false required: - id - storefrontId - latestTitle - latestRevisionNumber - sourceScope - latestRunnableUntil - isRunnable - createdByUserId - createdAt - revisions additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /simulator/scenarios/{scenarioId}: get: operationId: getMerchandisingSimulationScenario summary: Get a merchandising simulation scenario description: Read one tenant-scoped scenario with every immutable revision and declared variant generation. Replay inputs are never returned. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: scenarioId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true responses: '200': description: Get a merchandising simulation scenario content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ storefrontId: type: string latestTitle: type: string latestRevisionNumber: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object latestRunnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ revisions: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ scenarioId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionNumber: type: integer maximum: 9007199254740991 minimum: 1 title: type: string sourceKind: type: string enum: - sample - seller_provided - live_observed sourceRef: type: string briefSnapshot: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' observedDecisionSnapshot: type: - object - 'null' additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputSummary: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputDigest: type: string pattern: ^[a-f0-9]{64}$ schemaVersion: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object runnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean replayAvailableUntil: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ variants: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ slotIndex: type: integer minimum: 0 maximum: 3 generation: type: integer maximum: 9007199254740991 minimum: 1 label: type: string isBaseline: type: boolean overrides: anyOf: - type: object properties: {} additionalProperties: false - type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false overrideDigest: type: string pattern: ^[a-f0-9]{64}$ supersedesVariantId: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ executions: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ decisionRecord: $ref: '#/components/schemas/SellerDecisionRecord' sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - decisionRecord - sourceScope - createdByUserId - createdAt additionalProperties: false executionHistory: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - sourceScope - createdByUserId - createdAt additionalProperties: false required: - id - revisionId - slotIndex - generation - label - isBaseline - overrides - overrideDigest - supersedesVariantId - createdByUserId - createdAt - executions - executionHistory additionalProperties: false createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - scenarioId - revisionNumber - title - sourceKind - sourceRef - briefSnapshot - observedDecisionSnapshot - inputSummary - inputDigest - schemaVersion - sourceScope - runnableUntil - isRunnable - replayAvailableUntil - variants - createdByUserId - createdAt additionalProperties: false required: - id - storefrontId - latestTitle - latestRevisionNumber - sourceScope - latestRunnableUntil - isRunnable - createdByUserId - createdAt - revisions additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No scenario with this id on the caller’s Storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /simulator/scenarios/{scenarioId}/revisions: post: operationId: createMerchandisingSimulationRevision summary: Append a merchandising simulation revision description: Append a newly captured immutable revision without rewriting prior evidence. Each revision receives a no-override baseline and its own 30-day replay window. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: scenarioId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true requestBody: required: true content: application/json: schema: type: object properties: title: type: string minLength: 1 maxLength: 120 sourceId: type: string minLength: 1 maxLength: 500 source: oneOf: - type: object properties: sourceKind: type: string enum: - sample sourceRef: type: string minLength: 1 maxLength: 500 required: - sourceKind - sourceRef additionalProperties: false - type: object properties: sourceKind: type: string enum: - live_observed sourceRef: type: string pattern: ^\d+$ required: - sourceKind - sourceRef additionalProperties: false - type: object properties: sourceKind: type: string enum: - seller_provided sourceRef: type: string minLength: 1 maxLength: 500 brief: type: string minLength: 1 maxLength: 10000 required: - sourceKind - sourceRef - brief additionalProperties: false type: object required: - title - source additionalProperties: false responses: '201': description: Append a merchandising simulation revision content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ scenarioId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionNumber: type: integer maximum: 9007199254740991 minimum: 1 title: type: string sourceKind: type: string enum: - sample - seller_provided - live_observed sourceRef: type: string briefSnapshot: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' observedDecisionSnapshot: type: - object - 'null' additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputSummary: type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' inputDigest: type: string pattern: ^[a-f0-9]{64}$ schemaVersion: type: integer maximum: 9007199254740991 minimum: 1 sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object runnableUntil: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isRunnable: type: boolean replayAvailableUntil: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ variants: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ slotIndex: type: integer minimum: 0 maximum: 3 generation: type: integer maximum: 9007199254740991 minimum: 1 label: type: string isBaseline: type: boolean overrides: anyOf: - type: object properties: {} additionalProperties: false - type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false overrideDigest: type: string pattern: ^[a-f0-9]{64}$ supersedesVariantId: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ executions: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ decisionRecord: $ref: '#/components/schemas/SellerDecisionRecord' sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - decisionRecord - sourceScope - createdByUserId - createdAt additionalProperties: false executionHistory: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - sourceScope - createdByUserId - createdAt additionalProperties: false required: - id - revisionId - slotIndex - generation - label - isBaseline - overrides - overrideDigest - supersedesVariantId - createdByUserId - createdAt - executions - executionHistory additionalProperties: false createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - scenarioId - revisionNumber - title - sourceKind - sourceRef - briefSnapshot - observedDecisionSnapshot - inputSummary - inputDigest - schemaVersion - sourceScope - runnableUntil - isRunnable - replayAvailableUntil - variants - createdByUserId - createdAt additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No scenario with this id on the caller’s Storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /simulator/scenarios/{scenarioId}/revisions/{revisionId}/variants: post: operationId: appendMerchandisingSimulationVariant summary: Append a merchandising simulation variant description: Add one declared posture, pricing, or rule variant without changing any live Storefront control. A revision supports its baseline plus at most three counterfactual variants. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: scenarioId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true - in: path name: revisionId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true requestBody: required: true content: application/json: schema: type: object properties: label: type: string minLength: 1 maxLength: 80 overrides: type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false supersedesVariantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: - label - overrides additionalProperties: false responses: '201': description: Append a merchandising simulation variant content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ slotIndex: type: integer minimum: 0 maximum: 3 generation: type: integer maximum: 9007199254740991 minimum: 1 label: type: string isBaseline: type: boolean overrides: anyOf: - type: object properties: {} additionalProperties: false - type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false overrideDigest: type: string pattern: ^[a-f0-9]{64}$ supersedesVariantId: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ executions: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ decisionRecord: $ref: '#/components/schemas/SellerDecisionRecord' sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - decisionRecord - sourceScope - createdByUserId - createdAt additionalProperties: false executionHistory: default: [] type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - sourceScope - createdByUserId - createdAt additionalProperties: false required: - id - revisionId - slotIndex - generation - label - isBaseline - overrides - overrideDigest - supersedesVariantId - createdByUserId - createdAt - executions - executionHistory additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No scenario or revision with these ids on the caller’s Storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The revision already has three counterfactual variants. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /simulator/scenarios/{scenarioId}/revisions/{revisionId}/variants/{variantId}/executions: post: operationId: executeMerchandisingSimulationVariant summary: Execute a pinned merchandising simulation variant description: Execute one unexpired pinned variant through the resolved merchandising engine and append an immutable Seller Decision Record. The empty request body cannot replace frozen inputs or mutate live Storefront controls. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: scenarioId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true - in: path name: revisionId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true - in: path name: variantId schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true requestBody: required: true content: application/json: schema: type: object properties: {} additionalProperties: false responses: '201': description: Execute a pinned merchandising simulation variant content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ variantId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ intelligenceRunId: type: string attemptNumber: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - succeeded - failed resultCode: type: - string - 'null' inputDigest: type: string pattern: ^[a-f0-9]{64}$ overrideDigest: type: string pattern: ^[a-f0-9]{64}$ outputDigest: type: string pattern: ^[a-f0-9]{64}$ decisionRecord: $ref: '#/components/schemas/SellerDecisionRecord' sourceScope: default: mode: storefront sourceId: null sourceName: null diagnostics: includedBundleCount: 0 includedSignalCount: 0 excludedBundleCount: 0 excludedSignalCount: 0 missingLineageCount: 0 ambiguousLineageCount: 0 crossSourceLineageCount: 0 oneOf: - type: object properties: mode: type: string enum: - storefront sourceId: type: - string - 'null' enum: - null sourceName: type: - string - 'null' enum: - null diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false - type: object properties: mode: type: string enum: - source sourceId: type: string minLength: 1 maxLength: 500 sourceName: type: string minLength: 1 maxLength: 500 diagnostics: type: object properties: includedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 includedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 excludedBundleCount: type: integer minimum: 0 maximum: 9007199254740991 excludedSignalCount: type: integer minimum: 0 maximum: 9007199254740991 missingLineageCount: type: integer minimum: 0 maximum: 9007199254740991 ambiguousLineageCount: type: integer minimum: 0 maximum: 9007199254740991 crossSourceLineageCount: type: integer minimum: 0 maximum: 9007199254740991 required: - includedBundleCount - includedSignalCount - excludedBundleCount - excludedSignalCount - missingLineageCount - ambiguousLineageCount - crossSourceLineageCount additionalProperties: false required: - mode - sourceId - sourceName - diagnostics additionalProperties: false type: object createdByUserId: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - revisionId - variantId - intelligenceRunId - attemptNumber - status - resultCode - inputDigest - overrideDigest - outputDigest - decisionRecord - sourceScope - createdByUserId - createdAt additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: The scenario, revision, or variant was not found for this Storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The revision or variant changed before execution evidence could be recorded. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': description: The revision replay window expired and a new revision is required. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /intelligence-runs: get: operationId: listIntelligenceRuns summary: List storefront intelligence-run records description: Paginated list of intelligence-run records for the storefront, newest first. Each row captures the prompt, raw + parsed LLM output, matched buyer-instructions, and the result envelope. Page with `?skip=` and `?take=`. Filter the seller demand inbox with `?disposition=` (`responded` / `declined_fit` / `declined_policy` / `not_live`); an invalid value returns 400. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: skip schema: description: Number of rows to skip (offset pagination). example: 0 default: 0 type: integer minimum: 0 maximum: 9007199254740991 description: Number of rows to skip (offset pagination). - in: query name: take schema: description: Number of rows to return per page (1–100). example: 25 default: 25 type: integer minimum: 1 maximum: 100 description: Number of rows to return per page (1–100). - in: query name: disposition schema: description: 'Demand-inbox filter — return only runs with this brief outcome: `responded` (the storefront composed a response), `declined_fit` (declined: no matching inventory), `declined_policy` (declined: acceptance-policy violation), or `not_live` (brief arrived before the storefront was live; reserved, not yet emitted). Omit to return every outcome.' example: declined_fit type: string enum: - responded - declined_fit - declined_policy - not_live description: 'Demand-inbox filter — return only runs with this brief outcome: `responded` (the storefront composed a response), `declined_fit` (declined: no matching inventory), `declined_policy` (declined: acceptance-policy violation), or `not_live` (brief arrived before the storefront was live; reserved, not yet emitted). Omit to return every outcome.' - in: query name: q schema: description: Case-insensitive substring search over the buyer brief text. Use to find every brief mentioning a vertical, advertiser, or term (e.g. `fintech`). Combines with `disposition`. example: fintech type: string minLength: 1 maxLength: 200 description: Case-insensitive substring search over the buyer brief text. Use to find every brief mentioning a vertical, advertiser, or term (e.g. `fintech`). Combines with `disposition`. - in: query name: buyingMode schema: description: Filter by buying mode — `brief` for the demand inbox (excludes wholesale/refine runs), `wholesale`, or `refine`. Omit to return every mode. example: brief type: string enum: - brief - wholesale - refine description: Filter by buying mode — `brief` for the demand inbox (excludes wholesale/refine runs), `wholesale`, or `refine`. Omit to return every mode. - in: query name: commercialResult schema: description: 'Filter by the commercial result that followed the storefront response, derived from the latest attributed commercial-outcome event: `booked` (the media buy was forwarded upstream or has reported delivery — a confirmed commitment), `pending` (the media buy is awaiting the operator’s own acceptance-policy approval and could still be rejected), or `rejected` (the storefront rejected the media buy). Runs with no attributed media buy yet match no value. There is no `lost` value — a buyer silently passing on a response has no signal in AdCP today.' example: booked type: string enum: - booked - pending - rejected description: 'Filter by the commercial result that followed the storefront response, derived from the latest attributed commercial-outcome event: `booked` (the media buy was forwarded upstream or has reported delivery — a confirmed commitment), `pending` (the media buy is awaiting the operator’s own acceptance-policy approval and could still be rejected), or `rejected` (the storefront rejected the media buy). Runs with no attributed media buy yet match no value. There is no `lost` value — a buyer silently passing on a response has no signal in AdCP today.' - in: query name: view schema: description: '`full` (default) returns every run field. `summary` omits the heavy LLM payload columns (prompt, raw/inventory snapshots) the demand inbox does not render, keeping the response small. The full row is always available on `GET /intelligence-runs/:id`.' example: summary default: full type: string enum: - summary - full description: '`full` (default) returns every run field. `summary` omits the heavy LLM payload columns (prompt, raw/inventory snapshots) the demand inbox does not render, keeping the response small. The full row is always available on `GET /intelligence-runs/:id`.' responses: '200': description: List storefront intelligence-run records content: application/json: schema: $ref: '#/components/schemas/IntelligenceRunListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /intelligence-runs/{id}: get: operationId: getIntelligenceRun summary: Get a storefront intelligence-run record description: Fetch one intelligence-run record by id including the full prompt, raw and parsed LLM output, run rationale, composed product ids, and any evaluator label. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the intelligence-run row. example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the intelligence-run row. responses: '200': description: Get a storefront intelligence-run record content: application/json: schema: $ref: '#/components/schemas/IntelligenceRunResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /intelligence-runs/{id}/decision-record: get: operationId: getSellerDecisionRecord summary: Get the canonical seller decision record for an intelligence run description: Fetch the seller-readable chronology for one intelligence run, including the recorded buyer ask, fit decision, selling posture, response state, approval, commercial outcome, learning eligibility, and provenance. Historical facts that were not persisted are marked unavailable rather than inferred. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the intelligence-run row. example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the intelligence-run row. responses: '200': description: Get the canonical seller decision record for an intelligence run content: application/json: schema: $ref: '#/components/schemas/SellerDecisionRecord' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /intelligence-runs/{id}/label: put: operationId: labelIntelligenceRun summary: Attach an evaluator label to an intelligence-run description: 'Attach (or replace) an evaluator label on an intelligence-run record. The label body is freeform JSON the eval workflow defines (e.g. `{ "verdict": "good", "grader": "human", "notes": "..." }`).' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Surrogate id of the intelligence-run row. example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the intelligence-run row. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LabelIntelligenceRunBody' responses: '200': description: Attach an evaluator label to an intelligence-run content: application/json: schema: $ref: '#/components/schemas/IntelligenceRunResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox: get: operationId: getDemandInbox summary: Get the demand-inbox ledger description: 'The Proposal Studio front-of-house ledger for the calling storefront: a page of brief → proposal → feedback → result rows (each carrying the canonical brief and proposal artifact ids), plus a metrics strip computed only from persisted rows — briefs YTD, answered %, win rate, average grade, and the agent-vs-human split. A metric with no inputs is reported as null (unavailable), never 0. Page with `?skip=` and `?take=`.' tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: skip schema: default: 0 type: integer minimum: 0 maximum: 9007199254740991 - in: query name: take schema: default: 50 type: integer minimum: 1 maximum: 100 responses: '200': description: Get the demand-inbox ledger content: application/json: schema: $ref: '#/components/schemas/DemandInboxResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/ledger: put: operationId: recordDemandInboxResult summary: Record demand-inbox ledger annotations description: Record the seller's grade (A–F), buyer feedback, and led-by attribution (agent | human) on one demand-inbox row. Only the fields provided are changed; grade and feedback accept null to clear them. Scoped to the caller's storefront — a run outside it returns 404. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: description: Surrogate id of the chef compose run this ledger row wraps. example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the chef compose run this ledger row wraps. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RecordDemandInboxResultBody' responses: '200': description: Record demand-inbox ledger annotations content: application/json: schema: $ref: '#/components/schemas/DemandInboxRow' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No demand-inbox row with that id in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange: get: operationId: getDemandExchange summary: Get a demand exchange (proposal pass) description: 'The full story of one exchange for the calling storefront: condensed brief facts read from the persisted brief artifact, ordered passes with product allocation + pricing rows and expand-to-inspect snapshots from the persisted proposal artifacts, per-pass commercial outcome, and an exchange-level result (won if any pass won, else lost if the most recent decided pass lost, else pending). Grouped from persisted linkage only — one compose run and its proposal artifacts, never the content-addressed brief digest — so an exchange reads as a single composition pass until persisted cross-run lineage exists. A run with no captured artifact renders as unavailable, never reconstructed; a metric with no input is null, never 0. Scoped to the caller''s storefront — a run outside it returns 404.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: description: Surrogate id of the chef compose run that anchors this exchange (the demand-inbox ledger row id). example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the chef compose run that anchors this exchange (the demand-inbox ledger row id). responses: '200': description: Get a demand exchange (proposal pass) content: application/json: schema: $ref: '#/components/schemas/DemandExchange' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No demand-inbox exchange with that run id in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange/revisions: post: operationId: composeDemandExchangeRevision summary: Compose a demand exchange revision description: Declare posture, price, and product-count overrides in the merchandising simulator's own grammar and compose a silent draft revision on a live demand exchange through the real merchandising engine, against the storefront's current configuration. The draft holds no delivery state and issues no rate hold. Refused with a named reason (not_live_demand, brief_not_retained, no_operating_instructions, or adjustment_limit_reached) when the exchange is not adjustable — the same rule the exchange read states on every row. Scoped to the caller's storefront — a run outside it returns 404. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: description: Surrogate id of the chef compose run that anchors this exchange (the demand-inbox ledger row id). example: 42 type: integer maximum: 9007199254740991 minimum: 1 required: true description: Surrogate id of the chef compose run that anchors this exchange (the demand-inbox ledger row id). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ComposeDemandExchangeRevisionBody' responses: '200': description: Compose a demand exchange revision content: application/json: schema: $ref: '#/components/schemas/DemandExchangeRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No demand-inbox exchange with that run id in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The exchange is not currently adjustable; the response names the reason. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange/revisions/{revisionId}/submit: post: operationId: submitDemandExchangeRevision summary: Submit a demand exchange revision for approval description: Submit a draft revision for approval, or clear it immediately when the storefront's campaign-approval setting (or a per-buyer auto-approve override) covers it. expectedSubmissionGeneration must match the draft's current submissionGeneration (as read) — a stale generation (a concurrent amend landed first) is refused rather than submitting content the caller never saw. Resubmitting a previously-rejected draft clears its whole decision record — decider, decided-at, and notes — not just the notes. Scoped to the caller's storefront. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true - in: path name: revisionId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SubmitDemandExchangeRevisionBody' responses: '200': description: Submit a demand exchange revision for approval content: application/json: schema: $ref: '#/components/schemas/DemandExchangeRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Only the composer of this draft can submit it. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No matching revision in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The revision is not currently submittable, or was submitted against a stale submission generation. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange/revisions/{revisionId}/decision: put: operationId: decideDemandExchangeRevision summary: Approve or reject a demand exchange revision description: Approve or reject a revision awaiting approval. Approving requires a decider distinct from the revision's own composer (maker-checker, enforced here and by a table constraint); rejecting — including the composer withdrawing their own submission — has no such restriction, because it creates no buyer-visible evidence. An approved decision captures the revision as a real pass on the exchange's compose run in the same transaction. Scoped to the caller's storefront. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true - in: path name: revisionId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DecideDemandExchangeRevisionBody' responses: '200': description: Approve or reject a demand exchange revision content: application/json: schema: $ref: '#/components/schemas/DemandExchangeRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: The composer of this revision cannot approve their own submission. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No matching revision in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The revision is not currently awaiting approval. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange/revisions/{revisionId}/amend: post: operationId: amendDemandExchangeRevision summary: Amend a demand exchange revision description: Re-run the merchandising engine with newly declared overrides on an existing draft (including a rejected draft), in place — the SAME revision row, not a new one. Bumps the submission generation so any stale pending approval no longer applies, clears the decision record (decider, decided-at, notes), and counts against the exchange's lifetime adjustment limit. Refused with a named reason when the revision is not currently a draft. Scoped to the caller's storefront. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true - in: path name: revisionId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AmendDemandExchangeRevisionBody' responses: '200': description: Amend a demand exchange revision content: application/json: schema: $ref: '#/components/schemas/DemandExchangeRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Only the composer of this draft can amend it. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No matching revision in the calling storefront. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Only a draft revision can be amended. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /demand-inbox/{runId}/exchange/revisions/{revisionId}: delete: operationId: discardDemandExchangeRevision summary: Discard a demand exchange revision description: Discard a draft revision. Leaves nothing durable beyond the terminal audit row — a discarded revision still counts against the exchange’s lifetime adjustment limit. Only a draft (never submitted, or bounced back after rejection) can be discarded. Scoped to the caller’s storefront. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: runId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true - in: path name: revisionId schema: type: integer maximum: 9007199254740991 minimum: 1 required: true responses: '200': description: Discard a demand exchange revision content: application/json: schema: $ref: '#/components/schemas/DemandExchangeRevision' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Only the composer of this draft can discard it. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Only a draft revision can be discarded. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /brief-artifacts: get: operationId: listBriefArtifacts summary: List canonical brief artifacts description: Paginated list of brief artifacts — the exact validated AdCP get_products requests this storefront received, content-addressed by sha-256 digest and stored post-redaction. Summaries only; fetch one artifact for the request payload. Page with `?skip=` and `?take=`. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: skip schema: description: Number of rows to skip (offset pagination). example: 0 default: 0 type: integer minimum: 0 maximum: 9007199254740991 description: Number of rows to skip (offset pagination). - in: query name: take schema: description: Number of rows to return per page (1–100). example: 25 default: 25 type: integer minimum: 1 maximum: 100 description: Number of rows to return per page (1–100). responses: '200': description: List canonical brief artifacts content: application/json: schema: $ref: '#/components/schemas/BriefArtifactListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /brief-artifacts/{id}: get: operationId: getBriefArtifact summary: Get a canonical brief artifact description: Fetch one brief artifact including the exact validated inbound request payload and its redaction manifest. `complete=false` means the payload exceeded the size limit and only envelope metadata was retained. A missing artifact returns 404 — artifacts are never reconstructed. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Artifact id (UUID). example: 5f0c2a54-9c1b-4f0e-8a9d-3f4b2f4a1c11 type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true description: Artifact id (UUID). responses: '200': description: Get a canonical brief artifact content: application/json: schema: $ref: '#/components/schemas/GetBriefArtifactResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /proposal-artifacts: get: operationId: listProposalArtifacts summary: List canonical proposal artifacts description: Paginated list of proposal artifacts — the exact response envelopes this storefront returned, linked to the brief artifact and intelligence run that produced them. Filter with `?briefArtifactId=` to see every proposal version answering one brief. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: skip schema: description: Number of rows to skip (offset pagination). example: 0 default: 0 type: integer minimum: 0 maximum: 9007199254740991 description: Number of rows to skip (offset pagination). - in: query name: take schema: description: Number of rows to return per page (1–100). example: 25 default: 25 type: integer minimum: 1 maximum: 100 description: Number of rows to return per page (1–100). - in: query name: briefArtifactId schema: description: Return only proposals answering this brief artifact (one brief can have several proposal versions). example: 5f0c2a54-9c1b-4f0e-8a9d-3f4b2f4a1c11 type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ description: Return only proposals answering this brief artifact (one brief can have several proposal versions). responses: '200': description: List canonical proposal artifacts content: application/json: schema: $ref: '#/components/schemas/ProposalArtifactListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /proposal-artifacts/{id}: get: operationId: getProposalArtifact summary: Get a canonical proposal artifact description: Fetch one proposal artifact including the exact response envelope and the resolved immutable product snapshots for every referenced product. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: id schema: description: Artifact id (UUID). example: 5f0c2a54-9c1b-4f0e-8a9d-3f4b2f4a1c11 type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ required: true description: Artifact id (UUID). responses: '200': description: Get a canonical proposal artifact content: application/json: schema: $ref: '#/components/schemas/GetProposalArtifactResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /seller-analytics: get: operationId: getStorefrontSellerAnalytics summary: Get the seller-analytics posture-conversion rollup description: 'Conversion rolled up by the negotiation posture the agent used over recent intelligence runs: per-posture run count, booked count, win rate, and booked budget, plus a recommendation-adherence summary (how often the selected posture matched the history-derived recommendation and whether following it converted better). Read `?limit=` to set the window size (default 100). Runs where no composition ran are excluded from the denominators.' tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: limit schema: description: How many of the most recent intelligence runs to aggregate over. example: 100 default: 100 type: integer minimum: 1 maximum: 200 description: How many of the most recent intelligence runs to aggregate over. responses: '200': description: Get the seller-analytics posture-conversion rollup content: application/json: schema: $ref: '#/components/schemas/StorefrontSellerAnalyticsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /approval-routing: get: operationId: getStorefrontApprovalRouting summary: Get storefront approval routing description: Returns explicit primary and fallback audiences, delivery channels, SLA settings, and active role/user choices for media-buy and creative approval. Customer admins only. tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get storefront approval routing content: application/json: schema: type: object properties: policies: type: array items: type: object properties: id: type: string pattern: ^\d+$ storefrontId: type: string pattern: ^\d+$ kind: type: string enum: - MEDIA_BUY - CREATIVE_REVIEW - AD_SERVER_APPROVAL - INVENTORY_SHORTFALL primaryUserIds: type: array items: type: string pattern: ^\d+$ fallbackUserIds: type: array items: type: string pattern: ^\d+$ primaryRoleKeys: type: array items: type: string enum: - ADMIN - PREMIUM - BASIC fallbackRoleKeys: type: array items: type: string enum: - ADMIN - PREMIUM - BASIC primaryChannels: type: array items: type: string enum: - in_app - email - slack fallbackChannels: type: array items: type: string enum: - in_app - email - slack reminderAfterMinutes: type: integer minimum: -9007199254740991 maximum: 9007199254740991 escalateAfterMinutes: type: integer minimum: -9007199254740991 maximum: 9007199254740991 version: type: integer minimum: -9007199254740991 maximum: 9007199254740991 createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - kind - primaryUserIds - fallbackUserIds - primaryRoleKeys - fallbackRoleKeys - primaryChannels - fallbackChannels - reminderAfterMinutes - escalateAfterMinutes - version - createdAt - updatedAt additionalProperties: false eligibleUsers: type: array items: type: object properties: id: type: string pattern: ^\d+$ email: type: string format: email pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$ name: type: string permissionLevel: type: string enum: - ADMIN - PREMIUM - BASIC required: - id - email - name - permissionLevel additionalProperties: false eligibleRoles: type: array items: type: object properties: key: type: string enum: - ADMIN - PREMIUM - BASIC label: type: string activeUserCount: type: integer minimum: 0 maximum: 9007199254740991 required: - key - label - activeUserCount additionalProperties: false canManage: type: boolean required: - policies - eligibleUsers - eligibleRoles - canManage additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /approval-routing/{kind}: put: operationId: updateStorefrontApprovalRouting summary: Replace one storefront approval routing policy description: Configures explicit role or named-user primary and fallback audiences, delivery channels, and reminder/escalation timing. Customer admins only. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: kind schema: type: string enum: - MEDIA_BUY - CREATIVE_REVIEW - AD_SERVER_APPROVAL - INVENTORY_SHORTFALL required: true requestBody: required: true content: application/json: schema: type: object properties: primaryUserIds: default: [] maxItems: 25 type: array items: type: string pattern: ^\d+$ fallbackUserIds: default: [] maxItems: 25 type: array items: type: string pattern: ^\d+$ primaryRoleKeys: default: [] maxItems: 4 type: array items: type: string enum: - ADMIN - PREMIUM - BASIC fallbackRoleKeys: default: [] maxItems: 4 type: array items: type: string enum: - ADMIN - PREMIUM - BASIC primaryChannels: minItems: 1 maxItems: 3 type: array items: type: string enum: - in_app - email - slack fallbackChannels: minItems: 1 maxItems: 3 type: array items: type: string enum: - in_app - email - slack reminderAfterMinutes: type: integer minimum: 5 maximum: 43200 escalateAfterMinutes: type: integer minimum: 10 maximum: 86400 required: - primaryChannels - fallbackChannels - reminderAfterMinutes - escalateAfterMinutes responses: '200': description: Replace one storefront approval routing policy content: application/json: schema: type: object properties: id: type: string pattern: ^\d+$ storefrontId: type: string pattern: ^\d+$ kind: type: string enum: - MEDIA_BUY - CREATIVE_REVIEW - AD_SERVER_APPROVAL - INVENTORY_SHORTFALL primaryUserIds: type: array items: type: string pattern: ^\d+$ fallbackUserIds: type: array items: type: string pattern: ^\d+$ primaryRoleKeys: type: array items: type: string enum: - ADMIN - PREMIUM - BASIC fallbackRoleKeys: type: array items: type: string enum: - ADMIN - PREMIUM - BASIC primaryChannels: type: array items: type: string enum: - in_app - email - slack fallbackChannels: type: array items: type: string enum: - in_app - email - slack reminderAfterMinutes: type: integer minimum: -9007199254740991 maximum: 9007199254740991 escalateAfterMinutes: type: integer minimum: -9007199254740991 maximum: 9007199254740991 version: type: integer minimum: -9007199254740991 maximum: 9007199254740991 createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - kind - primaryUserIds - fallbackUserIds - primaryRoleKeys - fallbackRoleKeys - primaryChannels - fallbackChannels - reminderAfterMinutes - escalateAfterMinutes - version - createdAt - updatedAt additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /approval-routing/work-items/{workItemId}/assignee: put: operationId: reassignStorefrontApprovalWorkItem summary: Reassign an approval work item description: Moves open approval work to an active user in its snapshotted eligible audience without granting admins implicit approval permission. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: workItemId schema: type: string pattern: ^\d+$ required: true requestBody: required: true content: application/json: schema: type: object properties: userId: type: string pattern: ^\d+$ required: - userId responses: '200': description: Reassign an approval work item content: application/json: schema: type: object properties: workItemId: type: string pattern: ^\d+$ assignedTo: type: - string - 'null' pattern: ^\d+$ assignedToName: type: - string - 'null' assignmentStage: type: - string - 'null' enum: - PRIMARY - FALLBACK dueAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ escalatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ isMine: type: boolean eligibleAssigneeIds: type: array items: type: string pattern: ^\d+$ required: - workItemId - assignedTo - assignedToName - assignmentStage - dueAt - escalatedAt - isMine - eligibleAssigneeIds additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buy-approvals: get: operationId: listPendingMediaBuys summary: List media-buy approval entries description: List approval-queue entries for the storefront, newest first. Defaults to `status=pending`; pass `status=approved|rejected|revoked` to see decided history. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: status schema: description: Filter by lifecycle state. Defaults to `pending` so the operator queue does not have to thread the filter through manually. type: string enum: - pending - approved - rejected - revoked description: Filter by lifecycle state. Defaults to `pending` so the operator queue does not have to thread the filter through manually. responses: '200': description: List media-buy approval entries content: application/json: schema: $ref: '#/components/schemas/PendingMediaBuyListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buy-approvals/{mediaBuyId}: get: operationId: getPendingMediaBuy summary: Get a single media-buy approval entry description: Fetch one approval-queue entry by the buyer's `media_buy_id`. Returns the raw submitted payload alongside the current status and any operator decision. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: mediaBuyId schema: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). type: string minLength: 1 required: true description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). responses: '200': description: Get a single media-buy approval entry content: application/json: schema: $ref: '#/components/schemas/PendingMediaBuyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buy-approvals/{mediaBuyId}/decide: post: operationId: decidePendingMediaBuy summary: Approve or reject a pending media buy description: Record the operator decision for a pending media buy. Only valid on entries still in `pending` state — double-decide is rejected. Approved entries are forwarded upstream by the storefront's MCP layer. If the buyer's original `create_media_buy` request included AdCP `push_notification_config` (or camelCase `pushNotificationConfig`), approval completion or rejection is delivered back to the buyer as a signed ADCP task webhook. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: mediaBuyId schema: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). type: string minLength: 1 required: true description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MediaBuyDecisionBody' responses: '200': description: Approve or reject a pending media buy content: application/json: schema: $ref: '#/components/schemas/PendingMediaBuyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buy-approvals/{mediaBuyId}/evaluate: post: operationId: evaluatePendingMediaBuy summary: Evaluate a media buy against acceptance policy description: Classify whether a pending media buy is definitely on policy, definitely not on policy, or needs human approval. The evaluator only recommends automatic approval when the buy references quoted storefront products, contains advertiser evidence, and does not match active acceptance-policy review or block rules. This endpoint does not record a decision. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: mediaBuyId schema: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). type: string minLength: 1 required: true description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). responses: '200': description: Evaluate a media buy against acceptance policy content: application/json: schema: $ref: '#/components/schemas/MediaBuyApprovalEvaluationResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buy-approvals/{mediaBuyId}/retry-forward: post: operationId: retryForwardPendingMediaBuy summary: Retry forwarding an approved media buy description: 'Re-attempt the upstream forward for an already-approved media buy whose previous forward did not complete. Idempotent: the storefront reuses the same idempotency key, so a source that already received the buy is not double-booked. Returns the approval-queue entry with its refreshed forwarding state. A buy terminalized by a structural failure is recoverable in place with `forceTerminal: true`, which re-forwards it under the same `mediaBuyId` and keeps the original approval — the request is refused unless every persisted source route is a failed, unsent leg, so a forced retry cannot duplicate an upstream buy.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: mediaBuyId schema: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). type: string minLength: 1 required: true description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/RetryForwardMediaBuyBody' responses: '200': description: Retry forwarding an approved media buy content: application/json: schema: $ref: '#/components/schemas/RetryForwardMediaBuyResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buys: get: operationId: listStorefrontMediaBuys summary: List every media buy on the storefront description: 'The union of routed buys (approval queue + per-source forwarding routes) and ESA-managed buys, with status filters. Default sort is urgency: buys still waiting on someone whose flight starts within 48 hours come first. Each row carries the shared `pendingReason` vocabulary (the same enum buyers see), the latest structured error code, and the forward outcome.' tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: status schema: description: Filter to one seller lifecycle state. allOf: - $ref: '#/components/schemas/SellerMediaBuyStatus' description: Filter to one seller lifecycle state. - in: query name: buyerCustomerId schema: description: Filter to one buyer (customer id). type: integer maximum: 9007199254740991 minimum: 1 description: Filter to one buyer (customer id). - in: query name: sourceId schema: description: Filter to buys with a leg on this inventory source (routed buys) or managed by this ad server source. type: string minLength: 1 description: Filter to buys with a leg on this inventory source (routed buys) or managed by this ad server source. - in: query name: flightStartFrom schema: description: Only buys whose flight starts at/after this instant. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ description: Only buys whose flight starts at/after this instant. - in: query name: flightStartTo schema: description: Only buys whose flight starts at/before this instant. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ description: Only buys whose flight starts at/before this instant. - in: query name: take schema: description: Page size (max 200). default: 50 type: integer maximum: 200 minimum: 1 description: Page size (max 200). - in: query name: skip schema: description: Rows to skip (offset pagination over the sorted list). default: 0 type: integer minimum: 0 maximum: 9007199254740991 description: Rows to skip (offset pagination over the sorted list). responses: '200': description: List every media buy on the storefront content: application/json: schema: $ref: '#/components/schemas/StorefrontMediaBuyListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /media-buys/{mediaBuyId}/timeline: get: operationId: getStorefrontMediaBuyTimeline summary: Get one buy's exchange timeline description: 'The seller-scoped projection of the buy''s exchange record: stages (received → screened → decided → forwarded / forward-failed → submitted → source moderation → accepted / rejected → delivering) with evidence, per-source legs, and the references to quote per state — the source''s own ids as their reference, and the `sf:` idempotency key paired with the request timestamp as the platform reference. The forwarded payload is returned minus platform-internal fields (webhook/push-notification config and signing material); admin-only material never appears. `{"pruned": true}` payloads mean retention removed the bytes.' tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: mediaBuyId schema: description: Media buy id at the storefront grain (`sf_mb_…`). type: string minLength: 1 required: true description: Media buy id at the storefront grain (`sf_mb_…`). responses: '200': description: Get one buy's exchange timeline content: application/json: schema: $ref: '#/components/schemas/StorefrontMediaBuyTimelineResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: The buy does not exist on this storefront (unknown id, or a buy belonging to another storefront). content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /pending-operations: get: operationId: getStorefrontPendingOperations summary: List everything waiting on someone description: 'The union of pending media-buy approvals, pending creative reviews, failed forwards (grouped by structured error code, each carrying the recovery-class-gated action: retry, fix-and-resubmit, or escalate), and buys awaiting asynchronous source acceptance ("waiting on source moderation since T"). Groups appear only when non-empty.' tags: - Storefront security: - bearerAuth: [] responses: '200': description: List everything waiting on someone content: application/json: schema: $ref: '#/components/schemas/StorefrontPendingOperationsResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: No storefront exists for the calling operator. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /gam-cleanups/{operationId}: post: operationId: resolveGamFailedOrderCleanup summary: Resolve a safe failed GAM order cleanup description: After explicit seller confirmation, ask the Embedded Sales Agent to re-check and archive a verified safe failed GAM order. Alternatively, record that the seller cleaned up the order manually in GAM. Permission and authentication failures are returned as typed cleanup outcomes with the required permission and safe next action. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: operationId schema: type: string minLength: 1 required: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResolveGamCleanupBody' responses: '200': description: Resolve a safe failed GAM order cleanup content: application/json: schema: anyOf: - type: object properties: operationId: type: string minLength: 1 orderId: type: string minLength: 1 attempted: type: boolean outcome: type: string enum: - archived - already_archived - failed - refused safety: type: object properties: ownershipVerified: type: boolean draftVerified: type: boolean noSpendUncommittedVerified: type: boolean lineItemCount: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 orderStatus: type: - string - 'null' alreadyArchived: type: - boolean - 'null' safeToCleanup: type: boolean verificationCode: type: string minLength: 1 required: - ownershipVerified - draftVerified - noSpendUncommittedVerified - lineItemCount - orderStatus - alreadyArchived - safeToCleanup - verificationCode additionalProperties: false errorCategory: type: - string - 'null' errorCode: type: - string - 'null' requiredPermission: type: - string - 'null' retryDisposition: type: string enum: - not_applicable - retryable - user_action_required - manual_review_required safeNextAction: type: string enum: - none - retry_cleanup - grant_archive_orders_and_recheck - reauthenticate_and_recheck - clean_up_manually_in_gam - review_order_in_gam alternativeSafeNextAction: type: - string - 'null' enum: - none - retry_cleanup - grant_archive_orders_and_recheck - reauthenticate_and_recheck - clean_up_manually_in_gam - review_order_in_gam required: - operationId - orderId - attempted - outcome - safety - retryDisposition - safeNextAction additionalProperties: false - type: object properties: operationId: type: string minLength: 1 resolution: type: string enum: - manually_cleaned required: - operationId - resolution additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: The caller is not a storefront account admin or credential admin. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: The storefront or cleanup operation does not exist for the caller. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /test-runs: get: operationId: listStorefrontAgentTestRuns summary: List recent sandbox test runs description: The caller storefront's durable Murph sandbox test-run history (agent E2E diagnostics) — the same rows the Murph test-runs widget renders, exposed on the storefront surface so external MCP-UI hosts can hydrate it via `storefront_api_call`. Tenant scope (customer) is always derived from auth. The optional `storefrontId` query param narrows the listing to a single storefront for multi-storefront sellers. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: take schema: default: 5 type: integer maximum: 20 minimum: 1 - in: query name: storefrontId schema: type: integer maximum: 9007199254740991 minimum: 1 - in: query name: runUid schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ responses: '200': description: List recent sandbox test runs content: application/json: schema: type: object properties: runs: type: array items: type: object properties: id: type: string runUid: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ customerId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 userId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 conversationUid: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ toolName: type: string status: type: string enum: - planned - partial - passed - failed stage: type: - string - 'null' sandbox: type: boolean storefrontId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 advertiserId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 campaignId: type: - string - 'null' discoveryId: type: - string - 'null' executedCampaign: type: boolean discoveredProductCount: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 selectedProductCount: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 summary: type: object additionalProperties: {} artifacts: type: object additionalProperties: {} diagnostics: type: object additionalProperties: {} steps: type: array items: type: object properties: key: type: string label: type: string status: type: string enum: - completed - failed - not_checked operation: type: - string - 'null' httpStatus: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 endpoint: type: - string - 'null' message: type: - string - 'null' required: - key - label - status - operation - httpStatus - endpoint - message additionalProperties: false createdAt: type: string updatedAt: type: string required: - id - runUid - customerId - userId - conversationUid - toolName - status - stage - sandbox - storefrontId - advertiserId - campaignId - discoveryId - executedCampaign - discoveredProductCount - selectedProductCount - summary - artifacts - diagnostics - steps - createdAt - updatedAt additionalProperties: false required: - runs additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /test-campaigns/plan: post: operationId: planInventorySourceTestCampaign summary: Plan a sandbox inventory-source test campaign description: Inspect source readiness and product candidates without changing campaign state. When sourceId, sandbox readiness, advertiser, flight, and package selections are complete, the response includes a five-minute, identity-scoped, single-use planToken. Call this endpoint again after choosing a product if the first exploratory plan is incomplete. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: anyOf: - type: object properties: sandbox: type: boolean enum: - true forceRefresh: type: boolean sellerSandboxReady: type: boolean advertiserDomain: type: string pattern: ^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$ advertiserId: type: integer maximum: 9007199254740991 minimum: 1 campaignBrief: type: string minLength: 1 maxLength: 10000 creativeReady: description: Set true only when required creative is ready or the operator explicitly confirmed this is a no-creative test. type: boolean budget: type: number exclusiveMinimum: 0 currency: type: string pattern: ^[A-Za-z]{3}$ flightStart: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ - type: string format: date pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$ flightEnd: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ - type: string format: date pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$ packages: minItems: 1 type: array items: type: object properties: productId: type: string minLength: 1 budget: type: number exclusiveMinimum: 0 pricingOptionId: type: string minLength: 1 bidPrice: type: number pacing: type: string enum: - even - asap - front_loaded required: - productId - budget maxCandidates: type: integer minimum: 1 maximum: 10 sourceId: type: string minLength: 1 sourceName: type: string minLength: 1 required: - sandbox - sourceId - type: object properties: sandbox: type: boolean enum: - true forceRefresh: type: boolean sellerSandboxReady: type: boolean advertiserDomain: type: string pattern: ^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$ advertiserId: type: integer maximum: 9007199254740991 minimum: 1 campaignBrief: type: string minLength: 1 maxLength: 10000 creativeReady: description: Set true only when required creative is ready or the operator explicitly confirmed this is a no-creative test. type: boolean budget: type: number exclusiveMinimum: 0 currency: type: string pattern: ^[A-Za-z]{3}$ flightStart: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ - type: string format: date pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$ flightEnd: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ - type: string format: date pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$ packages: minItems: 1 type: array items: type: object properties: productId: type: string minLength: 1 budget: type: number exclusiveMinimum: 0 pricingOptionId: type: string minLength: 1 bidPrice: type: number pacing: type: string enum: - even - asap - front_loaded required: - productId - budget maxCandidates: type: integer minimum: 1 maximum: 10 sourceId: type: string minLength: 1 sourceName: type: string minLength: 1 required: - sandbox - sourceName responses: '200': description: Plan a sandbox inventory-source test campaign content: application/json: schema: type: object properties: confirmation: type: object properties: status: type: string enum: - ready - incomplete planToken: type: - string - 'null' expiresAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ missingInputs: type: array items: type: string required: - status - planToken - expiresAt - missingInputs additionalProperties: false required: - confirmation additionalProperties: {} '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /test-campaigns/execute: post: operationId: executeInventorySourceTestCampaign summary: Execute a confirmed sandbox inventory-source test campaign description: Atomically redeem the single-use planToken returned by the plan endpoint and execute its exact server-stored sandbox/no-spend payload through the real buyer campaign stack. The request cannot replace the source, advertiser, flight, budget, or products captured by the plan. Re-plan after an expired, consumed, or failed token. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: planToken: type: string pattern: ^sf_test_plan_.* required: - planToken responses: '200': description: Execute a confirmed sandbox inventory-source test campaign content: application/json: schema: type: object properties: ok: type: boolean sandbox: type: boolean testRun: type: object properties: runUid: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ status: type: string enum: - planned - partial - passed - failed createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - runUid - status - createdAt additionalProperties: false required: - ok - sandbox additionalProperties: {} '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: The plan token is unknown, expired, consumed, or issued for another account or identity. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /creative-reviews: get: operationId: listCreativeReviews summary: List creative review queue description: List buyer-submitted creatives awaiting (or having received) operator review. Defaults to `status=pending` — pass `?status=` to filter by lifecycle state. tags: - Storefront security: - bearerAuth: [] parameters: - in: query name: status schema: description: Filter the queue by review status. Omit to return only `pending` rows (the operator queue default). allOf: - $ref: '#/components/schemas/CreativeReviewStatus' description: Filter the queue by review status. Omit to return only `pending` rows (the operator queue default). responses: '200': description: List creative review queue content: application/json: schema: $ref: '#/components/schemas/CreativeReviewListResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /creative-reviews/{creativeId}: get: operationId: getCreativeReview summary: Get a creative review row description: Fetch a single creative review row by the AdCP creative id supplied at submit time. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: creativeId schema: description: AdCP creative id as supplied by the buyer. example: cr_abc123 type: string minLength: 1 required: true description: AdCP creative id as supplied by the buyer. responses: '200': description: Get a creative review row content: application/json: schema: $ref: '#/components/schemas/CreativeReviewResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /creative-reviews/{creativeId}/decide: post: operationId: decideCreativeReview summary: Record a decision on a pending creative review description: Approve or reject a pending creative review. Only pending → approved or pending → rejected transitions are allowed; revoking an approved creative is a separate gesture. If the buyer's original `sync_creatives` request included AdCP `push_notification_config` (or camelCase `pushNotificationConfig`), the storefront emits a signed ADCP task webhook whose per-creative status is `approved` or `rejected`. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: creativeId schema: description: AdCP creative id as supplied by the buyer. example: cr_abc123 type: string minLength: 1 required: true description: AdCP creative id as supplied by the buyer. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PostCreativeReviewDecisionBody' responses: '200': description: Record a decision on a pending creative review content: application/json: schema: $ref: '#/components/schemas/CreativeReviewResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /creative-reviews/{creativeId}/evaluate: post: operationId: evaluateCreativeReview summary: Evaluate a pending creative review description: Run an advisory AI evaluation against a buyer-submitted creative review row. The evaluator uses explicit storefront acceptance policy text, answers operator questions, and recommends approve, manual review, or reject. Generic storefront operating instructions are not used as policy input. This endpoint never records the decision. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: creativeId schema: description: AdCP creative id as supplied by the buyer. example: cr_abc123 type: string minLength: 1 required: true description: AdCP creative id as supplied by the buyer. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EvaluateCreativeReviewBody' responses: '200': description: Evaluate a pending creative review content: application/json: schema: $ref: '#/components/schemas/CreativeReviewEvaluationResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /publishers: get: operationId: listStorefrontPublishers summary: List publisher domains description: List all publisher domains associated with the storefront (declared, crawled, and discovered), with adagents.json resolution status and authorization verdict. tags: - Storefront security: - bearerAuth: [] responses: '200': description: List publisher domains content: application/json: schema: type: object properties: publishers: type: array items: type: object properties: domain: type: string provenance: type: string enum: - declared - crawled - discovered adagentsStatus: type: - string - 'null' enum: - resolved - no_adagents - invalid - error - pending authorizationStatus: type: - string - 'null' enum: - authorized - unauthorized - unknown authorizationReason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized propertyCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 lastSyncedAt: type: - string - 'null' required: - domain - provenance - adagentsStatus - authorizationStatus - authorizationReason - propertyCount - lastSyncedAt additionalProperties: false total: type: integer minimum: 0 maximum: 9007199254740991 verified: type: integer minimum: 0 maximum: 9007199254740991 required: - publishers - total - verified additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: operationId: replaceStorefrontPublishers summary: Replace publisher list description: Atomically replace the full set of declared publisher domains. Max 5,000 domains per call. Invalid domains fail the entire request. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: publishers: maxItems: 5000 type: array items: type: string minLength: 1 required: - publishers responses: '200': description: Replace publisher list content: application/json: schema: type: object properties: publishers: type: array items: type: object properties: domain: type: string provenance: type: string enum: - declared - crawled - discovered adagentsStatus: type: - string - 'null' enum: - resolved - no_adagents - invalid - error - pending authorizationStatus: type: - string - 'null' enum: - authorized - unauthorized - unknown authorizationReason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized propertyCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 lastSyncedAt: type: - string - 'null' required: - domain - provenance - adagentsStatus - authorizationStatus - authorizationReason - propertyCount - lastSyncedAt additionalProperties: false total: type: integer minimum: 0 maximum: 9007199254740991 verified: type: integer minimum: 0 maximum: 9007199254740991 required: - publishers - total - verified additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: addStorefrontPublisher summary: Add a publisher domain description: Declare one publisher domain. Accepts bare domains (`bbc.com`) or full URLs (`https://www.bbc.com/news`) and normalizes them automatically. tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: domain: type: string minLength: 1 required: - domain responses: '201': description: Add a publisher domain content: application/json: schema: type: object properties: publishers: type: array items: type: object properties: domain: type: string provenance: type: string enum: - declared - crawled - discovered adagentsStatus: type: - string - 'null' enum: - resolved - no_adagents - invalid - error - pending authorizationStatus: type: - string - 'null' enum: - authorized - unauthorized - unknown authorizationReason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized propertyCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 lastSyncedAt: type: - string - 'null' required: - domain - provenance - adagentsStatus - authorizationStatus - authorizationReason - propertyCount - lastSyncedAt additionalProperties: false total: type: integer minimum: 0 maximum: 9007199254740991 verified: type: integer minimum: 0 maximum: 9007199254740991 required: - publishers - total - verified additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /property-roster: get: operationId: getStorefrontPropertyRoster summary: Get the property roster description: 'The canonical property roster: every declared publisher domain with the properties and collections resolved from that publisher''s adagents.json, plus the persisted authorization outcome (authorizationStatus and, when resolved under the reason contract, authorizationReason).' tags: - Storefront security: - bearerAuth: [] responses: '200': description: Get the property roster content: application/json: schema: $ref: '#/components/schemas/PropertyRosterResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /property-roster/properties: post: operationId: declareRosterProperty summary: Declare a property description: 'Record a seller-declared property under an already-declared publisher domain. At least one of propertyId, an identifier, or name is required. A publisher-origin adagents.json declaration with the same property key supersedes the seller-declared record (outcome: already_resolved).' tags: - Storefront security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: domain: description: A publisher domain already declared on this storefront. type: string minLength: 1 property: description: The declared property. At least one of propertyId, an identifier, or name is required — the roster never invents identity. type: object properties: propertyId: type: string minLength: 1 maxLength: 512 propertyType: type: string enum: - website - mobile_app - ctv_app - desktop_app - dooh - podcast - radio - streaming_audio name: type: string minLength: 1 maxLength: 512 identifiers: maxItems: 50 type: array items: type: object properties: type: type: string value: type: string required: - type - value tags: maxItems: 50 type: array items: type: string minLength: 1 maxLength: 512 required: - domain - property responses: '201': description: Declare a property content: application/json: schema: type: object properties: outcome: description: 'declared: recorded as seller-declared identity. already_resolved: a publisher-origin record already covers this property — it wins, and the seller''s claim is recorded on it so the declaration survives if that source later retracts the property.' type: string enum: - declared - already_resolved propertyKey: type: string required: - outcome - propertyKey additionalProperties: false '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /property-roster/properties/{domain}/{propertyKey}: delete: operationId: removeDeclaredRosterProperty summary: Remove a declared property description: Remove one seller-declared property from the roster. Publisher-origin properties cannot be removed here (409) — they disappear when the publisher's adagents.json stops declaring them. tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: domain schema: type: string minLength: 1 required: true - in: path name: propertyKey schema: type: string minLength: 1 required: true responses: '204': description: No content '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: The property is publisher-origin (declared in adagents.json) and cannot be removed through the roster. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /publishers/{domain}: delete: operationId: removeStorefrontPublisher summary: Remove a publisher domain description: Remove one declared publisher domain. Returns 204 (idempotent). Returns 409 if the domain was not seller-declared (e.g. crawled or discovered). tags: - Storefront security: - bearerAuth: [] parameters: - in: path name: domain schema: type: string minLength: 1 required: true responses: '204': description: No content '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Domain is not seller-declared (e.g. crawled or discovered). Only declared domains can be removed via this endpoint. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' components: schemas: UpdateInventorySourceWorkItemBody: description: Updates assignment, status, notes, or intermediate result metadata for a modular inventory source work item. Use the complete endpoint for completion. type: object properties: status: type: string enum: - OPEN - IN_PROGRESS - BLOCKED assignedTo: anyOf: - type: string minLength: 1 - type: integer minimum: -9007199254740991 maximum: 9007199254740991 blockedReason: type: - string - 'null' result: type: object additionalProperties: {} notes: type: string DemandInboxRow: type: object properties: id: type: string brief: description: The brief text the agent answered (label for the row). type: - string - 'null' buyer: description: Buyer label derived from the buyer scope (operator or brand domain). type: - string - 'null' budgetRange: description: The buyer's stated budget range, exactly as sent in the brief's filters.budget_range and captured in the brief artifact. Null when the buyer did not state one. type: - object - 'null' properties: min: type: - number - 'null' max: type: - number - 'null' currency: type: string required: - min - max - currency additionalProperties: false receivedAt: type: string respondedAt: description: When the agent answered. Null while the brief is unanswered. type: - string - 'null' ledBy: type: - string - 'null' enum: - agent - human feedback: type: - string - 'null' result: description: 'Commercial result derived from this run’s own attributed outcome: closed_won (booked/delivered), closed_lost (rejected), else pending. A booking attributed to a later refine pass is not rolled up here (see the win-rate scope note).' type: string enum: - closed_won - closed_lost - pending grade: type: - string - 'null' enum: - A - B - C - D - F wonValue: description: 'Money attributed to this run''s won outcome: delivered spend when reporting exists, else the booked media-buy budget. Null unless the outcome persisted both an amount and its currency.' type: - object - 'null' properties: amount: type: number currency: type: string required: - amount - currency additionalProperties: false provenance: description: 'How this brief reached the ledger: ''live'' = an AdCP get_products call from a buyer agent, ''uploaded'' = a seller-uploaded RFP/brief confirmed in chat (AI-4728). Reflects this run''s own intake origin (AI-5025), falling back to the linked brief artifact''s source column only for historical runs recorded before that origin was captured. Null when neither is available (e.g. a practice pitch or a historical pre-capture run). Uploaded briefs never masquerade as live buyer demand.' type: - string - 'null' briefArtifactId: description: Canonical brief artifact id (AI-4693) for the build-3 drill-in. Null = artifact unavailable (historical pre-capture run). type: - string - 'null' proposalArtifactId: description: Canonical proposal artifact id for the build-3 drill-in. Null = no proposal artifact captured. type: - string - 'null' artifactAvailable: description: False when the brief artifact was not captured; readers must say "artifact unavailable" rather than reconstruct it. type: boolean required: - id - brief - buyer - budgetRange - receivedAt - respondedAt - ledBy - feedback - result - grade - wonValue - provenance - briefArtifactId - proposalArtifactId - artifactAvailable additionalProperties: false EvaluateCreativeReviewBody: description: Request body for advisory AI evaluation of a pending storefront creative review. type: object properties: acceptance_policy_text: description: Optional storefront acceptance policy text for evaluating whether a buyer-submitted creative can be approved. This may include advertiser/category rules, creative asset rules, and manual-review workflow requirements. type: string minLength: 1 maxLength: 50000 expected_brand: description: Optional brand the creative is expected to represent. If omitted, the evaluator tries to infer brand evidence from the submitted creative payload. type: string minLength: 1 maxLength: 200 questions: description: Optional specific questions for the evaluator to answer about the creative. maxItems: 8 type: array items: type: string minLength: 1 maxLength: 300 CreateOperatingInstructionsBody: description: Request body for creating a new operating-instructions version and optionally activating it atomically. type: object properties: content: description: Markdown body the merchandising agent will use for product packaging, naming, selection, and explanation. Structured prices/floors/currencies belong in Playbook pricing; brand/operator discounts belong in Buyer Discounts and Buyer Instructions; buyer-visible channels and accepted countries belong in the Discovery Card; Product Marketing Media Kits are source material only; advertiser/category/creative eligibility belongs in Business Rules. type: string minLength: 1 maxLength: 50000 notes: description: Operator note describing why this version was created (e.g. "tighten brand-safety rules"). Not surfaced to buyers; visible in the version history UI. type: string maxLength: 2000 activate: description: When true, create and activate this immutable version atomically. Defaults to false. default: false type: boolean doctrine: description: 'The selling doctrine this version carries (AI-5870): the qualification strategy the merchandising agent applies BEFORE it composes anything — when to pitch in full, when to counter-pitch with a reframe, and when to pass with a branded decline. Supply exactly one of `variant` or `thresholds`; supplying both is rejected. Omit the whole object to carry no doctrine, which composes under the platform default (every brief the catalogue can serve gets a full pitch). Doctrine is versioned and activated exactly like the prose above, because it IS these instructions grown: reverting is activating the prior version.' allOf: - $ref: '#/components/schemas/SellingDoctrineBody' required: - content SaveModularSourceModuleCredentialBody: description: Create or rotate a storefront-scoped credential for one private inventory-source module. type: object properties: auth: description: Provider credential material. Stored only in the configured secret manager and never returned. type: object additionalProperties: {} scopes: default: [] type: array items: type: string minLength: 1 expiresAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastRefreshedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ metadata: default: {} type: object additionalProperties: {} required: - auth IntelligenceRunProductExplanation: description: Buyer-safe explanation of one product selected for the storefront response. type: object properties: productId: type: - string - 'null' name: type: - string - 'null' description: type: - string - 'null' reasoning: type: - string - 'null' pricing: allOf: - $ref: '#/components/schemas/IntelligenceRunProductPricingExplanation' bundleIds: type: array items: type: string signalIds: type: array items: type: string formatIds: type: array items: $ref: '#/components/schemas/IntelligenceRunProductFormatExplanation' required: - productId - name - description - reasoning - pricing - bundleIds - signalIds - formatIds additionalProperties: false InventorySourceDiscoveryTestBody: description: Input for a read-only, no-spend get_products diagnostic against one external sales-agent source. type: object properties: brief: description: Optional bounded buyer brief sent directly to this source with get_products. A deterministic diagnostic brief is used when omitted. type: string minLength: 1 maxLength: 2000 additionalProperties: false FeedContractId: description: Feed contract identifier. `static-avails-feed:v1` for static avails CSV/JSON; `wholesale-avails-pricing:v1` for wholesale pricing grids. type: string enum: - static-avails-feed:v1 - wholesale-avails-pricing:v1 DemandExchangeRevisionComposeError: type: object properties: code: type: string message: type: string required: - code - message additionalProperties: false RecordDemandInboxResultBody: description: Records the seller-authored ledger annotations (grade, buyer feedback, led-by attribution) on one demand-inbox row. type: object properties: grade: description: Seller's letter grade (A–F) for the proposal. Null clears it. type: - string - 'null' enum: - A - B - C - D - F feedback: description: Buyer feedback captured against the proposal. Null clears it. type: - string - 'null' maxLength: 2000 ledBy: description: 'Who led the response: the agent, or a human who took it over. Omit to leave the run''s current attribution.' type: string enum: - agent - human StorefrontPendingOperationsResponse: description: 'The union of things waiting on someone: pending approvals, pending creative reviews, failed forwards (grouped by error code), async-pending source acceptance, and seller-owned source degradations. Groups appear only when non-empty.' type: object properties: approvals: description: Media buys waiting on operator approval. type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: $ref: '#/components/schemas/PendingOperationsApprovalItem' required: - count - items additionalProperties: false creativeReviews: description: Creatives waiting on operator review. type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: $ref: '#/components/schemas/PendingOperationsCreativeReviewItem' required: - count - items additionalProperties: false failedForwards: description: Forwards that failed, grouped by structured error code with the recovery-class-gated action. type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 groups: type: array items: $ref: '#/components/schemas/PendingOperationsFailedForwardGroup' required: - count - groups additionalProperties: false awaitingSource: description: Buys a source accepted asynchronously and is still moderating ("waiting on source moderation since T"). type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: $ref: '#/components/schemas/PendingOperationsAwaitingSourceItem' required: - count - items additionalProperties: false sourceDegradations: description: Seller-owned source-health diagnoses (a degraded ad-server or sales-agent source) surfaced here so they are visible without opening the source directly. Scope3/vendor-owned diagnoses never appear. type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: $ref: '#/components/schemas/PendingOperationsSourceDegradationItem' required: - count - items additionalProperties: false gamCleanups: description: Unresolved safe GAM failed-order cleanup operations. Archive is offered only after verified upstream safety and explicit confirmation. type: object properties: count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: type: object properties: operationId: type: string orderId: type: string sourceId: type: string sourceName: type: - string - 'null' outcome: type: string enum: - failed - refused safeToCleanup: type: boolean requiredPermission: type: - string - 'null' retryDisposition: type: string enum: - not_applicable - retryable - user_action_required - manual_review_required safeNextAction: type: string enum: - none - retry_cleanup - grant_archive_orders_and_recheck - reauthenticate_and_recheck - clean_up_manually_in_gam - review_order_in_gam createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - operationId - orderId - sourceId - sourceName - outcome - safeToCleanup - requiredPermission - retryDisposition - safeNextAction - createdAt additionalProperties: false required: - count - items additionalProperties: false additionalProperties: false InventorySourceRuntimeProjection: description: Operator-facing setup-state projection for a modular inventory source. type: object properties: inventorySource: type: object properties: id: type: string storefrontId: type: string sourceId: type: string name: type: string executionType: type: string enum: - MODULAR_SOURCE status: type: string healthStatus: type: string lastError: type: - string - 'null' lastCheckedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - sourceId - name - executionType - status - healthStatus - lastError - lastCheckedAt additionalProperties: false modules: type: array items: $ref: '#/components/schemas/InventorySourceModuleRuntimeProjection' lifecycleSummary: type: array items: $ref: '#/components/schemas/InventorySourceLifecycleStageSummary' openWorkItemCount: type: integer minimum: 0 maximum: 9007199254740991 activeAvailCount: type: integer minimum: 0 maximum: 9007199254740991 catalogMappingReadiness: allOf: - $ref: '#/components/schemas/CatalogMappingReadiness' required: - inventorySource - modules - lifecycleSummary - openWorkItemCount - activeAvailCount additionalProperties: false ApiError: description: Structured error object type: object properties: code: description: Machine-readable error code type: string message: description: Human-readable error message type: string field: description: Field path associated with the error type: string details: description: Additional error context type: object additionalProperties: {} required: - code - message additionalProperties: false PendingOperationsSourceDegradationItem: description: One seller-owned source-health diagnosis (docs/spec/storefront/source-diagnosis-projection.md) — a projection of the same diagnoses array the readiness checklist and the ad-server widget already render. type: object properties: sourceId: type: - string - 'null' sourceName: type: string severity: type: string enum: - blocking - attention - advisory headline: description: 'Customer-safe, one sentence: what is wrong and why it matters to the seller.' type: string required: - sourceId - sourceName - severity - headline additionalProperties: false SellerMediaBuyStatus: description: Coarse seller-facing lifecycle of a buy on the storefront, derived from persisted approval + forwarding state. A platform list-view convenience — not an AdCP MediaBuyStatus. Use the per-buy timeline for the exact underlying states. type: string enum: - pending_approval - forwarding - forward_failed - awaiting_source - rejected - canceled - booked - delivering - paused - completed StorefrontPricingFactHints: description: Optional best-effort hints for matching a seller pricing fact. These are not product assembly rules; the Merchandising Agent still reasons over the natural-language appliesWhen field. type: object properties: channels: description: AdCP channel codes (e.g. `olv`, `ctv`, `dooh`) this fact applies to. Unlike the free-text hint categories, channels are matched as EXACT codes against the product's seller-declared `channels` plus the broad channel family inferred from its creative format kind — never as substrings of names, ids, or tags. So a fact scoped to `["ctv"]` applies only to products that declare `ctv`; a `video_hosted` format on its own resolves to the broad `video` family, which cannot distinguish `olv` from `ctv`. Within the array any code may match (OR); across hint categories every populated category must match (AND). maxItems: 32 type: array items: type: string minLength: 1 maxLength: 80 creativeTerms: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 publisherDomains: maxItems: 128 type: array items: type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ countries: maxItems: 64 type: array items: type: string pattern: ^[A-Z0-9_-]{2,32}$ advertiserVerticals: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 seasonality: maxItems: 32 type: array items: type: string minLength: 1 maxLength: 120 signalTags: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 placementTags: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 StorefrontSellerAnalyticsResponse: description: 'Seller-facing analytics rollup over a window of recent intelligence runs: summary KPIs, commercial outcomes, posture conversion with recommendation-adherence, recommendations, and recent runs.' type: object properties: generatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ storefront: type: - object - 'null' properties: id: type: string name: type: string state: type: string enum: - neutral - paused - archived required: - id - name - state additionalProperties: false window: type: object properties: requestedRunLimit: type: integer maximum: 9007199254740991 minimum: 1 runCount: type: integer minimum: 0 maximum: 9007199254740991 eligibleRunCount: type: integer minimum: 0 maximum: 9007199254740991 legacyRunCount: type: integer minimum: 0 maximum: 9007199254740991 firstRunAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastRunAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - requestedRunLimit - runCount - eligibleRunCount - legacyRunCount - firstRunAt - lastRunAt additionalProperties: false summary: type: object properties: totalRuns: type: integer minimum: 0 maximum: 9007199254740991 okRuns: type: integer minimum: 0 maximum: 9007199254740991 skippedRuns: type: integer minimum: 0 maximum: 9007199254740991 errorRuns: type: integer minimum: 0 maximum: 9007199254740991 briefRuns: type: integer minimum: 0 maximum: 9007199254740991 refineRuns: type: integer minimum: 0 maximum: 9007199254740991 wholesaleRuns: type: integer minimum: 0 maximum: 9007199254740991 totalShownProducts: type: integer minimum: 0 maximum: 9007199254740991 averageShownProducts: type: number minimum: 0 priceObjectionCount: type: integer minimum: 0 maximum: 9007199254740991 packagingAskCount: type: integer minimum: 0 maximum: 9007199254740991 requestAskCount: type: integer minimum: 0 maximum: 9007199254740991 productAskCount: type: integer minimum: 0 maximum: 9007199254740991 proposalAskCount: type: integer minimum: 0 maximum: 9007199254740991 appliedRefinements: type: integer minimum: 0 maximum: 9007199254740991 partialRefinements: type: integer minimum: 0 maximum: 9007199254740991 unableRefinements: type: integer minimum: 0 maximum: 9007199254740991 required: - totalRuns - okRuns - skippedRuns - errorRuns - briefRuns - refineRuns - wholesaleRuns - totalShownProducts - averageShownProducts - priceObjectionCount - packagingAskCount - requestAskCount - productAskCount - proposalAskCount - appliedRefinements - partialRefinements - unableRefinements additionalProperties: false outcomes: type: object properties: attributedRunCount: type: integer minimum: 0 maximum: 9007199254740991 eventCount: type: integer minimum: 0 maximum: 9007199254740991 submittedCount: type: integer minimum: 0 maximum: 9007199254740991 forwardedCount: type: integer minimum: 0 maximum: 9007199254740991 forwardFailedCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedCount: type: integer minimum: 0 maximum: 9007199254740991 deliveryReportedCount: type: integer minimum: 0 maximum: 9007199254740991 bookedMediaBuyCount: type: integer minimum: 0 maximum: 9007199254740991 bookedBudget: type: number minimum: 0 deliveredImpressions: type: integer minimum: 0 maximum: 9007199254740991 deliveredSpend: type: number minimum: 0 deliveredCurrency: type: - string - 'null' required: - attributedRunCount - eventCount - submittedCount - forwardedCount - forwardFailedCount - rejectedCount - deliveryReportedCount - bookedMediaBuyCount - bookedBudget - deliveredImpressions - deliveredSpend - deliveredCurrency additionalProperties: false historicalPerformance: type: object properties: runCount: type: integer minimum: 0 maximum: 9007199254740991 bookedRunCount: type: integer minimum: 0 maximum: 9007199254740991 winRate: type: - number - 'null' minimum: 0 askRunCount: type: integer minimum: 0 maximum: 9007199254740991 askToBookConversionRate: type: - number - 'null' minimum: 0 priceObjectionConversionRate: type: - number - 'null' minimum: 0 packagingAskConversionRate: type: - number - 'null' minimum: 0 averageBookedBudget: type: - number - 'null' minimum: 0 averageProductsPerRun: type: number minimum: 0 averageProductsPerBookedRun: type: - number - 'null' minimum: 0 averageProductsPerUnbookedRun: type: - number - 'null' minimum: 0 deliveryRate: type: - number - 'null' minimum: 0 repeatBuyerCount: type: integer minimum: 0 maximum: 9007199254740991 recommendedPosture: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - runCount - bookedRunCount - winRate - askRunCount - askToBookConversionRate - priceObjectionConversionRate - packagingAskConversionRate - averageBookedBudget - averageProductsPerRun - averageProductsPerBookedRun - averageProductsPerUnbookedRun - deliveryRate - repeatBuyerCount - recommendedPosture additionalProperties: false seasonality: type: array items: type: object properties: period: type: string runCount: type: integer minimum: 0 maximum: 9007199254740991 bookedRunCount: type: integer minimum: 0 maximum: 9007199254740991 winRate: type: number minimum: 0 askRunCount: type: integer minimum: 0 maximum: 9007199254740991 askToBookConversionRate: type: - number - 'null' minimum: 0 priceObjectionCount: type: integer minimum: 0 maximum: 9007199254740991 packagingAskCount: type: integer minimum: 0 maximum: 9007199254740991 bookedBudget: type: number minimum: 0 averageBookedBudget: type: - number - 'null' minimum: 0 averageShownProducts: type: number minimum: 0 recommendedPosture: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - period - runCount - bookedRunCount - winRate - askRunCount - askToBookConversionRate - priceObjectionCount - packagingAskCount - bookedBudget - averageBookedBudget - averageShownProducts - recommendedPosture additionalProperties: false buyers: type: array items: type: object properties: operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' country: type: - string - 'null' firstRunAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastRunAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ runCount: type: integer minimum: 0 maximum: 9007199254740991 bookedRunCount: type: integer minimum: 0 maximum: 9007199254740991 winRate: type: number minimum: 0 askRunCount: type: integer minimum: 0 maximum: 9007199254740991 askToBookConversionRate: type: - number - 'null' minimum: 0 attributedRunCount: type: integer minimum: 0 maximum: 9007199254740991 eventCount: type: integer minimum: 0 maximum: 9007199254740991 totalShownProducts: type: integer minimum: 0 maximum: 9007199254740991 averageShownProducts: type: number minimum: 0 priceObjectionCount: type: integer minimum: 0 maximum: 9007199254740991 packagingAskCount: type: integer minimum: 0 maximum: 9007199254740991 requestAskCount: type: integer minimum: 0 maximum: 9007199254740991 productAskCount: type: integer minimum: 0 maximum: 9007199254740991 proposalAskCount: type: integer minimum: 0 maximum: 9007199254740991 bookedMediaBuyCount: type: integer minimum: 0 maximum: 9007199254740991 bookedBudget: type: number minimum: 0 averageBookedBudget: type: - number - 'null' minimum: 0 deliveredImpressions: type: integer minimum: 0 maximum: 9007199254740991 deliveredSpend: type: number minimum: 0 deliveredCurrency: type: - string - 'null' recommendedPosture: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - operatorDomain - brandDomain - country - firstRunAt - lastRunAt - runCount - bookedRunCount - winRate - askRunCount - askToBookConversionRate - attributedRunCount - eventCount - totalShownProducts - averageShownProducts - priceObjectionCount - packagingAskCount - requestAskCount - productAskCount - proposalAskCount - bookedMediaBuyCount - bookedBudget - averageBookedBudget - deliveredImpressions - deliveredSpend - deliveredCurrency - recommendedPosture additionalProperties: false postureConversion: type: object properties: byPosture: type: array items: type: object properties: posture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror runCount: type: integer maximum: 9007199254740991 minimum: 1 bookedRunCount: type: integer minimum: 0 maximum: 9007199254740991 winRate: type: number minimum: 0 bookedBudget: type: number minimum: 0 required: - posture - runCount - bookedRunCount - winRate - bookedBudget additionalProperties: false adherence: type: object properties: comparableRunCount: type: integer minimum: 0 maximum: 9007199254740991 followedCount: type: integer minimum: 0 maximum: 9007199254740991 followedWinRate: type: - number - 'null' minimum: 0 divergedWinRate: type: - number - 'null' minimum: 0 required: - comparableRunCount - followedCount - followedWinRate - divergedWinRate additionalProperties: false required: - byPosture - adherence additionalProperties: false learnedDefault: type: - object - 'null' properties: posture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror reason: type: - string - 'null' checkedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - posture - reason - checkedAt additionalProperties: false strategySignals: type: array items: type: object properties: id: type: string priority: type: string enum: - high - medium - low label: type: string detail: type: string posture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror evidence: type: array items: type: object properties: label: type: string value: type: string required: - label - value additionalProperties: false required: - id - priority - label - detail - posture - evidence additionalProperties: false sellerRecommendations: type: array items: type: object properties: id: type: string priority: type: string enum: - high - medium - low kind: type: string enum: - protect_expand - prioritize_follow_up - packaging_friction - price_resistance - tighten_selection - learned_auto_approve title: type: string detail: type: string action: type: string buyer: type: - object - 'null' properties: operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' country: type: - string - 'null' required: - operatorDomain - brandDomain - country additionalProperties: false evidence: type: array items: type: object properties: label: type: string value: type: string required: - label - value additionalProperties: false required: - id - priority - kind - title - detail - action - buyer - evidence additionalProperties: false runs: type: array items: type: object properties: id: type: string purpose: allOf: - $ref: '#/components/schemas/IntelligenceRunPurpose' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ buyingMode: type: string resultKind: type: string enum: - ok - error - skipped resultCode: type: - string - 'null' selectedPosture: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror recommendedPosture: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror postureRationale: type: - string - 'null' postureEvidence: type: array items: type: string attributionState: type: string enum: - attributed - unattributed - unavailable buyer: type: object properties: operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' country: type: - string - 'null' required: - operatorDomain - brandDomain - country additionalProperties: false shownProductCount: type: integer minimum: 0 maximum: 9007199254740991 minSellPrice: type: - number - 'null' maxSellPrice: type: - number - 'null' requestAskCount: type: integer minimum: 0 maximum: 9007199254740991 productAskCount: type: integer minimum: 0 maximum: 9007199254740991 proposalAskCount: type: integer minimum: 0 maximum: 9007199254740991 hadPriceObjection: type: boolean hadPackagingAsk: type: boolean refinementStatusCounts: type: object properties: applied: type: integer minimum: 0 maximum: 9007199254740991 partial: type: integer minimum: 0 maximum: 9007199254740991 unable: type: integer minimum: 0 maximum: 9007199254740991 required: - applied - partial - unable additionalProperties: false outcome: type: object properties: eventCount: type: integer minimum: 0 maximum: 9007199254740991 latestType: type: - string - 'null' latestStatus: type: - string - 'null' mediaBuyId: type: - string - 'null' submittedCount: type: integer minimum: 0 maximum: 9007199254740991 forwardedCount: type: integer minimum: 0 maximum: 9007199254740991 forwardFailedCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedCount: type: integer minimum: 0 maximum: 9007199254740991 deliveryReportedCount: type: integer minimum: 0 maximum: 9007199254740991 bookedMediaBuyCount: type: integer minimum: 0 maximum: 9007199254740991 bookedBudget: type: - number - 'null' minimum: 0 deliveredImpressions: type: integer minimum: 0 maximum: 9007199254740991 deliveredSpend: type: number minimum: 0 deliveredCurrency: type: - string - 'null' required: - eventCount - latestType - latestStatus - mediaBuyId - submittedCount - forwardedCount - forwardFailedCount - rejectedCount - deliveryReportedCount - bookedMediaBuyCount - bookedBudget - deliveredImpressions - deliveredSpend - deliveredCurrency additionalProperties: false required: - id - purpose - createdAt - buyingMode - resultKind - resultCode - selectedPosture - recommendedPosture - postureRationale - postureEvidence - attributionState - buyer - shownProductCount - minSellPrice - maxSellPrice - requestAskCount - productAskCount - proposalAskCount - hadPriceObjection - hadPackagingAsk - refinementStatusCounts - outcome additionalProperties: false topProducts: type: array items: type: object properties: productId: type: string name: type: - string - 'null' impressions: type: integer minimum: 0 maximum: 9007199254740991 required: - productId - name - impressions additionalProperties: false notes: type: array items: type: string required: - generatedAt - storefront - window - summary - outcomes - historicalPerformance - seasonality - buyers - postureConversion - learnedDefault - strategySignals - sellerRecommendations - runs - topProducts - notes additionalProperties: false FeedPushBody: description: Request body for POST /inventory-sources/:sourceId/feed/push (API_PUSH one-shot ingest). type: object properties: contractId: $ref: '#/components/schemas/FeedContractId' rawRows: minItems: 1 type: array items: type: object additionalProperties: {} csvText: type: string minLength: 1 maxLength: 2000000 jsonText: type: string minLength: 1 maxLength: 2000000 idempotencyKey: description: Deterministic replay idempotency key (UUID). Provide only together with revisionId and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: description: Deterministic replay revision id (UUID). Provide only together with idempotencyKey and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ observedAt: description: ISO-8601 observation timestamp for deterministic replay. Provide only together with idempotencyKey and revisionId; omit all three fields to default to the current time. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ dryRun: description: 'When true, the revision is built and validated but not committed. The response carries `dryRun: true` and the validated revision envelope.' type: boolean required: - contractId DemandInboxResponse: description: 'The demand-inbox ledger: a persisted-only metrics strip, a page of brief → proposal → feedback → result rows, and the total brief count for page-cap disclosure.' type: object properties: metrics: $ref: '#/components/schemas/DemandInboxMetrics' rows: type: array items: $ref: '#/components/schemas/DemandInboxRow' total: description: Total number of brief rows for the storefront. When it exceeds the returned page, the client discloses the cap ("showing the N most recent of total"). type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - metrics - rows - total additionalProperties: false SellerTimelineEvidence: description: One observed fact supporting a timeline stage. type: object properties: at: description: When it happened (ISO 8601). type: string kind: description: exchange_event = one attempt/response/poll observation; webhook = an inbound source webhook receipt; collapsed_run = N near-identical repeated events elided (retry loops). type: string enum: - exchange_event - webhook - collapsed_run eventType: description: Ledger event type (attempt_started, request_sent, response_received, precondition_failed, poll_result, webhook_received, terminalized). type: - string - 'null' outcome: type: - string - 'null' errorCode: description: Structured error code when the exchange failed. type: - string - 'null' recovery: description: 'Recovery class of a failure: transient (retry can succeed), correctable (fix the input and resubmit), structural (no retry can succeed — escalate).' type: - string - 'null' enum: - transient - correctable - structural attemptNumber: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 hiddenCount: description: 'For collapsed_run: how many near-identical events were elided.' type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 detail: description: Short human-readable note (webhook type, poll status, …). type: - string - 'null' required: - at - kind - eventType - outcome - errorCode - recovery - attemptNumber - hiddenCount - detail additionalProperties: false ErrorResponse: description: Standard error response type: object properties: data: type: - string - 'null' enum: - null error: $ref: '#/components/schemas/ApiError' required: - data - error additionalProperties: false DemandInboxMetrics: description: Front-of-house scoreboard. Every field is computed only from persisted rows; a metric with no inputs reports null (unavailable), never 0. type: object properties: briefsYtd: description: Count of brief passes received this calendar year. type: integer minimum: -9007199254740991 maximum: 9007199254740991 answeredPercent: description: Share of this year’s briefs the agent answered with a proposal (0–100). Null when no briefs exist yet. type: - number - 'null' winRate: description: Won / (won + lost) across briefs with a decided commercial result (0–100). Null when no result is recorded yet. type: - number - 'null' avgGrade: description: Mean seller grade rounded to the nearest letter. Null when nothing is graded yet. type: - string - 'null' enum: - A - B - C - D - F agentVsHuman: description: Led-by split across briefs with recorded attribution. Null when no run has been attributed yet. type: - object - 'null' properties: agent: type: integer minimum: -9007199254740991 maximum: 9007199254740991 human: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - agent - human additionalProperties: false bookedYtd: description: Money won this calendar year, one entry per currency, from attributed outcomes that carried both an amount and its currency (delivered spend when reported, else the booked media-buy budget). Null when nothing won this year recorded a priced outcome. type: - array - 'null' items: type: object properties: amount: type: number currency: type: string required: - amount - currency additionalProperties: false required: - briefsYtd - answeredPercent - winRate - avgGrade - agentVsHuman - bookedYtd additionalProperties: false ManagedSalesAgentSummary: description: Read-only managed ad-server source state for inventory sources with `executionType=MANAGED_SALES_AGENT`. type: object properties: connectionId: description: Surrogate id of the underlying managed ad-server source connection (BIGINT serialized as string). Used internally to route action requests; clients should generally identify the source by the inventory `sourceId` instead. type: string tenantId: description: Upstream tenant id for the managed ad-server source. Null until provisioning succeeds. type: - string - 'null' adServer: description: Publisher-supplied ad-server config. Null if not yet collected. allOf: - $ref: '#/components/schemas/AdServerConfigView' lastError: description: Failure reason from the most recent provisioning or test-connection attempt. type: - string - 'null' lastErrorCode: description: Machine-readable classification of the most recent provisioning failure (`ADAPTER_NETWORK_NOT_FOUND`, `ADAPTER_PERMISSION_DENIED`, `ADAPTER_INVALID_CREDENTIALS`, `ADAPTER_INVALID_CONFIG`, `ADAPTER_CONNECTION_FAILED`, or `INTERNAL_ERROR`). Null when there has been no failure. Same vocabulary as `EsaConnection.lastErrorCode` on the full ad-server connection. type: - string - 'null' lastTestedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ provisionedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ deactivatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - connectionId - tenantId - adServer - lastError - lastErrorCode - lastTestedAt - provisionedAt - deactivatedAt additionalProperties: false CompleteInventorySourceWorkItemBody: description: Completes a modular inventory source work item and applies any completion side effects required by the module contract. type: object properties: result: type: object additionalProperties: {} notes: type: string ResolveHouseResponse: description: A domain resolved up its corporate hierarchy for authoring. type: object properties: domain: description: Normalized input domain. type: string chain: description: Ordered self → … → house. A single element means the domain heads its own house or only a self-domain fallback is available; use coverage to distinguish unregistered from unavailable. example: - converse.com - nike.com type: array items: type: string house: description: The corporate house at the top of the chain. example: nike.com type: string known: description: Whether usable published hierarchy evidence exists. False means the domain is unregistered or hierarchy evidence is unavailable; inspect coverage before treating that as a definitive no-match. type: boolean coverage: description: 'Hierarchy coverage state: registered means usable registry/upstream or cached hierarchy evidence, unregistered means a definitive self-domain fallback, and unavailable means no usable evidence was available.' type: string enum: - registered - unregistered - unavailable resolverDegraded: description: True when registry resolution failed and the response retained fallback cache evidence; coverage explains whether that evidence is usable. type: boolean isTop: description: A known domain that already heads its own house. type: boolean required: - domain - chain - house - known - coverage - resolverDegraded - isTop additionalProperties: false SellerTimelineStage: description: One reached stage of the exchange, with evidence. type: object properties: stage: $ref: '#/components/schemas/SellerTimelineStageName' at: description: When the buy entered this stage (ISO 8601). Null when the stage is inferred without a precise timestamp. type: - string - 'null' detail: description: Human-readable note — the reviewer decision, the sanitized source moderation message, the failure summary. type: - string - 'null' evidence: description: Supporting observations, newest first. type: array items: $ref: '#/components/schemas/SellerTimelineEvidence' required: - stage - at - detail - evidence additionalProperties: false DemandExchangeRunPurpose: description: The compose run's own trusted execution classification. 'live' (or the historical 'unclassified' sentinel) is real buyer demand; every other value — including 'unknown', which marks a classification this build does not recognize — is never treated as a live buyer. type: string enum: - live - setup_test - simulation - probe - evaluation - unclassified - unknown InventorySourceWorkItemSummary: description: Summary of a seller-facing modular inventory source work item. Fetch the detail endpoint for module payload and result metadata. type: object properties: id: type: string storefrontId: type: string inventorySourceId: type: string moduleId: type: - string - 'null' kind: type: string enum: - APPROVE_MEDIA_BUY - APPROVE_MEDIA_BUY_CANCELLATION - REVIEW_CREATIVE - CONFIRM_AVAILS - APPROVE_RATE_EXCEPTION - MAP_CREATIVE_REF - SYNC_UPSTREAM_CREATIVE - EXECUTE_UPSTREAM_BOOKING - TRAFFIC_TO_CADENT - RESOLVE_TRAFFICKING_ERROR - UPLOAD_FINAL_REPORT - RESOLVE_SOURCE_HEALTH - GENERAL title: type: string description: type: - string - 'null' status: type: string enum: - OPEN - IN_PROGRESS - BLOCKED - COMPLETED - CANCELLED priority: type: string enum: - LOW - NORMAL - HIGH - URGENT resourceType: type: string resourceId: type: string mediaBuyId: type: - string - 'null' buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 assignedTo: type: - string - 'null' dueAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ blockedReason: type: - string - 'null' createdByType: type: string createdById: type: - string - 'null' completedBy: type: - string - 'null' completedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ requiredResultFields: type: array items: type: string required: - id - storefrontId - inventorySourceId - moduleId - kind - title - description - status - priority - resourceType - resourceId - mediaBuyId - buyerCustomerId - assignedTo - dueAt - blockedReason - createdByType - createdById - completedBy - completedAt - createdAt - updatedAt additionalProperties: false ResolveGamCleanupBody: description: Explicitly confirm safe archival, or record that the order was cleaned up manually in GAM. anyOf: - type: object properties: confirmed: type: boolean enum: - true manuallyCleaned: not: {} orderId: type: string minLength: 1 required: - confirmed - orderId - type: object properties: confirmed: not: {} manuallyCleaned: type: boolean enum: - true orderId: type: string minLength: 1 manualCleanupNote: type: string minLength: 1 maxLength: 500 required: - manuallyCleaned - orderId - manualCleanupNote InventorySourceWorkItemMutationResponse: type: object properties: ok: type: boolean enum: - true item: $ref: '#/components/schemas/InventorySourceWorkItem' changed: description: Completion only. True when this call completed the item; false when it was already COMPLETED and the call was an idempotent no-op. Decided under the row lock, so it is safe against a concurrent completion. Absent on update responses. type: boolean required: - ok - item additionalProperties: false EsaCapabilityRecheckResult: description: Result of explicitly re-checking a separately provisioned ad-server capability. A successful check may resume the paused sync for that capability. type: object properties: capability: $ref: '#/components/schemas/EsaCapability' capabilityState: type: string enum: - unknown - available - awaiting_vendor_permission status: type: string enum: - available - awaiting_vendor_permission - not_probeable - credential_failure - retryable_failure - recovery_dispatch_failed - failed probePerformed: type: boolean issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false recoveryStarted: default: false type: boolean syncRunId: default: null type: - string - 'null' message: type: string required: - capability - capabilityState - status - probePerformed - issue - recoveryStarted - syncRunId - message additionalProperties: false MediaBuyPendingReason: description: Why a not-yet-delivering media buy is waiting, and implicitly whose side owns the wait. A platform-derived annotation — never a status value. awaiting_storefront_approval / awaiting_source_moderation / creative_processing_at_source / awaiting_creative_approval = the seller side owns the wait; no_creatives_attached / source_rejected_creatives = the buyer owns it (attach or fix creatives); forward_failed_retrying / forward_failed_needs_correction = the platform owns it; accepted_awaiting_trafficking / scheduled_not_started = nothing is wrong, the buy is queued or scheduled. type: string enum: - forward_failed_needs_correction - forward_failed_retrying - awaiting_storefront_approval - awaiting_source_moderation - no_creatives_attached - source_rejected_creatives - creative_processing_at_source - awaiting_creative_approval - accepted_awaiting_trafficking - scheduled_not_started ModularSourceModuleCredentialResponse: description: Non-secret lifecycle metadata for one inventory-source module credential. type: object properties: data: type: object properties: credentialId: type: string moduleInstanceId: type: string credentialKind: type: string enum: - API_KEY - BEARER - OAUTH status: type: string enum: - PENDING - ACTIVE - EXPIRED - REVOKED - ERROR scopes: type: array items: type: string expiresAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastRefreshedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ metadata: type: object additionalProperties: {} createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ revokedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - credentialId - moduleInstanceId - credentialKind - status - scopes - expiresAt - lastRefreshedAt - metadata - createdAt - updatedAt - revokedAt additionalProperties: false required: - data additionalProperties: false EsaSyncHistoryResponse: description: Historical sync-run timeline for operator drill-down from coarse status. type: object properties: runs: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' count: type: integer minimum: -9007199254740991 maximum: 9007199254740991 nextCursor: default: null type: - string - 'null' required: - runs - count - nextCursor additionalProperties: false IntelligenceRunExplanation: description: 'Sanitized, user-facing explanation derived from the persisted run record: selected products, reasoning, pricing notes, buyer-instruction effects, and failures.' type: object properties: summary: type: string selectedProducts: type: array items: $ref: '#/components/schemas/IntelligenceRunProductExplanation' unpricedProducts: type: array items: $ref: '#/components/schemas/IntelligenceRunUnpricedProductExplanation' buyerInstructionNotes: type: array items: type: string pricingNotes: type: array items: type: string failure: type: - object - 'null' properties: code: type: - string - 'null' message: type: - string - 'null' required: - code - message additionalProperties: false required: - summary - selectedProducts - unpricedProducts - buyerInstructionNotes - pricingNotes - failure additionalProperties: false StorefrontPricingFactPrice: description: Value-pricing anchor extracted from seller rate cards, media kits, or operator instructions. type: object properties: pricingModel: description: AdCP pricing model this pricing fact anchors, sourced from the AdCP SDK vocabulary. A price shape the protocol has no model for — share of voice, a day-part premium — is a product-coverage gap to report, not a value to store. default: cpm type: string enum: - cpm - vcpm - cpc - cpcv - cpv - cpp - cpa - flat_rate - time currency: description: ISO 4217 currency for this pricing fact. Falls back to the storefront pricing currency when omitted. example: USD type: string minLength: 3 maxLength: 3 targetPrice: description: Preferred value-based buyer-facing price for this fact. This is a value anchor, not a cost-plus markup. type: number exclusiveMinimum: 0 floorPrice: description: Hard minimum buyer-facing price when this fact applies. Composition also floors at wholesale cost/floor. type: number minimum: 0 ceilingPrice: description: Optional maximum buyer-facing price when this fact applies. type: number exclusiveMinimum: 0 BriefArtifact: description: 'The canonical inbound brief: the exact validated AdCP request, content-addressed and immutable.' type: object properties: id: type: string storefrontId: type: string buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 source: description: Capture surface (`live` = the AdCP get_products surface). type: string buyingMode: type: string adcpMajorVersion: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 schemaVersion: type: string redactionManifest: $ref: '#/components/schemas/ExchangeArtifactRedactionManifest' digest: description: sha-256 hex over the canonical (sorted-key) JSON of the redacted request — the content address. type: string byteSize: type: integer minimum: -9007199254740991 maximum: 9007199254740991 complete: description: False when the payload exceeded the size limit and only the envelope metadata was retained. type: boolean createdAt: type: string request: description: The exact validated inbound AdCP GetProductsRequest after redaction; null when complete=false. required: - id - storefrontId - buyerCustomerId - source - buyingMode - adcpMajorVersion - schemaVersion - redactionManifest - digest - byteSize - complete - createdAt - request additionalProperties: false DemandExchangeBudgetRange: description: The buyer's stated budget range, exactly as sent in the brief's filters.budget_range. Null when the buyer did not state one. type: object properties: min: type: - number - 'null' max: type: - number - 'null' currency: type: string required: - min - max - currency additionalProperties: false DemandCoverageSampleBrief: description: Representative starter-brief combination for seller demand coverage. type: object properties: category: type: string market: type: string channel: type: string status: type: string enum: - covered - needs_inventory rationale: type: string required: - category - market - channel - status - rationale additionalProperties: false GamAdServerConfig: description: Google Ad Manager configuration. Per-customer service-account credentials are managed by Scope3 (publisher grants access in their GAM admin console). type: object properties: type: type: string enum: - google_ad_manager connectionContract: description: Pinned built-in GAM connection contract. Omit only for legacy clients that have not migrated yet. type: object properties: id: type: string minLength: 1 maxLength: 128 pattern: ^[a-z][a-z0-9_-]*$ version: type: integer maximum: 9007199254740991 minimum: 1 authenticationMethod: type: string enum: - none - bearer_token - api_key - credential_exchange - basic_auth - oauth2 - jwt - platform_service_account required: - id - version - authenticationMethod additionalProperties: false networkCode: description: Google Ad Manager network code. example: '12345678' type: string minLength: 1 maxLength: 32 pattern: ^[0-9]+$ required: - type - networkCode CreativeReviewStatus: description: Lifecycle state of a buyer-submitted creative awaiting storefront review. `pending` until an operator decides; `approved` or `rejected` after a decision; `revoked` if an operator pulls a previously-approved creative. type: string enum: - pending - approved - rejected - revoked EsaSetupTaskItem: description: A single configuration-completeness item from the upstream managed-source status feed. type: object properties: id: type: string name: type: string severity: type: string enum: - blocker - warning - info scope: type: string enum: - platform - publisher description: type: string isComplete: type: boolean configurePath: description: Managed-source-relative path that surfaces the configuration UI for this task (e.g. `/settings#aao`). Null when no UI exists. type: - string - 'null' required: - id - name - severity - scope - description - isComplete additionalProperties: false PendingMediaBuyListResponse: description: List response for the operator approval queue. type: object properties: items: description: Entries matching the requested status filter, newest first. type: array items: $ref: '#/components/schemas/PendingMediaBuyResponse' total: description: Number of entries returned. type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false IntelligenceRunPurpose: description: Trusted execution classification. Null is reserved for historical runs recorded before purpose was required. type: string enum: - live - setup_test - simulation - probe - evaluation GetProposalArtifactResponse: type: object properties: data: $ref: '#/components/schemas/ProposalArtifact' required: - data additionalProperties: false OperatingInstructionsListResponse: description: List of operating-instructions versions for a storefront. type: object properties: items: description: Versions for this storefront, newest first. The active version (if any) is also flagged via `isActive`. type: array items: $ref: '#/components/schemas/OperatingInstructionsResponse' total: description: Total number of versions authored for this storefront. type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false SourceRecheckAction: description: Portable named operation for re-running a source-health check. Hosts resolve method and path from the canonical operation registry; deprecated method/path fields remain as a derived compatibility projection. oneOf: - type: object properties: kind: type: string enum: - recheck label: type: string operation: type: string enum: - refresh_esa pathParams: type: object properties: esaId: type: string required: - esaId additionalProperties: false method: description: Deprecated compatibility projection. Dispatch the named operation instead. deprecated: true type: string enum: - POST path: description: Deprecated compatibility projection derived from the operation registry. Dispatch the named operation instead. deprecated: true type: string required: - kind - label - operation - pathParams - method - path additionalProperties: false - type: object properties: kind: type: string enum: - recheck label: type: string operation: type: string enum: - recheck_esa_capability pathParams: type: object properties: esaId: type: string capability: type: string enum: - reporting - forecasting required: - esaId - capability additionalProperties: false method: description: Deprecated compatibility projection. Dispatch the named operation instead. deprecated: true type: string enum: - POST path: description: Deprecated compatibility projection derived from the operation registry. Dispatch the named operation instead. deprecated: true type: string required: - kind - label - operation - pathParams - method - path additionalProperties: false - type: object properties: kind: type: string enum: - recheck label: type: string operation: type: string enum: - run_inventory_source_discovery_test pathParams: type: object properties: sourceId: type: string required: - sourceId additionalProperties: false body: type: object properties: {} additionalProperties: false method: description: Deprecated compatibility projection. Dispatch the named operation instead. deprecated: true type: string enum: - POST path: description: Deprecated compatibility projection derived from the operation registry. Dispatch the named operation instead. deprecated: true type: string required: - kind - label - operation - pathParams - body - method - path additionalProperties: false type: object AcceptancePolicyResponse: description: A single acceptance-policy version for a storefront. Versions are immutable; updates produce a new row. type: object properties: id: description: Surrogate id of the version row (BIGINT serialized). example: '42' type: string storefrontId: description: Storefront the version belongs to (BIGINT serialized as string). example: '1234' type: string version: description: Per-storefront version number. example: 3 type: integer minimum: 1 maximum: 9007199254740991 content: description: Markdown acceptance policy. type: string notes: description: Operator note about why this version was authored. type: - string - 'null' isActive: description: Whether this version is the Storefront's active acceptance policy. type: boolean createdAt: description: Creation timestamp (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdBy: description: User id of the operator who authored the version (BIGINT serialized as string). Null when authored by a system or service-token caller. type: - string - 'null' required: - id - storefrontId - version - content - notes - isActive - createdAt - createdBy additionalProperties: false StorefrontResponse: description: Storefront configuration response type: object properties: storefrontId: description: Surrogate id (BIGINT serialized as string) example: '1234' type: string platformId: description: Public-facing slug example: acme-media type: string name: description: Display name example: Acme Media type: string publisherDomain: description: Publisher domain for the storefront's business profile example: acme.com type: - string - 'null' operatorDomain: description: Canonical operator domain example: scope3.com type: - string - 'null' brandName: description: Brand name from AAO registry example: Scope3 type: - string - 'null' logoUrl: description: Logo URL from brand.json type: - string - 'null' logoBackground: description: Backdrop the logo is designed for, from brand.json. Null or absent when unknown; the storefront card falls back to a dark tile. type: - string - 'null' enum: - dark-bg - light-bg - transparent-bg membershipStatus: description: AAO membership tier. Null when the operator has not set a value. type: - string - 'null' enum: - AAO_FOUNDING_MEMBER - AAO_MEMBER - NONE regions: description: Legacy merchandising-region context projected from businessProfile. This does not govern brief acceptance or Discovery Card country coverage. type: array items: type: string acceptedCountries: description: Operator-confirmed exhaustive country allowlist for brief routing. Null means routing scope has not been confirmed. type: - array - 'null' items: type: string pattern: ^[A-Z]{2}$ acceptsAllCountries: description: Whether the operator explicitly accepts briefs from every country. type: boolean advertisingPolicyDisclosure: description: Seller-selected Business Rules sections disclosed publicly as Advertising Policies. Empty means no local disclosure. type: array items: description: A Business Rules section the seller elects to disclose publicly as Advertising Policies on its Discovery Card. type: string enum: - brief_acceptance - creative_policy advertisedCountries: description: Standard primary countries advertised by backing AdCP sales agents. Authoritative for a pure pass-through Discovery Card; inventory evidence otherwise. type: array items: type: string pattern: ^[A-Z]{2}$ advertisedChannels: description: Standard primary channels advertised by backing AdCP sales agents. Authoritative for a pure pass-through Discovery Card; inventory evidence otherwise. type: array items: type: string description: description: Operator-curated description (overrides brand.json). type: - string - 'null' channels: description: ADCP channel codes the storefront offers. type: array items: type: string website: description: Operator-curated website URL (overrides brand.json). type: - string - 'null' discoveryCard: description: Canonical buyer-visible storefront identity and coverage. This is distinct from Media Kit merchandising inputs and seller policies. allOf: - $ref: '#/components/schemas/DiscoveryCard' demandContactName: description: Demand contact name. Null when the operator has not set one. type: - string - 'null' demandContactEmail: description: Demand contact email. Null when the operator has not set one. type: - string - 'null' operatorDomainVerified: description: Whether the operator domain has been verified (email match or manual KYC) type: boolean routingMode: description: 'Which backend function the buyer-facing storefront dispatches to: the Merchandising Agent or an expert-run adapter.' type: string enum: - CHEF - ADAPTER adapterProviderType: description: Expert-run adapter provider when routingMode is `ADAPTER`; null otherwise. type: - string - 'null' enum: - amazon - audiostack - elevenlabs - fal - gemini - google - linkedin - meta - openai - pinterest - reddit - snap - spotify - tiktok - veo adapterSourceKind: description: Adapter role when routingMode is `ADAPTER`; null otherwise. type: - string - 'null' enum: - sales - creative - signals - measurement - optimization - composite adapterCredentialMode: description: Adapter credential mode when routingMode is `ADAPTER`; null otherwise. type: - string - 'null' enum: - BYOK plan: description: Storefront plan tier type: string enum: - basic transacting: description: Deprecated compatibility projection of `!isPaused`; not proof that the storefront currently satisfies readiness. type: boolean isPaused: description: Compatibility-named seller intake hold. True blocks discovery, new buys, and buyer edits but does not pause existing delivery. False is neutral; it does not by itself make the storefront live. type: boolean archivedAt: description: When the storefront was archived (read-only thereafter). Null for non-archived storefronts. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ displayStatus: description: Deprecated stored-control display status. This is never proof that the storefront can transact; use the readiness projection. type: string enum: - configuring - transacting - archived - neutral - paused capabilities: description: Effective buyer-facing AdCP capabilities. Product composition derives from merchandising access and ready Source product paths; it is not locked to the legacy configured flag. allOf: - $ref: '#/components/schemas/StorefrontCapabilities' configuredCapabilities: description: Persisted operator capability flags before source-topology derivation. Compare this field for declarative writes; `capabilities` is the effective buyer-facing projection. allOf: - $ref: '#/components/schemas/StorefrontCapabilities' setupIntent: description: Declared selling intent from the first onboarding question, or null when the operator has not been asked yet. A record of the operator's answer — what the storefront exposes is always the derived `capabilities`. type: - string - 'null' enum: - third_party_connect - sell_through_scope3 compositionPricing: description: 'Composition pricing settings: fallback pricing percentile plus seller pricing facts. Separate from Scope3 contract/billing rate cards.' allOf: - $ref: '#/components/schemas/StorefrontCompositionPricingOutput' creativeApproval: description: Stored operator setting for creative submissions. It only affects ad-server-backed or product-composition storefronts; pass-through external-agent storefronts ignore this because their sources own review. type: string enum: - auto - manual mediaBuyApproval: description: Stored operator setting for new media buys. It only affects ad-server-backed or product-composition storefronts; pass-through external-agent storefronts ignore this because Interchange does not insert an approval queue. type: string enum: - auto - manual capabilitiesLocked: description: 'Legacy topology projection: true when the storefront has at least one active ad-server-backed inventory source (`executionType=MANAGED_SALES_AGENT`). Product composition is now Source-derived, so this value does not authorize or lock capability writes.' type: boolean advertiseAsAgent: description: 'Derived: true when the Storefront has an active Inventory Source, an active embedded Sales Agent, adapter routing, or an advertised Storefront-owned capability. Every active Source remains behind the buyer-facing Storefront AdCP endpoint, including COMPOSING-only Sources.' type: boolean sellsThirdPartyInventory: description: 'Operator toggle: when true, the storefront also resells third-party inventory from other Interchange storefronts (composition draws from the marketplace in addition to its own sources). When false/absent (default), the storefront sells only its own inventory sources.' type: boolean createdAt: description: Creation timestamp (ISO 8601) type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: description: Last update timestamp (ISO 8601) type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ businessProfile: description: Operator-supplied business profile captured during Murph-led setup. Null when the operator has not shared one. allOf: - $ref: '#/components/schemas/BusinessProfileOutput' defaultCurrency: description: Seller-confirmed primary settlement currency (ISO-4217). Null until confirmed; required before go-live for Interchange-cleared storefronts. Direct sales adapter storefronts run by our expert agents skip settlement-currency readiness checks because Interchange does not pay the seller on that path. type: - string - 'null' paymentCurrencies: description: ISO-4217 currencies the storefront will be paid in (the payout set). A media buy settles in one of these. Empty falls back to defaultCurrency. The marketplace may additionally accept buyer currencies outside this set via cross-currency FX, converting each source cost to the buyer currency at the platform spot rate. type: array items: type: string required: - storefrontId - platformId - name - publisherDomain - operatorDomain - brandName - logoUrl - membershipStatus - regions - acceptedCountries - acceptsAllCountries - advertisingPolicyDisclosure - advertisedCountries - advertisedChannels - description - channels - website - discoveryCard - demandContactName - demandContactEmail - operatorDomainVerified - routingMode - adapterProviderType - adapterSourceKind - adapterCredentialMode - plan - transacting - isPaused - archivedAt - displayStatus - capabilities - configuredCapabilities - compositionPricing - creativeApproval - mediaBuyApproval - capabilitiesLocked - advertiseAsAgent - createdAt - updatedAt - businessProfile additionalProperties: false RefreshComplianceBody: description: Request body for re-running the storefront compliance check. type: object properties: agentId: description: Scope the live re-run to a single agent. When omitted, every testable agent on this storefront is re-checked. type: string minLength: 1 additionalProperties: false OperatingInstructionsResponse: description: A single operating-instructions version for a storefront. Versions are immutable; updates produce a new row. type: object properties: id: description: Surrogate id of the version row (BIGINT serialized as string). example: '42' type: string storefrontId: description: Storefront the version belongs to (BIGINT serialized as string). example: '1234' type: string version: description: Per-storefront version number. Monotone, never reused. The first version a storefront authors is 1. example: 3 type: integer minimum: 1 maximum: 9007199254740991 content: description: Markdown body consumed by the Merchandising Agent. type: string notes: description: Operator note about why this version was authored. type: - string - 'null' isActive: description: Whether this version is the Storefront's active operating instructions (the version the Merchandising Agent will use on the next composition). type: boolean createdAt: description: Creation timestamp (ISO 8601). Rows are immutable so there is no updatedAt. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdBy: description: User id of the operator who authored the version (BIGINT serialized as string). Null when authored by a system or service-token caller. type: - string - 'null' ownershipIssues: description: Canonical-ownership conflicts detected in this immutable version. Empty for versions that keep pricing, discounts, markets, and acceptance facts in their owning storefront surfaces. type: array items: type: object properties: area: type: string enum: - pricing - discounts - markets - acceptance_policy canonicalOwner: type: string enum: - selling_terms - buyer_discounts - business_profile - acceptance_policy canonicalSurface: type: string enum: - playbook_pricing - buyer_discounts - discovery_card - business_rules message: type: string required: - area - canonicalOwner - canonicalSurface - message additionalProperties: false doctrine: description: 'The selling doctrine this version composes under (AI-5870) — always resolved, never null: a version that stored none reads the platform default with `isDefault: true`.' allOf: - $ref: '#/components/schemas/SellingDoctrineResponse' required: - id - storefrontId - version - content - notes - isActive - createdAt - createdBy - ownershipIssues - doctrine additionalProperties: false StorefrontPricingFact: description: Lightly structured seller value-pricing fact. Pricing facts anchor prices and floors; they are not product assembly templates. type: object properties: id: description: Stable operator-facing id for this pricing fact. Murph should preserve ids across rewrites when the fact is semantically the same. type: string minLength: 1 maxLength: 120 pattern: ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ label: description: Short display label for this pricing fact. example: Rich media packages type: string minLength: 1 maxLength: 160 appliesWhen: description: Natural-language applicability condition. This is intentionally not a rigid product template; the Merchandising Agent uses it as reasoning context. type: string minLength: 1 maxLength: 2000 hints: description: Optional structured hints for deterministic matching. Missing hints are fine. default: {} allOf: - $ref: '#/components/schemas/StorefrontPricingFactHints' pricing: $ref: '#/components/schemas/StorefrontPricingFactPrice' strength: default: default description: '`hard_floor` is a must-not-go-below seller constraint. `default` is the preferred value-pricing anchor. `guidance` is advisory context only.' type: string enum: - hard_floor - default - guidance provenance: description: Where this pricing fact came from, such as "Uploaded 2026 rate card, page 3" or "Operator statement on setup call". type: string maxLength: 500 notes: description: Human-readable rationale or caveats for operators and Murph. type: string maxLength: 2000 required: - id - label - appliesWhen - pricing LinkedStorefrontSummary: description: Retired. Never populated — storefront interchange runs through the ambient wholesale pool, so no inline link state is produced. Retained as a reserved, always-null component for response-shape stability. type: object properties: status: description: Retired. Storefront interchange no longer uses per-counterparty links; this enum is retained only for response-shape stability and is never emitted. type: string enum: - PENDING - ACTIVE - REJECTED - CANCELLED buyer: description: The storefront that initiated the link (the row owner). allOf: - $ref: '#/components/schemas/StorefrontResponse' seller: description: The storefront whose inventory the link surfaces. allOf: - $ref: '#/components/schemas/StorefrontResponse' requestMessage: type: - string - 'null' responseMessage: type: - string - 'null' requestedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ respondedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cancelledAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ cancelledBy: description: Which side stopped the link. Null until status is `CANCELLED`. type: - string - 'null' enum: - BUYER - SELLER required: - status - buyer - seller - requestMessage - responseMessage - requestedAt - respondedAt - cancelledAt - cancelledBy additionalProperties: false SellingDoctrineSetThresholds: type: object properties: thresholds: $ref: '#/components/schemas/SellingDoctrineThresholds' required: - thresholds additionalProperties: false BuyerInstructionsListResponse: description: List of buyer-instructions rows for a storefront. type: object properties: items: type: array items: $ref: '#/components/schemas/BuyerInstructionsResponse' total: type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false SourceDetailAction: description: Server-selected portable specialist surface for one inventory source. The operation discriminant fixes the exact validated arguments shape. oneOf: - type: object properties: operation: type: string enum: - list_ad_server_sources arguments: type: object properties: esaId: type: string minLength: 1 required: - esaId additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - get_modular_inventory_source_readiness arguments: type: object properties: sourceId: type: string minLength: 1 required: - sourceId additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - open_source_diagnostics arguments: type: object properties: sourceId: type: string minLength: 1 sourceName: type: string minLength: 1 required: - sourceId - sourceName additionalProperties: false required: - operation - arguments additionalProperties: false type: object InventorySourceMappingWorkspaceResponse: description: Mode-aware, source-scoped mapping workspace. Shared identity counts are Storefront projections; source and mapped counts never imply coverage by another Source. type: object properties: source: type: object properties: id: type: string sourceId: type: string name: type: string status: type: string enum: - PENDING - ACTIVE - DISABLED executionType: type: string declaredAgentProductMode: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH bindingProductMode: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH effectiveProductMode: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH runtimeReasons: type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY required: - id - sourceId - name - status - executionType - declaredAgentProductMode - bindingProductMode - effectiveProductMode - runtimeReasons additionalProperties: false productPaths: type: array items: type: object properties: productPath: type: string enum: - WHOLESALE - COMPOSING active: type: boolean runtimeReady: type: boolean runtimeReasons: type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY sections: type: array items: type: object properties: id: type: string enum: - connection - inventory - properties - formats - pricing - advertisers - diagnostics label: type: string owner: type: string enum: - SUPPLIED_BY_CONNECTED_AGENT - MANAGED_BY_SCOPE3_ADAPTER - CONFIGURED_IN_STOREFRONT - NEEDS_SELLER_MAPPING - NEEDS_SCOPE3_RECONCILIATION access: type: string enum: - READ_ONLY - UNAVAILABLE state: type: - string - 'null' enum: - READY - NEEDS_ATTENTION - EMPTY - RETAINED_INACTIVE summary: type: string counts: type: object properties: shared: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 source: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 mapped: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - shared - source - mapped additionalProperties: false nextAction: type: - object - 'null' properties: label: type: string owner: type: string enum: - SELLER - CONNECTED_AGENT - SCOPE3 path: type: - string - 'null' format: uri pattern: ^https:\/\/.* required: - label - owner - path additionalProperties: false required: - id - label - owner - access - state - summary - counts - nextAction additionalProperties: false required: - productPath - active - runtimeReady - runtimeReasons - sections additionalProperties: false storefrontProjection: type: object properties: properties: type: object properties: shared: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 source: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 mapped: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - shared - source - mapped additionalProperties: false formats: type: object properties: shared: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 source: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 mapped: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - shared - source - mapped additionalProperties: false advertisers: type: object properties: shared: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 source: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 mapped: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - shared - source - mapped additionalProperties: false required: - properties - formats - advertisers additionalProperties: false generatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - source - productPaths - storefrontProjection - generatedAt additionalProperties: false BuyerAutoApproveResponse: description: A single per-buyer media-buy auto-approve override. type: object properties: id: description: Surrogate id (BIGINT serialized as string). example: '42' type: string storefrontId: description: Storefront the override belongs to (BIGINT serialized as string). example: '1234' type: string buyerCustomerId: description: Customer id of the trusted buyer (INTEGER). example: 804 type: number buyerName: description: Resolved buyer company/name for operator confirmation. Null if it cannot be resolved. example: Coca-Cola type: - string - 'null' autoApproveEnabled: type: boolean reason: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdBy: description: Session user id of the operator who first armed the override (BIGINT serialized as string), when available. type: - string - 'null' createdByCustomerId: description: Operator customer id that first armed the override. type: - number - 'null' updatedByCustomerId: description: Operator customer id that last changed the override. type: - number - 'null' policyBypassCount: description: How many of this buyer's media buys were auto-forwarded while enabled even though the acceptance-policy evaluator would have held them. A rising count is a prompt to reconsider the carve-out; it never blocks a buy. example: 0 type: integer minimum: 0 maximum: 9007199254740991 lastPolicyBypassAt: description: When the most recent policy-flagged buy was auto-forwarded for this buyer, or null if none. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - buyerCustomerId - buyerName - autoApproveEnabled - reason - createdAt - updatedAt - createdBy - createdByCustomerId - updatedByCustomerId - policyBypassCount - lastPolicyBypassAt additionalProperties: false SubmitDemandExchangeRevisionBody: description: Submit a draft for approval, or clear it immediately when the storefront/buyer auto-approve dial covers it. expectedSubmissionGeneration must match the draft's current submissionGeneration (as read) — a stale generation (a concurrent amend landed first) is refused rather than submitting content the caller never saw. type: object properties: expectedSubmissionGeneration: type: integer minimum: 0 maximum: 9007199254740991 required: - expectedSubmissionGeneration CatalogMappingAction: description: One portable, validated V2 operation. The same action is projected to Modular Source and Seller Setup. oneOf: - type: object properties: operation: type: string enum: - open_modular_avails_commit arguments: type: object properties: sourceId: type: string required: - sourceId additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - open_property_roster arguments: type: object properties: {} additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - get_modular_inventory_source_readiness arguments: type: object properties: sourceId: type: string required: - sourceId additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - get_playbook arguments: type: object properties: {} additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - get_business_rules arguments: type: object properties: {} additionalProperties: false required: - operation - arguments additionalProperties: false - type: object properties: operation: type: string enum: - test_storefront_brief arguments: type: object properties: sourceId: type: string required: - sourceId additionalProperties: false required: - operation - arguments additionalProperties: false type: object InventorySourceWorkItemDetailResponse: type: object properties: item: $ref: '#/components/schemas/InventorySourceWorkItem' events: type: array items: $ref: '#/components/schemas/InventorySourceWorkItemEvent' required: - item - events additionalProperties: false StorefrontCompositionPricing: description: 'Storefront composition pricing settings: fallback guidance percentile plus lightly structured seller pricing facts.' type: object properties: targetPercentile: default: p75 description: 'Deprecated. Historical auction-clearing percentile, retained for explainability only — it no longer sets the price. Pricing is value-led: the Merchandising Agent prices each brief to its value, bounded by wholesale floors and seller ceilings, never anchored to a clearing percentile.' type: string enum: - p50 - p75 - p90 rateCard: description: Seller product-pricing facts. Separate from Scope3 contract rate cards. default: facts: [] type: object properties: currency: description: Default ISO 4217 currency for pricing facts in this storefront rate card. example: USD type: string minLength: 3 maxLength: 3 facts: default: [] maxItems: 500 type: array items: $ref: '#/components/schemas/StorefrontPricingFact' FeedPreviewBody: description: Request body for POST /inventory-sources/:sourceId/feed/preview. type: object properties: contractId: $ref: '#/components/schemas/FeedContractId' rawRows: description: JSON rows — provide exactly one of rawRows, csvText, or jsonText. minItems: 1 type: array items: type: object additionalProperties: {} csvText: description: CSV text — provide exactly one of rawRows, csvText, or jsonText. type: string minLength: 1 maxLength: 2000000 jsonText: description: JSON text — provide exactly one of rawRows, csvText, or jsonText. type: string minLength: 1 maxLength: 2000000 idempotencyKey: description: Deterministic replay idempotency key (UUID). Provide only together with revisionId and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: description: Deterministic replay revision id (UUID). Provide only together with idempotencyKey and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ observedAt: description: ISO-8601 observation timestamp for deterministic replay. Provide only together with idempotencyKey and revisionId; omit all three fields to default to the current time. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - contractId DemandExchangeFedBy: type: object properties: ingredientType: description: Which of the seller's ingredient families this attribution names. 'taught_guidance' is reserved for standing guidance a seller teaches the agent and is not written yet. type: string enum: - inventory_bundle - signal - pricing_fact - operating_instructions - buyer_instructions - taught_guidance ingredientId: description: The real id on the ingredient's canonical owner as it stood at compose time — a wholesale bundle id, signal id, rate-card pricing fact id, playbook version, or buyer-terms row id. Never a synthesized key. type: string label: description: Operator-facing label captured at compose time, when the ingredient carries one. Null when the ingredient has no label of its own; the reader names the family instead of inventing copy. Renaming the ingredient later never rewrites this — chips name what fed the decision then. type: - string - 'null' version: description: The version consulted, where the owner is versioned. Only operating instructions (the Playbook) are versioned today; null everywhere else. type: - string - 'null' granularity: description: How honestly this attribution is scoped. 'product_line' = resolution genuinely named this ingredient for this product (its selected inventory bundles and signals, and the pricing facts matched against them). 'run' = the ingredient was resolved once for the whole pass and collapses into one prompt, so no per-product attribution exists (the Playbook and the buyer's resolved terms). 'pitch_claim' = the ingredient backs one sentence of the composed pitch; these appear inside the pitch's own claims rather than in a product's or pass's fedBy list. Never inferred — the writer records the level it actually had. type: string enum: - product_line - run - pitch_claim claimRef: description: The pitch sentence this attribution backs, for 'pitch_claim' entries; null for every other granularity. A stable server-minted handle, never model-authored, so a claim and its receipts always agree. default: null type: - string - 'null' ownerState: description: Whether the ingredient's owner can be opened now. 'available' = it still exists and has an owner Task. 'ingredient_removed' = a completed check proved the ingredient is gone, so the chip opens an honest missing state rather than a fabricated Task. 'no_owner_surface' = it exists but no owner Task is reachable from this surface (per-buyer terms, or inventory reached through another seller's storefront). 'owner_unavailable' = the check that would have decided between those did not complete, so existence is unknown — never reported as deletion. Only 'available' carries a launch; readers must treat an unrecognized value as non-launchable. type: string enum: - available - ingredient_removed - no_owner_surface - owner_unavailable ownerToolName: description: Canonical owner tool the chip launches through the shared MCP app contract. Non-null only when ownerState is 'available'. type: - string - 'null' ownerArguments: description: Arguments that owner Task needs (e.g. the inventory source id). Non-null exactly when ownerToolName is. type: - object - 'null' additionalProperties: type: string required: - ingredientType - ingredientId - label - version - granularity - claimRef - ownerState - ownerToolName - ownerArguments additionalProperties: false SourceHealthDiagnosis: description: 'One typed source-health diagnosis: what failed, who owns the fix, how much it matters to this storefront, and the inline action.' type: object properties: diagnosisId: description: 'Stable within a storefront: ":".' type: string sourceId: description: Inventory source this diagnosis is about; null for storefront-level problems (e.g. the ad server source connection). type: - string - 'null' sourceName: type: string failureMode: description: Typed failure mode from the source-diagnosis catalog. type: string enum: - catalog_products_stale - catalog_products_empty - catalog_products_hidden - catalog_signals_stale - catalog_fetch_error - adapter_credentials_invalid - ad_server_sync_failed - reporting_access_missing - forecasting_access_missing - source_unreachable - source_degraded - reporting_unreachable - reporting_payload_rejected - agent_auth_missing - trafficking_error - wholesale_pricing_stale - media_buy_status_stale owner: description: Who owns the fix. Only `seller`-owned diagnoses may become a task, a blocker, or a notification; `scope3`/`vendor` diagnoses render as passive status lines and route internally. type: string enum: - seller - scope3 - vendor severity: description: 'Impact on THIS storefront, never the failure mechanism: `blocking` stops selling/setup, `attention` degrades it, `advisory` will only matter later.' type: string enum: - blocking - attention - advisory summary: description: 'Customer-safe, one sentence: what is wrong and why it matters to the seller.' type: string detail: description: 'Customer-safe evidence: counts, ages, codes. Null when nothing useful.' type: - string - 'null' action: $ref: '#/components/schemas/DiagnosisAction' docsAnchor: description: mintlify troubleshooting anchor, when one exists. type: - string - 'null' observedAt: type: string required: - diagnosisId - sourceId - sourceName - failureMode - owner - severity - summary - detail - action - docsAnchor - observedAt additionalProperties: false DemandExchangeRevisionSend: description: How a sent revision cleared. Null until sent. An auto send never carries a human decision record. type: object properties: mode: type: - string - 'null' enum: - manual - auto autoApproveReason: type: - string - 'null' enum: - storefront_auto_approve - buyer_auto_approve required: - mode - autoApproveReason additionalProperties: false InventorySourceDiagnosticsResponse: description: Seller-facing diagnostics for a single third-party sales-agent or modular inventory source. type: object properties: source: type: object properties: id: type: string sourceId: type: string name: type: string executionType: description: What backs this private upstream inventory source. `AGENT` is an external AdCP-compatible sales agent the Merchandising Agent connects to; `MANAGED_SALES_AGENT` is an operator-owned ad server with Interchange-managed sales-agent plumbing behind it; `LINKED_STOREFRONT` is wholesale inventory discovered automatically from the ambient pool of LISTED storefronts whose computed `canTransact` projection is true (resolved at runtime, never persisted as a source row); `MODULAR_SOURCE` is a composed inventory source assembled from private modules such as avails, booking, trafficking, and reporting. Storefront-level `ADAPTER` dispatch is configured on the storefront, not as an inventory source. type: string enum: - AGENT - MANAGED_SALES_AGENT - LINKED_STOREFRONT - MODULAR_SOURCE status: description: Inventory source lifecycle status type: string enum: - PENDING - ACTIVE - DISABLED agentId: type: - string - 'null' endpointUrl: type: - string - 'null' protocol: type: - string - 'null' enum: - MCP - A2A auth: type: object properties: type: type: - string - 'null' required: type: boolean configured: type: boolean required: - type - required - configured additionalProperties: false capabilities: type: object properties: tools: type: array items: type: string products: type: string enum: - supported - unsupported - unknown createMediaBuy: type: string enum: - supported - unsupported - unknown updateMediaBuy: type: string enum: - supported - unsupported - unknown signals: type: string enum: - supported - unsupported - unknown required: - tools - products - createMediaBuy - updateMediaBuy - signals additionalProperties: false productMode: type: object properties: agentCapabilityUid: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ declaredAgentMode: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH bindingSelection: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH effectiveMode: type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH reasons: type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY paths: type: array items: type: object properties: path: type: string enum: - WHOLESALE - COMPOSING ready: type: boolean reasons: type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY required: - path - ready - reasons additionalProperties: false required: - agentCapabilityUid - declaredAgentMode - bindingSelection - effectiveMode - reasons - paths additionalProperties: false health: type: object properties: status: type: string enum: - healthy - degraded - unhealthy - unknown lastError: type: - string - 'null' lastErrorCode: type: - string - 'null' lastErrorAt: type: - string - 'null' lastSuccessAt: type: - string - 'null' lastCheckedAt: type: - string - 'null' required: - status - lastError - lastErrorCode - lastErrorAt - lastSuccessAt - lastCheckedAt additionalProperties: false capabilityHealth: type: object properties: inventory: type: object properties: status: type: - string - 'null' enum: - healthy - degraded - unhealthy observations: type: array items: type: object properties: observer: type: string status: type: string enum: - healthy - degraded - unhealthy previousStatus: type: - string - 'null' enum: - healthy - degraded - unhealthy cause: type: - string - 'null' detail: type: - string - 'null' owner: type: - string - 'null' observedAt: type: string lastOkAt: type: - string - 'null' required: - observer - status - previousStatus - cause - detail - owner - observedAt - lastOkAt additionalProperties: false required: - status - observations additionalProperties: false reporting: type: object properties: status: type: - string - 'null' enum: - healthy - degraded - unhealthy observations: type: array items: type: object properties: observer: type: string status: type: string enum: - healthy - degraded - unhealthy previousStatus: type: - string - 'null' enum: - healthy - degraded - unhealthy cause: type: - string - 'null' detail: type: - string - 'null' owner: type: - string - 'null' observedAt: type: string lastOkAt: type: - string - 'null' required: - observer - status - previousStatus - cause - detail - owner - observedAt - lastOkAt additionalProperties: false required: - status - observations additionalProperties: false required: - inventory - reporting additionalProperties: false required: - id - sourceId - name - executionType - status - agentId - endpointUrl - protocol - auth - capabilities - productMode - health - capabilityHealth additionalProperties: false window: type: object properties: hours: type: integer maximum: 9007199254740991 minimum: 1 startedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ sampledActivityCount: type: integer minimum: 0 maximum: 9007199254740991 activityTruncated: type: boolean sampledTestRunCount: type: integer minimum: 0 maximum: 9007199254740991 required: - hours - startedAt - endedAt - sampledActivityCount - activityTruncated - sampledTestRunCount additionalProperties: false performance: type: object properties: requestCount: type: integer minimum: 0 maximum: 9007199254740991 responseCount: type: integer minimum: 0 maximum: 9007199254740991 exchangeCount: type: integer minimum: 0 maximum: 9007199254740991 completedCount: type: integer minimum: 0 maximum: 9007199254740991 failedCount: type: integer minimum: 0 maximum: 9007199254740991 inputRequiredCount: type: integer minimum: 0 maximum: 9007199254740991 pendingCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutRate: type: number minimum: 0 maximum: 1 errorRate: type: number minimum: 0 maximum: 1 inputRequiredRate: type: number minimum: 0 maximum: 1 completedRate: type: number minimum: 0 maximum: 1 latencyStatus: type: string enum: - within_threshold - over_threshold - unknown latencyThresholdMs: type: integer maximum: 9007199254740991 minimum: 1 overThresholdCount: type: integer minimum: 0 maximum: 9007199254740991 staleAsyncResponseCount: type: integer minimum: 0 maximum: 9007199254740991 p50LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 p99LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 unknownLatencyCount: type: integer minimum: 0 maximum: 9007199254740991 required: - requestCount - responseCount - exchangeCount - completedCount - failedCount - inputRequiredCount - pendingCount - rejectedCount - timeoutCount - timeoutRate - errorRate - inputRequiredRate - completedRate - latencyStatus - latencyThresholdMs - overThresholdCount - staleAsyncResponseCount - p50LatencyMs - p95LatencyMs - p99LatencyMs - unknownLatencyCount additionalProperties: false comparison: type: object properties: previousWindow: type: object properties: startedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ exchangeCount: type: integer minimum: 0 maximum: 9007199254740991 issueCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 errorRate: type: number minimum: 0 maximum: 1 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 sampledActivityCount: type: integer minimum: 0 maximum: 9007199254740991 activityTruncated: type: boolean required: - startedAt - endedAt - exchangeCount - issueCount - timeoutCount - errorRate - p95LatencyMs - sampledActivityCount - activityTruncated additionalProperties: false issueDelta: type: integer minimum: -9007199254740991 maximum: 9007199254740991 timeoutDelta: type: integer minimum: -9007199254740991 maximum: 9007199254740991 errorRateDelta: type: number p95LatencyDeltaMs: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 trend: type: string enum: - new_issue - worse - improved - recovered - unchanged - not_enough_data summary: type: string required: - previousWindow - issueDelta - timeoutDelta - errorRateDelta - p95LatencyDeltaMs - trend - summary additionalProperties: false timeline: type: array items: type: object properties: startedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ exchangeCount: type: integer minimum: 0 maximum: 9007199254740991 issueCount: type: integer minimum: 0 maximum: 9007199254740991 failedCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 errorRate: type: number minimum: 0 maximum: 1 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - startedAt - endedAt - exchangeCount - issueCount - failedCount - rejectedCount - timeoutCount - errorRate - p95LatencyMs additionalProperties: false toolBreakdown: type: array items: type: object properties: tool: type: string exchangeCount: type: integer minimum: 0 maximum: 9007199254740991 completedCount: type: integer minimum: 0 maximum: 9007199254740991 failedCount: type: integer minimum: 0 maximum: 9007199254740991 inputRequiredCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - tool - exchangeCount - completedCount - failedCount - inputRequiredCount - rejectedCount - timeoutCount - p95LatencyMs additionalProperties: false externalCallLanes: type: array items: type: object properties: taskType: type: string callCount: type: integer minimum: 0 maximum: 9007199254740991 successCount: type: integer minimum: 0 maximum: 9007199254740991 errorCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 previous: type: object properties: callCount: type: integer minimum: 0 maximum: 9007199254740991 successCount: type: integer minimum: 0 maximum: 9007199254740991 errorCount: type: integer minimum: 0 maximum: 9007199254740991 timeoutCount: type: integer minimum: 0 maximum: 9007199254740991 p95LatencyMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 required: - callCount - successCount - errorCount - timeoutCount - p95LatencyMs additionalProperties: false required: - taskType - callCount - successCount - errorCount - timeoutCount - p95LatencyMs - previous additionalProperties: false discoveryParticipation: type: object properties: calledCount: type: integer minimum: 0 maximum: 9007199254740991 skippedCount: type: integer minimum: 0 maximum: 9007199254740991 excludedCount: type: integer minimum: 0 maximum: 9007199254740991 timedOutCount: type: integer minimum: 0 maximum: 9007199254740991 skipReasons: type: array items: type: object properties: reason: type: string count: type: integer maximum: 9007199254740991 minimum: 1 required: - reason - count additionalProperties: false required: - calledCount - skippedCount - excludedCount - timedOutCount - skipReasons additionalProperties: false outcomeMix: type: object properties: returnedProductsCount: type: integer minimum: 0 maximum: 9007199254740991 returnedNoProductsCount: type: integer minimum: 0 maximum: 9007199254740991 failedCount: type: integer minimum: 0 maximum: 9007199254740991 businessRejectedCount: type: integer minimum: 0 maximum: 9007199254740991 pendingCount: type: integer minimum: 0 maximum: 9007199254740991 inputRequiredCount: type: integer minimum: 0 maximum: 9007199254740991 timedOutCount: type: integer minimum: 0 maximum: 9007199254740991 skippedCount: type: integer minimum: 0 maximum: 9007199254740991 required: - returnedProductsCount - returnedNoProductsCount - failedCount - businessRejectedCount - pendingCount - inputRequiredCount - timedOutCount - skippedCount additionalProperties: false demandImpact: type: object properties: buyerRequestsAffected: type: integer minimum: 0 maximum: 9007199254740991 missedProductOpportunityCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 notes: type: array items: type: string required: - buyerRequestsAffected - missedProductOpportunityCount - notes additionalProperties: false recentActivity: type: array items: type: object properties: id: type: integer minimum: -9007199254740991 maximum: 9007199254740991 timestamp: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ tool: type: - string - 'null' taskStatus: type: string activityType: type: string taskId: type: - string - 'null' operationId: type: - string - 'null' contextId: type: - string - 'null' idempotencyKey: type: - string - 'null' debugId: type: - string - 'null' traceparent: type: - string - 'null' requestId: type: - string - 'null' correlationId: type: - string - 'null' initiatorEmail: type: - string - 'null' origin: type: object properties: kind: type: string enum: - sandbox_test - live_demand testRunUid: type: - string - 'null' testRunStatus: type: - string - 'null' enum: - passed - partial - failed - planned testRunToolName: type: - string - 'null' testRunCreatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - kind - testRunUid - testRunStatus - testRunToolName - testRunCreatedAt additionalProperties: false isIssue: type: boolean summary: type: - string - 'null' details: type: - object - 'null' properties: payload: type: object additionalProperties: {} relatedRequest: type: - object - 'null' properties: timestamp: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ payload: type: object additionalProperties: {} required: - timestamp - payload additionalProperties: false required: - payload - relatedRequest additionalProperties: false required: - id - timestamp - tool - taskStatus - activityType - taskId - operationId - contextId - idempotencyKey - debugId - traceparent - requestId - correlationId - initiatorEmail - origin - isIssue - summary - details additionalProperties: false diagnosis: type: object properties: severity: type: string enum: - ok - warning - critical - unknown owner: description: Who must act on the failure. `seller` for a generic external sales agent or an adapter credential issue; `scope3` when an official Scope3-hosted adapter runtime is failing (the seller cannot and should not fix our infrastructure). type: string enum: - seller - scope3 topCause: type: string issues: type: array items: type: object properties: mode: type: string enum: - disabled_retired - auth_missing - ad_server_connection_blocked - manual_pricing_upload_required - stale_async - async_poll_exhausted - timeout_degraded - source_runtime_error - input_required - business_rejected - readiness_blocker severity: type: string enum: - warning - critical count: type: integer maximum: 9007199254740991 minimum: 1 summary: type: string required: - mode - severity - count - summary additionalProperties: false nextSteps: type: array items: type: string developerHandoff: type: object properties: sourceId: type: string sourceName: type: string agentId: type: - string - 'null' endpointUrl: type: - string - 'null' latestTaskId: type: - string - 'null' latestOperationId: type: - string - 'null' latestContextId: type: - string - 'null' latestIdempotencyKey: type: - string - 'null' latestDebugId: type: - string - 'null' latestCorrelationId: type: - string - 'null' correlationHeaders: type: - object - 'null' additionalProperties: type: string latestError: type: - string - 'null' required: - sourceId - sourceName - agentId - endpointUrl - latestTaskId - latestOperationId - latestContextId - latestIdempotencyKey - latestDebugId - latestCorrelationId - correlationHeaders - latestError additionalProperties: false required: - severity - owner - topCause - issues - nextSteps - developerHandoff additionalProperties: false docs: type: array items: type: object properties: label: type: string url: type: string format: uri required: - label - url additionalProperties: false required: - source - window - performance - comparison - timeline - toolBreakdown - externalCallLanes - discoveryParticipation - outcomeMix - demandImpact - recentActivity - diagnosis - docs additionalProperties: false FeedPushResponse: description: Response from POST /feed/push. When dryRun is true or the revision is REJECTED, only revision is returned. Otherwise feedId, sourceId, revision, and revisionRecord are all present. anyOf: - type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ sourceId: type: string revision: $ref: '#/components/schemas/FeedRevisionEnvelope' revisionRecord: $ref: '#/components/schemas/FeedRevisionRecord' required: - feedId - sourceId - revision - revisionRecord additionalProperties: false - type: object properties: dryRun: type: boolean enum: - true revision: $ref: '#/components/schemas/FeedRevisionEnvelope' required: - dryRun - revision additionalProperties: false EsaPricingCoverageSummary: description: Per-product wholesale pricing coverage. Ad-server and manual pricing may coexist; unresolved active products need manual fallback before they are buyer-visible. type: object properties: totalProducts: type: integer minimum: 0 maximum: 9007199254740991 activeProducts: type: integer minimum: 0 maximum: 9007199254740991 adServerPriced: type: integer minimum: 0 maximum: 9007199254740991 manuallyPriced: type: integer minimum: 0 maximum: 9007199254740991 unresolved: type: integer minimum: 0 maximum: 9007199254740991 draftIgnored: type: integer minimum: 0 maximum: 9007199254740991 byUnresolvedReason: type: object additionalProperties: type: integer minimum: 0 maximum: 9007199254740991 required: - totalProducts - activeProducts - adServerPriced - manuallyPriced - unresolved - draftIgnored - byUnresolvedReason additionalProperties: false IngestModularAvailsFeedBody: description: Previews or upserts avails through the production static-avails-feed:v1 compatibility parser; this is not the target Inventory Feed schema. Every legacy compatibility grouping requires consistent canonical format options and publisher properties, supplied per row or as explicit defaults; its collectionId, collectionName, and collectionDescription fields do not establish AdCP Collection identity. Formats are never inferred from channel. Normalized avails require confirmed=true; rawRows, csvText, and jsonText can be previewed before confirmation. type: object properties: confirmed: type: boolean enum: - true avails: minItems: 1 type: array items: type: object properties: collectionId: description: Exact legacy field name for a static-avails v1 compatibility grouping/container identifier. It does not establish AdCP Collection identity. type: string minLength: 1 collectionName: description: Exact legacy field name for a static-avails v1 compatibility grouping/container label. It does not establish AdCP Collection identity. type: string minLength: 1 collectionDescription: description: Exact legacy field name for a static-avails v1 compatibility grouping/container description. It does not establish AdCP Collection identity. type: - string - 'null' channel: type: - string - 'null' formatOptions: minItems: 1 type: array items: type: object properties: format_option_id: type: string publisher_domain: description: Publisher catalog namespace for format_option_id. Omit for product-local format options. type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_kind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} required: - format_kind - params additionalProperties: false publisherProperties: minItems: 1 type: array items: anyOf: - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - all required: - selection_type additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ selection_type: type: string enum: - by_id property_ids: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - publisher_domain - selection_type - property_ids additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - by_tag property_tags: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - selection_type - property_tags additionalProperties: {} availId: type: string minLength: 1 name: type: string minLength: 1 startTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ impressionsCapacity: type: integer minimum: 0 maximum: 9007199254740991 upstreamBookedImpressions: type: integer minimum: 0 maximum: 9007199254740991 cpm: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 targeting: type: object additionalProperties: {} sourceMetadata: type: object additionalProperties: {} required: - collectionId - collectionName - formatOptions - publisherProperties - availId - name - startTime - endTime - impressionsCapacity rawRows: minItems: 1 type: array items: type: object additionalProperties: {} csvText: type: string minLength: 1 maxLength: 2000000 jsonText: type: string minLength: 1 maxLength: 2000000 defaultCollectionId: description: Fallback for the exact legacy static-avails v1 collectionId field. This compatibility grouping value does not establish AdCP Collection identity. type: string minLength: 1 maxLength: 255 defaultCollectionName: description: Fallback for the exact legacy static-avails v1 collectionName field. This compatibility grouping value does not establish AdCP Collection identity. type: string minLength: 1 maxLength: 255 defaultCollectionDescription: description: Fallback for the exact legacy static-avails v1 collectionDescription field. This compatibility grouping value does not establish AdCP Collection identity. type: string minLength: 1 maxLength: 2000 defaultChannel: type: string minLength: 1 maxLength: 80 defaultFormatOptions: minItems: 1 type: array items: type: object properties: format_option_id: type: string publisher_domain: description: Publisher catalog namespace for format_option_id. Omit for product-local format options. type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_kind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} required: - format_kind - params additionalProperties: false defaultPublisherProperties: minItems: 1 type: array items: anyOf: - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - all required: - selection_type additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ selection_type: type: string enum: - by_id property_ids: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - publisher_domain - selection_type - property_ids additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - by_tag property_tags: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - selection_type - property_tags additionalProperties: {} defaultStartTime: type: string minLength: 1 maxLength: 80 defaultEndTime: type: string minLength: 1 maxLength: 80 InventorySourceContractField: description: Field declared by a modular inventory source contract. type: object properties: key: type: string label: type: string description: type: string source: description: Where a module contract field is expected to come from. type: string enum: - MODULE_CONFIG - INVENTORY_FEED - PRODUCT_METADATA - MEDIA_BUY_INPUT - CREATIVE_INPUT - REPORTING_UPLOAD - SYSTEM - MODULE_RESULT valueType: type: string enum: - STRING - NUMBER - BOOLEAN - DATE - DATETIME - DURATION - ENUM - OBJECT - ARRAY required: type: boolean requiredFor: type: array items: description: Lifecycle stage a modular source module may implement. type: string enum: - LIST_ACCOUNTS - INGEST_AVAILS - SYNC_INVENTORY - GET_PRODUCTS - GET_MEDIA_BUYS - GET_ACCOUNT_RESOURCES - RESERVE_AVAILS - FINALIZE_BOOKING - RELEASE_BOOKING - RECONCILE_DELIVERY - SYNC_CREATIVES - TRAFFIC_CAMPAIGN - UPDATE_CAMPAIGN - SYNC_STATUS - IMPORT_REPORTING mapsTo: type: string enumValues: type: array items: type: string required: - key - label - description - source - valueType - required - requiredFor additionalProperties: false StorefrontApprovalPolicyDecision: description: Policy confidence for storefront approval automation. `definitely_on_policy` is eligible for automatic approval, `definitely_not_on_policy` is a clear policy conflict, and `needs_human_approval` is the safe default for ambiguous or incomplete evidence. type: string enum: - definitely_on_policy - definitely_not_on_policy - needs_human_approval ProposalArtifactListResponse: description: Proposal artifacts for a storefront, newest first. type: object properties: data: type: array items: $ref: '#/components/schemas/ProposalArtifactSummary' meta: $ref: '#/components/schemas/ExchangeArtifactPaginationMeta' required: - data - meta additionalProperties: false BuyerAutoApproveListResponse: description: Per-buyer media-buy auto-approve overrides plus the storefront-scoped buyers eligible for a new override. type: object properties: items: type: array items: $ref: '#/components/schemas/BuyerAutoApproveResponse' total: type: integer minimum: 0 maximum: 9007199254740991 eligibleBuyers: description: Every buyer known to this storefront through submitted media buys. Includes buyers with existing enabled or disabled overrides so clients can reconcile the complete trust roster. type: array items: $ref: '#/components/schemas/BuyerAutoApproveEligibleBuyer' required: - items - total - eligibleBuyers additionalProperties: false CreativeReviewEvaluationResponse: description: Advisory AI evaluation for a storefront creative review row. Evaluation does not approve or reject the creative. type: object properties: creativeId: description: AdCP creative id that was evaluated. example: cr_abc123 type: string evaluatorId: description: Stable evaluator implementation id. Provider-backed evaluators expose the provider here. type: string evaluatorVersion: description: Evaluator implementation version. type: string status: description: Aggregate advisory status from the evaluator. `fail` means one or more checks recommend rejection. type: string enum: - pass - warn - fail recommendation: description: Advisory operator action. This endpoint never records the decision. type: string enum: - approve - manual_review - reject policyDecision: description: Policy confidence for automated creative approval. The safe default is `needs_human_approval` unless the evaluator has enough evidence to decide the creative is definitely on or off policy. allOf: - $ref: '#/components/schemas/StorefrontApprovalPolicyDecision' summary: description: Short evaluator summary. type: string checks: description: Individual policy, brand, readiness, and visual checks supporting the recommendation. type: array items: type: object properties: evaluator_id: type: string minLength: 1 evaluator_version: type: string minLength: 1 category: type: string enum: - readiness - asset - brand_brief - format_seller - policy_safety - performance code: type: string label: type: string stage: type: string enum: - generation - selection - refinement - finalization - adaptation - approval - live_learning - draft - final status: type: string enum: - pass - warn - fail detail: type: string severity: type: string enum: - hard - soft blocking: type: boolean confidence: type: number minimum: 0 maximum: 1 evidence_refs: type: array items: type: string minLength: 1 remediation: type: string maxLength: 1000 required: - label - status - detail additionalProperties: false answers: description: Answers to any requested evaluator questions. type: array items: $ref: '#/components/schemas/CreativeReviewEvaluationAnswer' required: - creativeId - evaluatorId - evaluatorVersion - status - recommendation - policyDecision - summary - checks - answers additionalProperties: false SellingDoctrineAdoptVariant: type: object properties: variant: type: string enum: - premium_scarcity_house - volume_partner - consultative required: - variant additionalProperties: false SellerRecoveryAction: description: 'Which action class applies: retry (transient failure, not terminalized — the platform can re-attempt), force_retry (a source refused the buy and the platform terminalized it, but every leg is a failed unsent one, so an operator can re-send it in place with `forceTerminal`), fix_and_resubmit (correctable input), escalate (nothing the operator can re-send — including a buy terminalized before any source was contacted; escalate to Scope3 with the references attached).' type: string enum: - retry - force_retry - fix_and_resubmit - escalate EsaConnectionList: description: All managed ad-server source connections owned by this storefront. type: array items: $ref: '#/components/schemas/EsaConnection' FinalizeModularInventoryBookingBody: description: Prepares a held modular inventory reservation for the source execution handoff. Cadent sources render Cadent XML; FreeWheel sources create source-side HITL work items. type: object properties: mediaBuyId: type: string minLength: 1 packageId: type: string buyerCustomerId: type: integer maximum: 9007199254740991 minimum: 1 availId: type: string minLength: 1 campaignName: type: string advertiserName: type: string advertiserExternalRef: type: string creative: type: object properties: clientCopyMasterRef: type: string duration: type: string required: - mediaBuyId - buyerCustomerId - availId MediaBuyApprovalEvaluationResponse: description: Brief Acceptance evaluation for a storefront media buy on the manual approval path. Definitely-on-policy buys auto-forward; ambiguous, failed, and hard findings enter the current human-review queue unless an existing per-buyer override bypasses the gate. type: object properties: mediaBuyId: description: Buyer-supplied media buy identifier that was evaluated. type: string evaluatorId: description: Stable evaluator implementation id. type: string evaluatorVersion: description: Evaluator implementation version. type: string policyDecision: description: '`definitely_on_policy` means this buy is eligible under Brief Acceptance. `needs_human_approval` is the safe escalation default. `definitely_not_on_policy` means the payload clearly conflicts with Brief Acceptance and supplies a strong operator-facing rejection signal.' allOf: - $ref: '#/components/schemas/StorefrontApprovalPolicyDecision' recommendation: description: Evaluator recommendation for the manual approval path. `auto_approve` = definitely on policy. `escalate_to_human` = eligibility needs operator review. `auto_reject` = hard deterministic Brief Acceptance violation and strong operator-facing rejection signal. In the current rollout, create_media_buy queues auto_reject findings for human review; LLM conflicts only escalate. type: string enum: - auto_approve - escalate_to_human - auto_reject rejectionReason: description: When `recommendation` is `auto_reject`, an evaluator-generated explanation naming the acceptance-policy terms the buy matched (drawn from the operator's policy). Null otherwise. type: - string - 'null' summary: description: Short evaluator summary. type: string checks: description: Individual policy, advertiser, and quoted-product checks supporting the recommendation. type: array items: type: object properties: evaluator_id: type: string minLength: 1 evaluator_version: type: string minLength: 1 category: type: string enum: - readiness - asset - brand_brief - format_seller - policy_safety - performance code: type: string label: type: string stage: type: string enum: - generation - selection - refinement - finalization - adaptation - approval - live_learning - draft - final status: type: string enum: - pass - warn - fail detail: type: string severity: type: string enum: - hard - soft blocking: type: boolean confidence: type: number minimum: 0 maximum: 1 evidence_refs: type: array items: type: string minLength: 1 remediation: type: string maxLength: 1000 required: - label - status - detail additionalProperties: false required: - mediaBuyId - evaluatorId - evaluatorVersion - policyDecision - recommendation - rejectionReason - summary - checks additionalProperties: false ComplianceTrackResult: description: Result for a single compliance track type: object properties: track: description: Compliance track name type: string status: description: Track assessment result. 'silent' means the track was wired but observation-based assertions saw zero resources — distinct from 'pass' (verified) and 'skip' (didn't run). type: string enum: - pass - fail - skip - partial - silent label: description: Human-readable track label type: string durationMs: description: Track duration in ms type: number failureReason: description: Why this track failed or partially passed type: string required: - track - status - label - durationMs additionalProperties: false SellerPayloadHighlights: description: 'Trafficker-grade highlights extracted from the forwarded payload: flight, budget, packages, targeting dimensions.' type: object properties: flightStart: type: - string - 'null' flightEnd: type: - string - 'null' budget: type: - number - 'null' currency: type: - string - 'null' packageCount: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 productIds: description: Product ids referenced by the packages (first 20). type: array items: type: string targetingKeys: description: Top-level targeting dimensions present in the request (keys only). type: array items: type: string required: - flightStart - flightEnd - budget - currency - packageCount - productIds - targetingKeys additionalProperties: false SellerAccountGrantReviewDecision: type: object properties: account_id: type: string brand: type: object properties: domain: type: string required: - domain additionalProperties: false operator: type: string name: type: string action: type: string enum: - created - updated - unchanged status: type: string account_scope: type: string enum: - operator_brand billing: type: string billing_entity: type: object additionalProperties: {} setup: type: object properties: url: type: string format: uri message: type: string expires_at: type: string required: - message additionalProperties: false warnings: type: array items: type: string sandbox: type: boolean required: - account_id - brand - operator - name - action - status - account_scope additionalProperties: false CreativeReviewDecisionStatus: description: Terminal statuses an operator can set via the decide endpoint. `revoked` is handled separately and is not a valid decide-time value. type: string enum: - approved - rejected UpdateBuyerInstructionsBody: description: Partial update for a buyer-instructions row. Scope (operatorDomain, brandDomain) is immutable — delete and recreate to change it. type: object properties: discountPercent: description: Discount percent off the storefront base price. 0–100. Resolver picks MAX across all matching rows — adding a brand-specific row only wins by being a better deal. example: 15 type: - number - 'null' minimum: 0 maximum: 100 notes: type: - string - 'null' maxLength: 2000 countries: description: ISO 3166-1 alpha-2 country codes (uppercase). Row applies only when the buy targets one of these countries. Omit (or send null) for a global row. example: - US - CA minItems: 1 type: - array - 'null' items: type: string pattern: ^[A-Z]{2}$ HouseDiscountResponse: description: A single house-scoped buyer-discount row. type: object properties: id: description: Surrogate id (BIGINT serialized as string). example: '17' type: string storefrontId: description: Storefront the row belongs to (BIGINT serialized as string). example: '1234' type: string houseDomain: type: string scope: description: 'Which buyer axis this discount applies to: `brand` matches the buy''s advertiser brand (and its corporate parents/house), `operator` matches the buying operator (agency/DSP, and its parents/house). When both a brand and an operator discount match a buy, the larger applies (a tie resolves to the brand axis).' example: brand type: string enum: - brand - operator discountPercent: type: number notes: type: - string - 'null' createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdBy: type: - string - 'null' required: - id - storefrontId - houseDomain - scope - discountPercent - notes - createdAt - updatedAt - createdBy additionalProperties: false EsaTenantStatus: description: 'Operational snapshot of a managed ad-server source: adapter health, sync state, workflows, packages, creatives, webhook stats.' type: object properties: operational: $ref: '#/components/schemas/EsaOperationalStatus' wholesalePricingMode: description: Legacy source-level pricing preference. Inspect syncs.pricingAvailability.coverageSummary for effective per-product coverage. allOf: - $ref: '#/components/schemas/EsaWholesalePricingMode' adapter: type: object properties: type: type: string connected: type: boolean lastTestedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastTestError: type: - string - 'null' required: - type - connected - lastTestedAt - lastTestError additionalProperties: false syncs: type: object properties: inventory: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false customTargeting: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false advertisers: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false reporting: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false signalCoverage: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false pricingAvailability: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false coverageSummary: allOf: - $ref: '#/components/schemas/EsaPricingCoverageSummary' required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false required: - inventory additionalProperties: type: object properties: status: type: string severity: default: ok anyOf: - type: string enum: - ok - warning - critical - type: string lastSuccessAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: default: null type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false lastRunAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastStartedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: default: null type: - string - 'null' history: default: recentRunCount: 0 recentFailureCount: 0 consecutiveFailureCount: 0 latestFailureAt: null latestError: null type: object properties: recentRunCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 recentFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 consecutiveFailureCount: default: 0 type: integer minimum: 0 maximum: 9007199254740991 latestFailureAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ latestError: default: null type: - string - 'null' recentRuns: type: array items: $ref: '#/components/schemas/EsaSyncHistoryRun' required: - recentRunCount - recentFailureCount - consecutiveFailureCount - latestFailureAt - latestError additionalProperties: false required: - status - severity - lastSuccessAt - issue - lastRunAt - lastStartedAt - itemCount - error - history additionalProperties: false workflows: type: object properties: openCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 oldestOpenedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ byKind: type: object additionalProperties: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - openCount - oldestOpenedAt - byKind additionalProperties: false packages: type: object properties: activeCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 pausedCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 last24hImpressions: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - activeCount - pausedCount - last24hImpressions additionalProperties: false creatives: type: object properties: activeCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 pendingReviewCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 rejectedLast24hCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - activeCount - pendingReviewCount - rejectedLast24hCount additionalProperties: false products: description: Sellable wholesale-product rollup. Optional for backward compatibility with upstream builds before the rollup shipped. type: object properties: activeCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 draftCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - activeCount - draftCount - archivedCount additionalProperties: false inventoryProfiles: description: Reusable inventory-profile ingredient rollup from the managed source. Separate from products, which counts sellable wholesale products. type: object properties: totalCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 completeCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 incompleteCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 wholesaleOwnedCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - totalCount - completeCount - incompleteCount - wholesaleOwnedCount additionalProperties: false webhooks: type: - object - 'null' properties: last24h: type: object properties: delivered: type: integer minimum: -9007199254740991 maximum: 9007199254740991 failed: type: integer minimum: -9007199254740991 maximum: 9007199254740991 successRate: type: number required: - delivered - failed - successRate additionalProperties: false lastFailureAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - last24h - lastFailureAt additionalProperties: false catalog: description: Local view of whether managed-source product/signal catalog webhooks are landing and refreshing buyer discovery caches. type: object properties: sourceCount: type: integer minimum: 0 maximum: 9007199254740991 sources: type: array items: type: object properties: storefrontId: type: string storefrontPlatformId: type: - string - 'null' storefrontName: type: - string - 'null' sourceId: type: string sourceName: type: - string - 'null' required: - storefrontId - storefrontPlatformId - storefrontName - sourceId - sourceName additionalProperties: false products: description: Local storefront catalog cache and webhook freshness for one AdCP 3.1 catalog bucket. type: object properties: bucket: type: string enum: - WHOLESALE_PRODUCTS - SIGNALS status: type: string enum: - ok - error - unsupported - missing - mixed - no_source cachedItemCount: type: integer minimum: 0 maximum: 9007199254740991 sourceCount: type: integer minimum: 0 maximum: 9007199254740991 okSourceCount: type: integer minimum: 0 maximum: 9007199254740991 errorSourceCount: type: integer minimum: 0 maximum: 9007199254740991 unsupportedSourceCount: type: integer minimum: 0 maximum: 9007199254740991 missingSourceCount: type: integer minimum: 0 maximum: 9007199254740991 accountKeyCount: type: integer minimum: 0 maximum: 9007199254740991 lastFetchedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastWebhookAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ oldestFetchedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ softExpired: type: boolean hardExpired: type: boolean errorCode: type: - string - 'null' errorMessage: type: - string - 'null' cacheScope: type: - string - 'null' enum: - public - account wholesaleFeedVersion: type: - string - 'null' pricingVersion: type: - string - 'null' required: - bucket - status - cachedItemCount - sourceCount - okSourceCount - errorSourceCount - unsupportedSourceCount - missingSourceCount - accountKeyCount - lastFetchedAt - lastWebhookAt - oldestFetchedAt - softExpired - hardExpired - errorCode - errorMessage - cacheScope - wholesaleFeedVersion - pricingVersion additionalProperties: false signals: description: Local storefront catalog cache and webhook freshness for one AdCP 3.1 catalog bucket. type: object properties: bucket: type: string enum: - WHOLESALE_PRODUCTS - SIGNALS status: type: string enum: - ok - error - unsupported - missing - mixed - no_source cachedItemCount: type: integer minimum: 0 maximum: 9007199254740991 sourceCount: type: integer minimum: 0 maximum: 9007199254740991 okSourceCount: type: integer minimum: 0 maximum: 9007199254740991 errorSourceCount: type: integer minimum: 0 maximum: 9007199254740991 unsupportedSourceCount: type: integer minimum: 0 maximum: 9007199254740991 missingSourceCount: type: integer minimum: 0 maximum: 9007199254740991 accountKeyCount: type: integer minimum: 0 maximum: 9007199254740991 lastFetchedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ lastWebhookAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ oldestFetchedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ softExpired: type: boolean hardExpired: type: boolean errorCode: type: - string - 'null' errorMessage: type: - string - 'null' cacheScope: type: - string - 'null' enum: - public - account wholesaleFeedVersion: type: - string - 'null' pricingVersion: type: - string - 'null' required: - bucket - status - cachedItemCount - sourceCount - okSourceCount - errorSourceCount - unsupportedSourceCount - missingSourceCount - accountKeyCount - lastFetchedAt - lastWebhookAt - oldestFetchedAt - softExpired - hardExpired - errorCode - errorMessage - cacheScope - wholesaleFeedVersion - pricingVersion additionalProperties: false required: - sourceCount - sources - products - signals additionalProperties: false setupTasks: allOf: - $ref: '#/components/schemas/EsaSetupTasksBlock' capabilities: description: Durable state for separately provisioned ad-server capabilities. A capability awaiting vendor permission remains paused until explicitly re-checked. type: object properties: reporting: type: object properties: state: type: string enum: - unknown - available - awaiting_vendor_permission checkedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false required: - state - checkedAt - issue additionalProperties: false forecasting: type: object properties: state: type: string enum: - unknown - available - awaiting_vendor_permission checkedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false required: - state - checkedAt - issue additionalProperties: false additionalProperties: type: object properties: state: type: string enum: - unknown - available - awaiting_vendor_permission checkedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issue: type: - object - 'null' properties: code: type: string category: type: string message: type: string retryable: type: boolean action: type: - string - 'null' capability: type: - string - 'null' required: - code - category - message - retryable additionalProperties: false required: - state - checkedAt - issue additionalProperties: false diagnoses: description: Typed ad-server-scoped source-health diagnoses (sync + catalog failure modes), computed by the same rules as readiness `diagnoses`. Only `seller`-owned entries are tasks; `scope3`/`vendor`-owned entries are informational. type: array items: $ref: '#/components/schemas/SourceHealthDiagnosis' fetchedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - operational - adapter - syncs - workflows - packages - creatives - webhooks - fetchedAt additionalProperties: false RetryForwardMediaBuyResponse: description: An approval-queue entry returned from a retry-forward attempt, carrying the outcome of the dispatch when one ran. type: object properties: id: description: Surrogate id of the approval row (BIGINT serialized as string). example: '42' type: string kind: description: Approval workstream kind. `create` is an initial create_media_buy approval; `update` is a material update_media_buy approval for an already-created buy. default: create type: string enum: - create - update storefrontId: description: Storefront the pending buy was submitted to (BIGINT serialized as string). example: '1234' type: string mediaBuyId: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). Unique per storefront — re-submitting the same id is idempotent. type: string buyerCustomerId: description: Customer id of the buyer who submitted the media buy. type: integer minimum: -9007199254740991 maximum: 9007199254740991 submittedPayload: description: Raw AdCP `create_media_buy` payload as the buyer submitted it, with buyer webhook credentials (`push_notification_config` / `pushNotificationConfig`) removed before it reaches operator-facing responses. Not normalized — the operator UI renders a summary directly from this object. status: description: Lifecycle state. `pending` until the operator decides; `approved` once the operator accepts (forwarding upstream happens out-of-band and is reflected by `forwardedAt`); `rejected` when the operator declines; `revoked` for buyer- or system-initiated cancellation after a decision. type: string enum: - pending - approved - rejected - revoked reviewedBy: description: User id of the operator who recorded the decision (BIGINT serialized as string). Null while pending. type: - string - 'null' reviewedAt: description: When the operator decision was recorded (ISO 8601). Null while pending. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ reviewerNotes: description: Operator note attached to the decision. Null while pending. type: - string - 'null' forwardedAt: description: 'When forwarding to the underlying sales agent settled (ISO 8601) — stamped both when every source accepted the buy and when the forward was terminalized, because the stamp is also what stops the background worker re-attempting a dead forward. Null means the forward has not been attempted or is still in flight. Read it with the per-source legs to tell a delivered buy from a refused one: a delivered buy carries an `upstreamMediaBuyId`.' type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdAt: description: When the buyer submitted the media buy (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: description: When the row was last modified — submission, decision, or forwarding stamp (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ forwardOutcome: description: Result of the dispatch this call triggered. `deferred` means the retry was accepted and is running asynchronously — poll `GET /media-buy-approvals/{mediaBuyId}` for the settled result. Absent when no dispatch ran. type: string enum: - deferred - all_completed - all_submitted - partial - all_failed - precondition_failed forwardResult: description: Per-source forwarding legs for this dispatch. Empty while `forwardOutcome` is `deferred`. type: array items: $ref: '#/components/schemas/SourceForwardResult' required: - id - kind - storefrontId - mediaBuyId - buyerCustomerId - submittedPayload - status - reviewedBy - reviewedAt - reviewerNotes - forwardedAt - createdAt - updatedAt additionalProperties: false AcceptancePolicyListResponse: description: List of acceptance-policy versions for a storefront. type: object properties: items: description: Acceptance-policy versions for this storefront. type: array items: $ref: '#/components/schemas/AcceptancePolicyResponse' total: description: Total number of versions authored for this storefront. type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false ProposalArtifact: description: 'The canonical outbound proposal: exact response envelope + immutable product snapshots, with brief/run lineage.' type: object properties: id: type: string storefrontId: type: string buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 briefArtifactId: description: The brief artifact this proposal answered; null when the brief capture failed (the link is soft and never invented). type: - string - 'null' chefComposeRunId: description: The intelligence run that composed this proposal; null when the run record failed. type: - string - 'null' version: type: integer minimum: -9007199254740991 maximum: 9007199254740991 supersedesArtifactId: type: - string - 'null' schemaVersion: type: string redactionManifest: $ref: '#/components/schemas/ExchangeArtifactRedactionManifest' digest: type: string byteSize: type: integer minimum: -9007199254740991 maximum: 9007199254740991 complete: type: boolean createdAt: type: string response: description: The exact response envelope the buyer received; null when complete=false. productSnapshots: description: Resolved immutable product snapshots keyed by product id; null when complete=false. required: - id - storefrontId - buyerCustomerId - briefArtifactId - chefComposeRunId - version - supersedesArtifactId - schemaVersion - redactionManifest - digest - byteSize - complete - createdAt - response - productSnapshots additionalProperties: false CatalogMappingReadiness: description: Tenant-scoped, read-only per-source catalog-mapping readiness derived from existing owners. type: object properties: sections: type: array items: type: object properties: id: type: string enum: - SET_UP_INVENTORY - MAKE_IT_MERCHANDISABLE - PROVE_IT title: type: string enum: - Set up inventory - Make it merchandisable - Prove it rows: type: array items: type: object properties: id: type: string title: type: string requirement: type: string enum: - REQUIRED - RECOMMENDED - NOT_APPLICABLE status: description: Null means Unknown because no-value is not a state. type: - string - 'null' enum: - NOT_STARTED - IN_PROGRESS - READY - NEEDS_ATTENTION - BLOCKED evidence: type: array items: type: object properties: code: type: string summary: type: string value: anyOf: - type: string - type: number - type: boolean observedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - code - summary - observedAt additionalProperties: false freshness: type: object properties: state: type: string enum: - FRESH - STALE - UNAVAILABLE observedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - state - observedAt additionalProperties: false sourceOfTruth: type: string enum: - INVENTORY_SOURCE - INVENTORY_FEED - PROPERTY_ROSTER - INVENTORY_COMPONENTS - PRODUCT_CATALOG - PRICING - PLAYBOOK - BUSINESS_RULES - DECISIONING_INPUTS - SOURCE_PROOF action: allOf: - $ref: '#/components/schemas/CatalogMappingAction' externalOwner: type: - string - 'null' enum: - PUBLISHER - SCOPE3 - VENDOR diagnostics: type: array items: type: object properties: code: type: string message: type: string required: - code - message additionalProperties: false required: - id - title - requirement - status - evidence - freshness - sourceOfTruth - action - externalOwner - diagnostics additionalProperties: false required: - id - title - rows additionalProperties: false progress: type: object properties: ready: type: integer minimum: 0 maximum: 9007199254740991 applicable: type: integer minimum: 0 maximum: 9007199254740991 percent: type: integer minimum: 0 maximum: 100 required: - ready - applicable - percent additionalProperties: false nextAction: allOf: - $ref: '#/components/schemas/CatalogMappingAction' required: - sections - progress - nextAction additionalProperties: false EsaSetupTasksBlock: description: Configuration-completeness rollup from the upstream managed-source status. Storefront merges these with its own platform-managed task list. type: object properties: blockerCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 warningCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 items: type: array items: $ref: '#/components/schemas/EsaSetupTaskItem' required: - blockerCount - warningCount - items additionalProperties: false SellerAccountBindingFeedCommitResult: type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ state: type: string enum: - committed idempotentReplay: type: boolean committedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ impact: type: object properties: createCount: type: integer minimum: 0 maximum: 9007199254740991 updateCount: type: integer minimum: 0 maximum: 9007199254740991 archiveCount: type: integer minimum: 0 maximum: 9007199254740991 unchangedCount: type: integer minimum: 0 maximum: 9007199254740991 quarantineCount: type: integer minimum: 0 maximum: 9007199254740991 duplicateCount: type: integer minimum: 0 maximum: 9007199254740991 snapshotAbsenceArchiveCount: type: integer minimum: 0 maximum: 9007199254740991 required: - createCount - updateCount - archiveCount - unchangedCount - quarantineCount - duplicateCount - snapshotAbsenceArchiveCount additionalProperties: false required: - feedId - revisionId - state - idempotentReplay - committedAt - impact additionalProperties: false BuyerInstructionsResponse: description: A single buyer-instructions row. type: object properties: id: description: Surrogate id (BIGINT serialized as string). example: '17' type: string storefrontId: description: Storefront the row belongs to (BIGINT serialized as string). example: '1234' type: string operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' discountPercent: type: - number - 'null' notes: type: - string - 'null' countries: type: - array - 'null' items: type: string createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdBy: type: - string - 'null' required: - id - storefrontId - operatorDomain - brandDomain - discountPercent - notes - countries - createdAt - updatedAt - createdBy additionalProperties: false ResolveBrandResponse: type: object properties: resolved: description: Whether a brand profile was found type: boolean domain: type: string brandName: type: string logoUrl: type: - string - 'null' logoBackground: description: Hint for the logo background (e.g. light/dark), when known type: - string - 'null' manifestUrl: type: string manifest: type: object additionalProperties: {} registryEntry: type: - object - 'null' additionalProperties: {} authorizedOperators: type: array items: type: object additionalProperties: {} houseBrand: type: boolean warning: type: string error: type: string builderUrl: description: Set when resolved is false -- URL where the caller can register a manifest type: string required: - resolved - domain additionalProperties: false DemandExchangeGrouping: type: object properties: basis: description: 'The persisted linkage the exchange is grouped on: a single compose run and its proposal artifacts.' type: string enum: - compose_run passCount: type: integer minimum: -9007199254740991 maximum: 9007199254740991 multiPass: type: boolean note: description: Human-readable disclosure of the grouping honesty (e.g. that refine passes are not yet rolled up because no persisted cross-run lineage exists). type: string required: - basis - passCount - multiPass - note additionalProperties: false InventorySourceModuleRuntimeProjection: description: Runtime setup state for one module on a modular inventory source. type: object properties: moduleRowId: type: string inventorySourceId: type: string moduleInstanceId: type: string kind: description: Role a module plays inside a modular inventory source. type: string enum: - INVENTORY_FEED - BOOKING_LEDGER - TRAFFICKING - STATUS_SYNC - REPORTING_IMPORT name: type: string provider: type: - string - 'null' status: description: Operator-facing module lifecycle status. type: string enum: - CONFIGURING - ACTIVE - DISABLED - ERROR contractId: type: - string - 'null' contractVersion: type: - string - 'null' contract: allOf: - $ref: '#/components/schemas/InventorySourceModuleContractSummary' configuredFieldKeys: type: array items: type: string missingSetupFieldsBySource: type: array items: $ref: '#/components/schemas/InventorySourceContractFieldGroup' lifecycle: type: array items: $ref: '#/components/schemas/InventorySourceLifecycleProjection' openWorkItemCount: type: integer minimum: 0 maximum: 9007199254740991 openWorkItemCountsByKind: type: object additionalProperties: type: integer minimum: 0 maximum: 9007199254740991 lastError: type: - string - 'null' lastCheckedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ issues: type: array items: type: string required: - moduleRowId - inventorySourceId - moduleInstanceId - kind - name - provider - status - contractId - contractVersion - contract - configuredFieldKeys - missingSetupFieldsBySource - lifecycle - openWorkItemCount - openWorkItemCountsByKind - lastError - lastCheckedAt - issues additionalProperties: false IntelligenceRunListResponse: description: List of intelligence runs for a storefront. type: object properties: items: type: array items: $ref: '#/components/schemas/IntelligenceRunResponse' total: type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false FeedUploadBody: description: Multipart form-data body for POST /inventory-sources/:sourceId/feed/upload. Send the feed file as the `file` part and the remaining fields as form text fields. For deterministic replay, provide idempotencyKey, revisionId, and observedAt together; otherwise omit all three. type: object properties: file: format: binary description: CSV, JSON, XLS, or XLSX file up to 10 MB. Provide as the `file` multipart part. type: string contractId: $ref: '#/components/schemas/FeedContractId' idempotencyKey: description: Deterministic replay idempotency key (UUID). Provide only together with revisionId and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: description: Deterministic replay revision id (UUID). Provide only together with idempotencyKey and observedAt; omit all three fields for server-generated, non-retryable convenience values. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ observedAt: description: ISO-8601 observation timestamp for deterministic replay. Provide only together with idempotencyKey and revisionId; omit all three fields to default to the current time. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - file - contractId EsaOperationalStatus: description: Derived private uptime-style state for a managed ad-server source. Local provisioning state is lifecycle bookkeeping; this status is computed from upstream status at read time. type: object properties: isLive: description: Whether this managed source has passed setup and has products available to buyers. type: boolean discoveryDegraded: description: Whether buyer discovery/proposal request flows appear degraded. False when the source is not live yet. type: boolean deliveryDegraded: description: Whether campaign execution/reporting flows appear degraded. Does not expose whether any campaigns are currently running. type: boolean summary: type: string issues: type: array items: $ref: '#/components/schemas/EsaOperationalIssue' required: - isLive - discoveryDegraded - deliveryDegraded - summary - issues additionalProperties: false CreateHouseDiscountBody: description: Request body for creating a rate-card discount on the brand or operator axis. (house_domain, scope) is unique per storefront — a duplicate fails with a conflict; use PATCH to update it. type: object properties: houseDomain: description: Lowercase buyer-entity domain the discount is keyed to (e.g. "nike.com" for a brand, "wpp.com" for an operator). A buy matches this row when its brand (scope=brand) or operator (scope=operator) resolves up its hierarchy to this domain — so a brand discount on "nike.com" applies to a converse.com buy. example: nike.com type: string minLength: 1 maxLength: 253 scope: description: 'Which buyer axis this discount applies to: `brand` matches the buy''s advertiser brand (and its corporate parents/house), `operator` matches the buying operator (agency/DSP, and its parents/house). When both a brand and an operator discount match a buy, the larger applies (a tie resolves to the brand axis).' example: brand type: string enum: - brand - operator discountPercent: description: Discount percent off the storefront quote for buys whose brand or operator resolves to this domain. 0–100. The larger of this and any buyer-specific instruction wins; the quote is floored at the wholesale cost. example: 20 type: number minimum: 0 maximum: 100 notes: description: Freeform operator notes for this discount (e.g. "Negotiated 2026 Nike-house rate"). Null = no notes. type: - string - 'null' maxLength: 2000 required: - houseDomain - scope - discountPercent - notes InventorySourceResponse: description: Inventory source response type: object properties: id: description: Globally unique surrogate id (BIGINT serialized as string). Use this when acting on rows the caller does not own (e.g. a seller approving an inbound link). type: string sourceId: description: Storefront-scoped identifier — unique within the row owner's storefront. Use this for actions on the caller's own rows; use `id` for cross-customer actions. type: string name: description: Display name type: string executionType: description: Execution type type: string enum: - AGENT - MANAGED_SALES_AGENT - LINKED_STOREFRONT - MODULAR_SOURCE connectionType: description: Public connection family for a preconfigured ad-server source. Omitted for other inventory-source families. type: string enum: - AD_SERVER adServerProvider: description: Ad-server provider for a preconfigured ad-server source. Omitted for other inventory-source families. type: string enum: - citrusad status: description: Source lifecycle status type: string enum: - PENDING - ACTIVE - DISABLED agentId: description: Linked agent ID (when executionType is agent) type: - string - 'null' type: description: Agent type type: - string - 'null' enum: - SALES - SIGNAL - CREATIVE - OUTCOME endpointUrl: description: Agent endpoint URL type: - string - 'null' protocol: description: Agent protocol type: - string - 'null' enum: - MCP - A2A description: description: Agent description type: - string - 'null' authenticationType: description: Agent authentication type type: - string - 'null' enum: - API_KEY - NO_AUTH - JWT - OAUTH - BASIC_AUTH authConfigured: description: Whether the agent has authentication configured type: boolean oauth: description: OAuth authorization info (for OAUTH agents) type: object properties: authorizationUrl: type: string agentId: type: string agentName: type: string required: - authorizationUrl - agentId - agentName additionalProperties: false managedSa: description: Embedded-sales-agent state when `executionType` is `MANAGED_SALES_AGENT`. Null/absent for external `AGENT`-type sources. The current REST surface (`/api/v2/storefront/esa/...`) remains the way to mutate this state today; subsequent PRs will move those actions under `/api/v2/storefront/inventory-sources/:sourceId/...`. allOf: - $ref: '#/components/schemas/ManagedSalesAgentSummary' linkedStorefront: description: 'Always null. Storefront interchange runs through the ambient wholesale pool: a curator discovers any LISTED storefront’s wholesale inventory automatically, with no per-counterparty link to establish. Retained for response-shape stability.' allOf: - $ref: '#/components/schemas/LinkedStorefrontSummary' reportingType: description: How the underlying agent reports delivery (`WEBHOOK`, `BUCKET`, `POLLING`). Mirrors the AdCP-spec values used when connecting the source. Projected from `storefront_agent_source`; null for non-AGENT sources. type: - string - 'null' enum: - WEBHOOK - BUCKET - POLLING reportingPollingCadence: description: Polling cadence (`DAILY`, `MONTHLY`) — only meaningful when `reportingType` is `POLLING`. Projected from `storefront_agent_source`; null for non-AGENT sources or non-polling reporting. type: - string - 'null' enum: - DAILY - MONTHLY isAdapterSource: description: True when this source is routed through an official Scope3-hosted adapter (storefront routing_mode is ADAPTER and the source_id matches the configured adapter). When true, the UI labels this as an official adapter rather than a generic external sales agent. type: boolean agentCapabilityUid: description: Explicit reusable SALES Agent capability connected to this Source. Null means the Source requires governed connection reconciliation; endpoint similarity is never used. type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ declaredAgentProductMode: description: The backing Agent completeness contract. Managed ESA and initial modular Sources project their fixed WHOLESALE contract. type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH bindingProductMode: description: Source product-path selection only when the Agent declares BOTH; null for single-mode Agents. type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH effectiveProductMode: description: Effective mode for new discovery. Null when the explicit Agent connection or declaration is unresolved. type: - string - 'null' enum: - WHOLESALE - COMPOSING - BOTH productModeReasons: description: Bounded reconciliation reasons when effective mode cannot be resolved. type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY productPaths: description: Readiness for the Agent-supplied and Storefront-built product paths. BOTH exposes both entries; neither path silently replaces the other. type: array items: type: object properties: path: type: string enum: - WHOLESALE - COMPOSING ready: type: boolean reasons: type: array items: type: string enum: - SOURCE_NOT_ACTIVE - AGENT_BINDING_MISSING - AGENT_MODE_UNDECLARED - BOTH_SELECTION_REQUIRED - MERCHANDISING_ACCESS_INACTIVE - WHOLESALE_CATALOG_NOT_READY required: - path - ready - reasons additionalProperties: false createdAt: description: Creation timestamp (ISO 8601) type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: description: Last update timestamp (ISO 8601) type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - sourceId - name - executionType - status - agentId - createdAt - updatedAt additionalProperties: false MerchandisingSimulationJsonValue: description: Any JSON value captured verbatim in simulation evidence. anyOf: - type: string - type: number - type: boolean - type: - string - 'null' enum: - null - type: array items: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' - type: object additionalProperties: $ref: '#/components/schemas/MerchandisingSimulationJsonValue' OnboardingPlanStep: type: object properties: completedAt: description: ISO timestamp the step was first observed complete. type: string owner: description: Who completed / owns the step. `null` when observed by the system rather than assigned; set when a person or Murph records it. type: - string - 'null' required: - completedAt - owner additionalProperties: false CreativeReviewListResponse: description: List response for the operator creative review queue endpoint. type: object properties: items: description: Creative review rows, newest first. Default scope is `status = pending`; pass `?status=` to filter. type: array items: $ref: '#/components/schemas/CreativeReviewResponse' total: description: Number of rows in the current filtered view. type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false StorefrontPublisherDomainReadiness: description: One configured publisher domain with its latest AAO/adagents.json authorization and managed-sales-agent synchronization evidence. type: object properties: publisherDomain: type: string status: description: Seller-facing publisher-domain readiness. `pending` has not completed a resolution, `authorized` has current positive authorization evidence, `unauthorized` is a confident negative, `unknown` has no conclusive authorization evidence, and `error` means the latest adagents.json resolution failed. type: string enum: - pending - authorized - unauthorized - unknown - error adagentsStatus: type: - string - 'null' enum: - resolved - no_adagents - invalid - error - pending authorizationStatus: type: - string - 'null' enum: - authorized - unauthorized - unknown authorizationReason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized resolvedPropertyCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 lastSyncedAt: type: - string - 'null' lastPushedAt: type: - string - 'null' required: - publisherDomain - status - adagentsStatus - authorizationStatus - authorizationReason - resolvedPropertyCount - lastSyncedAt - lastPushedAt additionalProperties: false InventorySourceWorkItemsResponse: type: object properties: items: type: array items: $ref: '#/components/schemas/InventorySourceWorkItemSummary' total: type: integer minimum: 0 maximum: 9007199254740991 scanned: description: Rows matched before storefront approval kinds were filtered out. Always greater than or equal to `total`. type: integer minimum: 0 maximum: 9007199254740991 windowFull: description: True when `scanned` reached the effective limit, so more work items may exist past this page. A short `items` list is then a floor, not a complete queue — narrow by status or kind to see the rest. type: boolean required: - items - total - scanned - windowFull additionalProperties: false CreateCitrusAdModularSourceBody: description: Connects CitrusAd using the standard sponsored-products composition. API credentials are stored separately through the CitrusAd ad-server credential endpoint. type: object properties: sourceId: type: string minLength: 1 maxLength: 255 pattern: ^[a-z0-9][a-z0-9_-]*$ name: type: string minLength: 1 maxLength: 255 environment: type: string enum: - sandbox - production teamId: type: string minLength: 1 maxLength: 255 namespaces: minItems: 1 type: array items: type: object properties: namespace: type: string minLength: 1 maxLength: 255 retailerName: type: string minLength: 1 maxLength: 255 publisherDomain: type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ required: - namespace - retailerName - publisherDomain defaultCurrency: type: string pattern: ^[A-Za-z]{3}$ floorPrice: type: number minimum: 0 required: - environment - teamId - namespaces - defaultCurrency EsaServiceAccountResponse: type: object properties: serviceAccountEmail: description: The platform service account email, or null when provisioning is not applicable. type: - string - 'null' required: - serviceAccountEmail additionalProperties: false SellerTimelineStageName: description: 'Lifecycle stage of a buy exchange as seen from the storefront: received → screened → decided → forwarded / forward-failed → submitted → source moderation → accepted / rejected → delivering. Update exchanges reuse the same stages. `screened` is RESERVED for the acceptance-policy pre-screen record and is not emitted today — do not wait for it.' type: string enum: - received - screened - decided - forwarded - forward_failed - submitted - source_moderation - accepted - rejected - delivering EsaSyncHistoryRun: description: One historical sync run from the managed ad-server source. type: object properties: syncId: type: string syncType: type: string startedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ completedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ status: type: string durationSeconds: default: null type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 itemsProcessed: default: 0 type: integer minimum: -9007199254740991 maximum: 9007199254740991 itemsFailed: default: 0 type: integer minimum: -9007199254740991 maximum: 9007199254740991 errorSummary: default: null type: - string - 'null' errorCategory: default: null type: - string - 'null' required: - syncId - syncType - startedAt - completedAt - status - durationSeconds - itemsProcessed - itemsFailed - errorSummary - errorCategory additionalProperties: false CreateStorefrontBody: description: Request body for creating a storefront type: object properties: name: description: Display name for the storefront example: Acme Media type: string minLength: 1 maxLength: 255 publisherDomain: description: The storefront's primary publisher domain — the identity buyers and partners look the storefront up by, and the join key that ties its inventory to buyer demand. Optional at creation (third-party sales agents' domains arrive via the product pass-through), but a storefront cannot go live without domain identity. Manage the full publisher-domain set via businessProfile.publisherDomains. example: acme.com type: string minLength: 1 maxLength: 255 operatorDomain: description: Canonical operator domain for this storefront. May differ from the account customerDomain when the storefront operates as a specific brand or managed seller. example: acme.com type: string minLength: 1 maxLength: 255 defaultCurrency: description: Seller-confirmed primary settlement currency (ISO-4217). Required before go-live for Interchange-cleared storefronts; never defaulted silently. Direct sales adapter storefronts run by our expert agents skip settlement-currency readiness checks because Interchange does not pay the seller on that path. example: EUR type: string pattern: ^[A-Z]{3}$ paymentCurrencies: description: ISO-4217 currencies this storefront will be paid in. The primary defaultCurrency must be included when both are provided. Empty falls back to defaultCurrency. example: - USD - GBP maxItems: 25 type: array items: type: string pattern: ^[A-Z]{3}$ acceptedCountries: description: Buyer-visible ISO country coverage for a managed storefront. Pass-through storefronts project country coverage from each source’s standard media_buy.portfolio.primary_countries. example: - FR minItems: 1 maxItems: 249 type: array items: type: string pattern: ^[A-Z]{2}$ acceptsAllCountries: description: Set true to explicitly accept briefs from every country. Mutually exclusive with acceptedCountries. type: boolean plan: description: Storefront plan tier default: basic type: string enum: - basic required: - name StorefrontMediaBuyListResponse: description: Every buy on the storefront — the union of routed and source-managed buys — urgency-sorted by default. type: object properties: items: type: array items: $ref: '#/components/schemas/StorefrontMediaBuySummary' total: description: Total rows matching the filters (before pagination). type: integer minimum: 0 maximum: 9007199254740991 warnings: description: Non-fatal data-source problems (e.g. an upstream source that could not be reached). Empty when every source answered. type: array items: type: string statusFreshness: description: Non-null when this storefront routes buys through an ad-platform connection whose status sync has been failing long enough that displayed statuses may be out of date. Null when statuses are current (or the storefront has no such connection). type: - object - 'null' properties: lastConfirmedAt: description: When statuses were last successfully confirmed with the ad platform. Null when no sync has ever succeeded. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ hoursSinceConfirmed: description: Whole hours since the last successful status sync. Null when no sync has ever succeeded. type: - integer - 'null' minimum: 0 maximum: 9007199254740991 message: description: Seller-facing staleness note, e.g. "status last confirmed 5h ago — source unreachable". type: string required: - lastConfirmedAt - hoursSinceConfirmed - message additionalProperties: false required: - items - total - warnings - statusFreshness additionalProperties: false DecideSellerAccountGrantReviewBody: description: Approve a buyer account into an existing seller-native ad-server record (link_existing, with operator- or advertiser-cleared billing and the seller-declared billing_entity for that invoice recipient), approve it into Interchange-cleared billing (approve_interchange), or reject it with a reason (reject). oneOf: - type: object properties: expectedVersion: type: integer maximum: 9007199254740991 minimum: 1 decision: type: string enum: - approve_interchange message: type: string minLength: 1 maxLength: 1000 required: - expectedVersion - decision additionalProperties: false - type: object properties: expectedVersion: type: integer maximum: 9007199254740991 minimum: 1 decision: type: string enum: - link_existing billing: type: string enum: - operator - advertiser billingEntity: type: object properties: legal_name: type: string maxLength: 200 vat_id: type: string pattern: ^[A-Z]{2}[A-Z0-9]{2,13}$ tax_id: type: string maxLength: 30 registration_number: type: string maxLength: 50 address: type: object properties: street: type: string maxLength: 200 city: type: string maxLength: 100 postal_code: type: string maxLength: 20 region: type: string maxLength: 100 country: type: string pattern: ^[A-Z]{2}$ required: - street - city - postal_code - country additionalProperties: false contacts: maxItems: 10 type: array items: type: object properties: role: type: string enum: - billing - legal - creative - general name: type: string maxLength: 200 email: type: string maxLength: 254 format: email pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$ phone: type: string maxLength: 30 required: - role additionalProperties: false bank: type: object properties: account_holder: type: string maxLength: 200 iban: type: string pattern: ^[A-Z]{2}[0-9]{2}[A-Z0-9]{4,30}$ bic: type: string pattern: ^[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?$ routing_number: type: string maxLength: 30 account_number: type: string maxLength: 30 required: - account_holder additionalProperties: false ext: type: object additionalProperties: {} required: - legal_name additionalProperties: false message: type: string minLength: 1 maxLength: 1000 required: - expectedVersion - decision - billing - billingEntity additionalProperties: false - type: object properties: expectedVersion: type: integer maximum: 9007199254740991 minimum: 1 decision: type: string enum: - reject message: type: string minLength: 1 maxLength: 1000 required: - expectedVersion - decision - message additionalProperties: false type: object FeedCommitResponse: description: Response from POST /feed/commit. The revision is now COMMITTED and the feed head has advanced. type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ sourceId: type: string revision: $ref: '#/components/schemas/FeedRevisionEnvelope' revisionRecord: $ref: '#/components/schemas/FeedRevisionRecord' required: - feedId - sourceId - revision - revisionRecord additionalProperties: false InventorySourceModuleContractSummary: description: Versioned contract summary used to interpret a modular source module. type: object properties: contractId: type: string version: type: string moduleType: type: string primaryKind: description: Role a module plays inside a modular inventory source. type: string enum: - INVENTORY_FEED - BOOKING_LEDGER - TRAFFICKING - STATUS_SYNC - REPORTING_IMPORT provider: type: string displayName: type: string description: type: string maturity: description: Present and `sandbox` when this contract is reachable only from a demo or sandbox source. A sandbox contract does NOT state what the platform can do with that vendor — the vendor may be implemented elsewhere with different automation. Absent means production. type: string enum: - sandbox constraints: type: array items: type: string required: - contractId - version - moduleType - primaryKind - displayName - description - constraints additionalProperties: false FreeWheelInventorySelectorPageResponse: type: object properties: items: type: array items: type: object properties: selectorType: type: string enum: - site - site_section - site_group - series - video_group - ad_unit_package - ad_unit_node - standard_attribute externalId: type: string name: type: string path: type: array items: type: string parentId: type: - string - 'null' status: type: - string - 'null' hasChildren: type: boolean metadata: type: object additionalProperties: {} required: - selectorType - externalId - name additionalProperties: false nextCursor: type: - string - 'null' count: type: integer minimum: 0 maximum: 9007199254740991 required: - items - nextCursor - count additionalProperties: false InventorySourceDiscoveryTestResponse: description: Normalized result of a direct, read-only get_products diagnostic against one third-party sales-agent source. type: object properties: source: type: object properties: sourceId: type: string name: type: string required: - sourceId - name additionalProperties: false operation: type: string enum: - get_products outcome: type: string enum: - passed - empty - failed - not_reached message: type: string productCount: type: integer minimum: 0 maximum: 9007199254740991 products: description: 'Representative matching products (id and name) from the source, capped at 20 items. products.length is at most productCount: items the source returned without a resolvable id are still counted in productCount but omitted from this list.' maxItems: 20 type: array items: type: object properties: productId: type: string name: type: - string - 'null' required: - productId - name additionalProperties: false checkedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ durationMs: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 trace: type: - object - 'null' properties: operationId: type: - string - 'null' taskId: type: - string - 'null' contextId: type: - string - 'null' debugId: type: - string - 'null' requestId: type: - string - 'null' traceparent: type: - string - 'null' required: - operationId - taskId - contextId - debugId - requestId - traceparent additionalProperties: false steps: type: array items: type: object properties: key: type: string label: type: string status: type: string enum: - completed - failed - not_checked operation: type: - string - 'null' httpStatus: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 endpoint: type: - string - 'null' message: type: - string - 'null' required: - key - label - status - operation - httpStatus - endpoint - message additionalProperties: false run: type: - object - 'null' properties: runUid: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ status: type: string enum: - passed - failed createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - runUid - status - createdAt additionalProperties: false required: - source - operation - outcome - message - productCount - products - checkedAt - durationMs - trace - steps - run additionalProperties: false LaunchEsaBody: description: Optional deep-link target for a managed ad-server source launch URL. type: object properties: path: description: Managed-source-relative deep-link path (e.g. `/products`). The service layer enforces structural constraints (no schemes, no `..`). Omit to land on the source home. type: string maxLength: 2048 FeedPreviewBaseline: description: Signed preview baseline. Pass it back unchanged to POST /feed/commit. type: object properties: previewToken: type: string minLength: 1 revisionId: type: string minLength: 1 customerId: type: integer maximum: 9007199254740991 minimum: 1 sourceId: type: string minLength: 1 profileId: type: string minLength: 1 profileVersion: type: string minLength: 1 payloadDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ activeRevisionId: type: - string - 'null' minLength: 1 activeCursor: type: - string - 'null' minLength: 1 activeSnapshot: type: - string - 'null' minLength: 1 createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ staleErrorCode: type: string enum: - STALE_PREVIEW_BASELINE required: - previewToken - revisionId - customerId - sourceId - profileId - profileVersion - payloadDigest - activeRevisionId - activeCursor - activeSnapshot - createdAt - expiresAt - staleErrorCode additionalProperties: false CitrusAdModularSourceResponse: description: Seller-facing CitrusAd ad-server connection. Internal recipe modules are intentionally not exposed. type: object properties: inventorySourceId: type: string sourceId: type: string provider: type: string enum: - citrusad connectionType: type: string enum: - AD_SERVER status: type: string enum: - CONFIGURING credentialRequired: type: boolean enum: - true supportedFormatIds: type: array items: type: string enum: - citrusad_sponsored_product required: - inventorySourceId - sourceId - provider - connectionType - status - credentialRequired - supportedFormatIds additionalProperties: false EsaAdapterCapabilityCheck: description: One adapter capability probe result. Mutating capabilities may be reported as `not_checked` by non-mutating connection tests. type: object properties: capability: type: string minLength: 1 status: anyOf: - type: string enum: - passed - type: string enum: - failed - type: string enum: - not_checked - type: string message: type: - string - 'null' errorCode: type: - string - 'null' remediation: type: - string - 'null' details: type: - object - 'null' additionalProperties: {} required: - capability - status additionalProperties: false IntelligenceRunBuyerScope: description: Buyer scope extracted from the AdCP get_products request that drove this run. type: object properties: operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' country: type: - string - 'null' required: - operatorDomain - brandDomain - country additionalProperties: false OnboardingPhaseTransition: type: object properties: from: allOf: - $ref: '#/components/schemas/OnboardingPhase' to: $ref: '#/components/schemas/OnboardingPhase' at: description: ISO timestamp of the transition. type: string required: - from - to - at additionalProperties: false MediaBuyDecisionBody: description: Request body for recording an operator decision on a pending media buy. type: object properties: status: description: Decision the operator is recording for this media buy. type: string enum: - approved - rejected reviewerNotes: description: Operator note about the decision. Surfaced back to the buyer alongside the status — keep it actionable when rejecting (e.g. 'targeting outside coverage area'). type: string maxLength: 2000 required: - status AdsWizzAdServerConfig: description: AdsWizz Domain API v8 (streaming audio + podcast) adapter configuration. The static API key is forwarded to the managed ad-server source and never persisted on the local connection row. type: object properties: type: type: string enum: - adswizz connectionContract: description: Pinned built-in AdsWizz connection contract. Omit only for legacy clients that have not migrated yet. type: object properties: id: type: string minLength: 1 maxLength: 128 pattern: ^[a-z][a-z0-9_-]*$ version: type: integer maximum: 9007199254740991 minimum: 1 authenticationMethod: type: string enum: - none - bearer_token - api_key - credential_exchange - basic_auth - oauth2 - jwt - platform_service_account required: - id - version - authenticationMethod additionalProperties: false apiKey: description: AdsWizz static API key, sent as the `x-api-key` header on every request. Required on write; write-only — never returned by the API or persisted by Scope3. writeOnly: true type: string minLength: 1 agencyId: description: AdsWizz agency id (sent as the `agency` header; scopes the billing currency and CPM ceiling). type: integer maximum: 9007199254740991 minimum: 1 environment: description: AdsWizz surface. Pinned to AUDIOSERVE (direct trafficking); AUDIOMAX/AUDIOMATIC are SSP-only and not supported. default: AUDIOSERVE type: string enum: - AUDIOSERVE baseUrl: description: AdsWizz Domain API v8 base URL. default: https://api.adswizz.com/domain/v8 type: string format: uri forecastingBaseUrl: description: AdsWizz Forecasting API v3 base URL (backs availability). default: https://api.adswizz.com/forecasting/v3 type: string format: uri defaultCurrency: description: Three-letter currency code the agency bills in (e.g. ZAR). Required — AdsWizz fixes the billing currency per agency, so it must be stated explicitly rather than defaulted; selected product pricing must match it. type: string pattern: ^[A-Z]{3}$ cpmLimit: description: Agency CPM ceiling. Every rate is guarded against this before any write. default: null type: - number - 'null' exclusiveMinimum: 0 defaultAdvertiserId: description: Fallback AdsWizz advertiser id for principals without an explicit AdsWizz mapping. default: null type: - string - 'null' maxLength: 64 required: - type - agencyId - defaultCurrency CreativeReviewResponse: description: A single creative review queue row — one buyer-submitted creative awaiting (or having received) an operator decision. type: object properties: id: description: Surrogate row id (BIGINT serialized as string). example: '42' type: string storefrontId: description: Storefront the submission was made against. example: '1234' type: string creativeId: description: AdCP creative id as submitted by the buyer. example: cr_abc123 type: string mediaBuyId: description: AdCP media_buy_id this creative was associated with at submit time, if any. Null when the buyer attaches creatives independently of a buy. type: - string - 'null' buyerCustomerId: description: customer_id of the buyer that submitted the creative — the tenancy boundary on buyer-side reads. type: integer minimum: -9007199254740991 maximum: 9007199254740991 submittedPayload: description: Verbatim AdCP sync_creatives entry, with buyer webhook credentials (`push_notification_config` / `pushNotificationConfig`) removed before it reaches operator-facing responses. The storefront stores the payload so the forwarder can reproduce it 1:1 to the upstream salesagent when the creative is approved. status: $ref: '#/components/schemas/CreativeReviewStatus' reviewedBy: description: User id of the operator who decided this review (BIGINT serialized as string). Null while pending. type: - string - 'null' reviewedAt: description: Decision timestamp (ISO 8601). Null while pending. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ reviewerNotes: description: Free-text reviewer note attached at decide time. Null when the operator did not supply one. type: - string - 'null' createdAt: description: Submission timestamp (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: description: Last-modified timestamp (ISO 8601). Equal to created_at while pending; bumped when the row transitions to a decided state. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - creativeId - mediaBuyId - buyerCustomerId - submittedPayload - status - reviewedBy - reviewedAt - reviewerNotes - createdAt - updatedAt additionalProperties: false SellerAccountBindingFeedPrepareResult: type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ state: type: string enum: - uploading uploadUrl: type: string format: uri uploadHeaders: type: object additionalProperties: type: string uploadExpiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ contentFingerprint: type: string pattern: ^[a-f0-9]{64}$ required: - feedId - revisionId - state - uploadUrl - uploadHeaders - uploadExpiresAt - contentFingerprint additionalProperties: false PendingOperationsApprovalItem: description: One media buy waiting on operator approval. type: object properties: mediaBuyId: type: string kind: type: string enum: - create - update buyer: type: object properties: customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: type: - string - 'null' required: - customerId - name additionalProperties: false submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - mediaBuyId - kind - buyer - submittedAt additionalProperties: false IngestModularAvailsFeedResponse: type: object properties: previewOnly: type: boolean inputSource: type: string parsedAvailCount: type: integer minimum: 0 maximum: 9007199254740991 avails: type: array items: type: object properties: collectionId: description: Exact legacy field name for a static-avails v1 compatibility grouping/container identifier. It does not establish AdCP Collection identity. type: string minLength: 1 collectionName: description: Exact legacy field name for a static-avails v1 compatibility grouping/container label. It does not establish AdCP Collection identity. type: string minLength: 1 collectionDescription: description: Exact legacy field name for a static-avails v1 compatibility grouping/container description. It does not establish AdCP Collection identity. type: - string - 'null' channel: type: - string - 'null' formatOptions: minItems: 1 type: array items: type: object properties: format_option_id: type: string publisher_domain: description: Publisher catalog namespace for format_option_id. Omit for product-local format options. type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_kind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} required: - format_kind - params additionalProperties: false publisherProperties: minItems: 1 type: array items: anyOf: - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - all required: - selection_type additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ selection_type: type: string enum: - by_id property_ids: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - publisher_domain - selection_type - property_ids additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - by_tag property_tags: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - selection_type - property_tags additionalProperties: {} availId: type: string minLength: 1 name: type: string minLength: 1 startTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ impressionsCapacity: type: integer minimum: 0 maximum: 9007199254740991 upstreamBookedImpressions: type: integer minimum: 0 maximum: 9007199254740991 cpm: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 targeting: type: object additionalProperties: {} sourceMetadata: type: object additionalProperties: {} required: - collectionId - collectionName - formatOptions - publisherProperties - availId - name - startTime - endTime - impressionsCapacity additionalProperties: false ingestedAvailCount: type: integer minimum: 0 maximum: 9007199254740991 projection: allOf: - $ref: '#/components/schemas/InventorySourceRuntimeProjection' products: type: array items: $ref: '#/components/schemas/ModularInventoryProduct' additionalProperties: false FreeWheelAdServerConfig: description: FreeWheel Publisher API adapter configuration. Credentials are forwarded to the managed ad-server source and never persisted on the local connection row. type: object properties: type: type: string enum: - freewheel connectionContract: description: Pinned built-in FreeWheel connection contract. Omit only for legacy clients that have not migrated yet. type: object properties: id: type: string minLength: 1 maxLength: 128 pattern: ^[a-z][a-z0-9_-]*$ version: type: integer maximum: 9007199254740991 minimum: 1 authenticationMethod: type: string enum: - none - bearer_token - api_key - credential_exchange - basic_auth - oauth2 - jwt - platform_service_account required: - id - version - authenticationMethod additionalProperties: false clientId: description: FreeWheel Publisher API client ID for the OAuth2 client_credentials grant. Required with `clientSecret`; omit when using legacy `username`/`password` or `apiToken`. type: string minLength: 1 maxLength: 255 clientSecret: description: FreeWheel Publisher API client secret for the OAuth2 client_credentials grant. Required with `clientId`. Write-only — never returned or written to the Interchange connection row; encrypted by the managed source. type: string minLength: 1 username: description: Legacy FreeWheel Publisher API username for password-grant authentication. Prefer `clientId` + `clientSecret` for partner-program credentials. type: string minLength: 1 maxLength: 255 password: description: Legacy FreeWheel Publisher API password for password-grant authentication. Write-only — never returned or written to the Interchange connection row; encrypted by the managed source. type: string minLength: 1 apiToken: description: Pre-minted FreeWheel API token (e.g. a 7-day temporary access key). Write-only — never returned or written to the Interchange connection row; encrypted by the managed source. Recommended for testing only; production deployments should use the client ID/client secret path which auto-refreshes. type: string minLength: 1 environment: description: FreeWheel environment to target. Sandbox is intended for testing only. default: production type: string enum: - production - staging - sandbox defaultAdvertiserId: description: Optional default FreeWheel advertiser id. type: string maxLength: 64 executionCurrency: description: FreeWheel commercial booking currency. New clients should send it explicitly. When omitted by a legacy create client, the API materializes the confirmed storefront default; when omitted during credential rotation, it preserves the current ESA execution currency. FreeWheel remains blocked until its write semantics are certified. type: string pattern: ^[A-Z]{3}$ required: - type ExchangeArtifactRedactionManifest: description: Discloses exactly what was removed or dropped from the stored payload. type: object properties: redactedPaths: description: JSON paths removed from the payload before storage (secret-bearing keys). type: array items: type: string truncated: description: Present when a payload exceeded its size limit and was dropped (the row remains with complete=false). type: array items: type: object properties: field: type: string reason: type: string originalByteSize: type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - field - reason - originalByteSize additionalProperties: false required: - redactedPaths additionalProperties: false SellerAccountGrantReviewList: type: object properties: items: type: array items: $ref: '#/components/schemas/SellerAccountGrantReviewItem' page: type: object properties: offset: type: integer minimum: 0 maximum: 9007199254740991 limit: type: integer minimum: 1 maximum: 100 total: type: integer minimum: 0 maximum: 9007199254740991 hasMore: type: boolean required: - offset - limit - total - hasMore additionalProperties: false required: - items - page additionalProperties: false IntelligenceRunBuyerInstructions: description: 'Resolver output: which buyer-instructions rows matched and the effective discount + notes applied.' type: object properties: matchedRowIds: type: array items: type: string effectiveDiscountPercent: type: - number - 'null' notes: type: array items: type: string required: - matchedRowIds - effectiveDiscountPercent - notes additionalProperties: false DemandExchangeBriefFacts: description: Condensed brief facts read from the persisted brief artifact request (never reconstructed). Any field the buyer did not send is null. type: object properties: channels: type: - array - 'null' items: type: string countries: type: - array - 'null' items: type: string budgetRange: allOf: - $ref: '#/components/schemas/DemandExchangeBudgetRange' promotedOffering: type: - string - 'null' brandDomain: type: - string - 'null' required: - channels - countries - budgetRange - promotedOffering - brandDomain additionalProperties: false DemandExchangePitch: description: 'The composed argument for one pass: what we heard, the thesis, the plan as roles with per-product fit arguments, outcome linkage, the value case, the honest counter, and the invitation. Every sentence carried at least one real source reference at composition time or was dropped before persistence — nothing here is unsourced prose. Sections the seller''s own ingredients could not support are empty rather than filled, so a pitch gets visibly plainer, never fabricated, as inputs thin out.' type: object properties: composedAt: type: string minLength: 1 composedVia: description: Which path attached this pitch. 'fast_follow' = composed after the buyer's response shipped, which is every pitch today; 'inline' is reserved for when the buyer-wire projection makes an in-request compose worth its latency. type: string enum: - inline - fast_follow claimsDropped: description: How many sentences the grounding contract removed for lacking a real source reference. Surfaced because a persistently high count means the composer is reaching, not that the pitch is thin. type: integer minimum: 0 maximum: 9007199254740991 whatWeHeard: description: The brief mirrored back sharper, in the buyer's own terms. May be empty. type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' thesis: description: 'The single argument connecting this buyer''s moment to this seller''s supply. Non-empty for a ''pitch'' or ''counter_pitch'' disposition: a pitch whose thesis did not survive grounding is not persisted at all, because products with decoration is not a plainer pitch. Empty for a composed ''pass'', which argues nothing and carries `decline` instead.' type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' roles: description: The plan presented as roles in a strategy rather than rows in a table, each with its fit argument. May be empty; the products still render. type: array items: $ref: '#/components/schemas/DemandExchangePitchRole' outcomeLinkage: description: How success will be measured, from the products' real reporting capabilities — and what will not be. May be empty. type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' valueCase: description: 'The argument for the price: the guarantee, the packaging, how the price was constructed. May be empty.' type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' honestCounter: description: What the brief asked for that this catalogue genuinely lacks, and what the seller would do instead. May be empty when there is no gap to name. type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' invitation: description: What happens next, stated as a verb and cited to a next-step affordance the platform can actually honour. May be empty when this pass offers none. type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' decline: description: 'The composed pass (AI-5870): a short, branded decline naming the mismatch and leaving the door open. Non-empty for a ''pass'' disposition and EMPTY for every pitch and counter-pitch — a pass composes this INSTEAD of an argument, never alongside one, and the schema refuses a record carrying both. A counter-pitch''s reframe rides its honest counter, not a decline. Sourced exactly like every other claim, so a decline cannot say anything a pitch could not.' default: [] type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' required: - composedAt - composedVia - claimsDropped - whatWeHeard - thesis - roles - outcomeLinkage - valueCase - honestCounter - invitation - decline additionalProperties: false ModularInventoryProduct: description: Product-like projection of one normalized modular inventory avail. type: object properties: productId: type: string availId: type: string collectionId: description: Legacy static-avails v1 compatibility grouping identifier. It does not establish AdCP Collection identity. type: string collectionName: description: Legacy static-avails v1 compatibility grouping label. It does not establish AdCP Collection identity. type: string name: type: string description: type: string channel: type: - string - 'null' formatOptions: minItems: 1 type: array items: $ref: '#/components/schemas/EsaCanonicalProductFormatOption' publisherProperties: minItems: 1 type: array items: anyOf: - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - all required: - selection_type additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ selection_type: type: string enum: - by_id property_ids: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - publisher_domain - selection_type - property_ids additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - by_tag property_tags: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - selection_type - property_tags additionalProperties: {} startTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ impressionsCapacity: type: integer minimum: 0 maximum: 9007199254740991 heldImpressions: type: integer minimum: 0 maximum: 9007199254740991 bookedImpressions: type: integer minimum: 0 maximum: 9007199254740991 availableImpressions: type: integer minimum: 0 maximum: 9007199254740991 cpm: type: - number - 'null' currency: type: - string - 'null' targeting: type: object additionalProperties: {} sourceMetadata: type: object additionalProperties: {} cadent: description: Cadent-specific execution projection. Null unless this modular source has an active Cadent execution module. type: - object - 'null' properties: campaignDeliveryType: type: string lineDeliveryType: type: string adType: type: string adClass: type: string targets: type: array items: type: object properties: condition: type: string enum: - include - exclude - strictexclude targetType: type: string values: type: array items: type: string required: - condition - targetType - values additionalProperties: false required: - campaignDeliveryType - lineDeliveryType - adType - adClass - targets additionalProperties: false required: - productId - availId - collectionId - collectionName - name - description - channel - formatOptions - publisherProperties - startTime - endTime - impressionsCapacity - heldImpressions - bookedImpressions - availableImpressions - cpm - currency - targeting - sourceMetadata - cadent additionalProperties: false FeedRevisionRecord: type: object properties: id: description: Surrogate row id of the revision record. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ idempotencyKey: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ contentDigest: description: SHA-256 content digest of the accepted facts. type: string validationStatus: type: string enum: - VALID - INVALID - PARTIALLY_VALID commitStatus: type: string enum: - PREVIEW - COMMITTED - REJECTED replayed: description: True if this row was returned from an idempotency cache hit. type: boolean required: - id - feedId - revisionId - idempotencyKey - contentDigest - validationStatus - commitStatus - replayed additionalProperties: false InventorySourceWorkItemEvent: type: object properties: id: type: string workItemId: type: string eventType: type: string actorType: type: string actorId: type: - string - 'null' notes: type: - string - 'null' payload: type: object additionalProperties: {} createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - workItemId - eventType - actorType - actorId - notes - payload - createdAt additionalProperties: false InventorySourceWorkItem: description: Seller-facing work item for a modular inventory source lifecycle task. type: object properties: id: type: string storefrontId: type: string inventorySourceId: type: string moduleId: type: - string - 'null' kind: type: string enum: - APPROVE_MEDIA_BUY - APPROVE_MEDIA_BUY_CANCELLATION - REVIEW_CREATIVE - CONFIRM_AVAILS - APPROVE_RATE_EXCEPTION - MAP_CREATIVE_REF - SYNC_UPSTREAM_CREATIVE - EXECUTE_UPSTREAM_BOOKING - TRAFFIC_TO_CADENT - RESOLVE_TRAFFICKING_ERROR - UPLOAD_FINAL_REPORT - RESOLVE_SOURCE_HEALTH - GENERAL title: type: string description: type: - string - 'null' status: type: string enum: - OPEN - IN_PROGRESS - BLOCKED - COMPLETED - CANCELLED priority: type: string enum: - LOW - NORMAL - HIGH - URGENT resourceType: type: string resourceId: type: string mediaBuyId: type: - string - 'null' buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 assignedTo: type: - string - 'null' dueAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ payload: type: object additionalProperties: {} result: type: object additionalProperties: {} blockedReason: type: - string - 'null' createdByType: type: string createdById: type: - string - 'null' completedBy: type: - string - 'null' completedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - storefrontId - inventorySourceId - moduleId - kind - title - description - status - priority - resourceType - resourceId - mediaBuyId - buyerCustomerId - assignedTo - dueAt - payload - result - blockedReason - createdByType - createdById - completedBy - completedAt - createdAt - updatedAt additionalProperties: false DemandCoverageSummary: description: Seller-side starter-brief coverage derived from profile, markets, channels, and product evidence. type: object properties: eligibleCombinations: type: integer minimum: 0 maximum: 9007199254740991 coveredCombinations: type: integer minimum: 0 maximum: 9007199254740991 categories: type: array items: type: string markets: type: array items: type: string channels: type: array items: type: string missingDimensions: type: array items: description: Demand-coverage dimension still needed before starter briefs can map cleanly to this storefront. type: string enum: - category - market - channel - inventory sampleBriefs: type: array items: $ref: '#/components/schemas/DemandCoverageSampleBrief' required: - eligibleCombinations - coveredCombinations - categories - markets - channels - missingDimensions - sampleBriefs additionalProperties: false ResolveBrandBody: type: object properties: domain: description: Brand domain to resolve (e.g., "nike.com") type: string minLength: 1 required: - domain AdServerConfigView: description: Non-secret view of the connection ad-server config. Returned by GET endpoints; never contains credentials. oneOf: - type: object properties: type: type: string enum: - google_ad_manager networkCode: description: Google Ad Manager network code. example: '12345678' type: string minLength: 1 maxLength: 32 pattern: ^[0-9]+$ required: - type - networkCode additionalProperties: false - type: object properties: type: type: string enum: - freewheel clientId: type: - string - 'null' username: type: - string - 'null' environment: type: string enum: - production - staging - sandbox defaultAdvertiserId: type: - string - 'null' executionCurrency: default: null type: - string - 'null' required: - type - clientId - username - environment - defaultAdvertiserId - executionCurrency additionalProperties: false - type: object properties: type: type: string enum: - springserve email: type: - string - 'null' environment: type: string enum: - production defaultDemandPartnerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 rateCurrency: default: null type: - string - 'null' required: - type - email - environment - defaultDemandPartnerId - rateCurrency additionalProperties: false - type: object properties: type: type: string enum: - adswizz agencyId: type: integer minimum: -9007199254740991 maximum: 9007199254740991 environment: type: string enum: - AUDIOSERVE baseUrl: type: string forecastingBaseUrl: type: string defaultCurrency: type: string cpmLimit: type: - number - 'null' defaultAdvertiserId: type: - string - 'null' required: - type - agencyId - environment - baseUrl - forecastingBaseUrl - defaultCurrency - cpmLimit - defaultAdvertiserId additionalProperties: false type: object PatchStorefrontCapabilitiesBody: description: Request body for patching legacy capability configuration and/or recording selling intent. Effective product composition is Source-derived even though V2 preserves the configured flag. type: object properties: capabilities: description: Patch legacy capability configuration; omitted flags are left unchanged. Product-composition configuration is persisted for V2 compatibility but is not runtime authority. type: object properties: offersCreativeReview: description: Surfaces the creative review protocol surface to buyers. Omit to leave unchanged. type: boolean offersCampaignApproval: description: Surfaces the campaign approval protocol surface to buyers. Omit to leave unchanged. type: boolean offersProductComposition: deprecated: true description: Deprecated V2 compatibility input. The value is preserved only in `configuredCapabilities`; it does not change the effective response or runtime behavior, which are derived from Source product paths and merchandising access. type: boolean setupIntent: description: Record the operator's declared selling intent. It does not select a Source product mode or grant merchandising access. type: string enum: - third_party_connect - sell_through_scope3 PendingMediaBuyResponse: description: A single pending media-buy entry on a storefront approval queue. type: object properties: id: description: Surrogate id of the approval row (BIGINT serialized as string). example: '42' type: string kind: description: Approval workstream kind. `create` is an initial create_media_buy approval; `update` is a material update_media_buy approval for an already-created buy. default: create type: string enum: - create - update storefrontId: description: Storefront the pending buy was submitted to (BIGINT serialized as string). example: '1234' type: string mediaBuyId: description: Buyer-supplied media buy identifier (AdCP `media_buy_id`). Unique per storefront — re-submitting the same id is idempotent. type: string buyerCustomerId: description: Customer id of the buyer who submitted the media buy. type: integer minimum: -9007199254740991 maximum: 9007199254740991 submittedPayload: description: Raw AdCP `create_media_buy` payload as the buyer submitted it, with buyer webhook credentials (`push_notification_config` / `pushNotificationConfig`) removed before it reaches operator-facing responses. Not normalized — the operator UI renders a summary directly from this object. status: description: Lifecycle state. `pending` until the operator decides; `approved` once the operator accepts (forwarding upstream happens out-of-band and is reflected by `forwardedAt`); `rejected` when the operator declines; `revoked` for buyer- or system-initiated cancellation after a decision. type: string enum: - pending - approved - rejected - revoked reviewedBy: description: User id of the operator who recorded the decision (BIGINT serialized as string). Null while pending. type: - string - 'null' reviewedAt: description: When the operator decision was recorded (ISO 8601). Null while pending. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ reviewerNotes: description: Operator note attached to the decision. Null while pending. type: - string - 'null' forwardedAt: description: 'When forwarding to the underlying sales agent settled (ISO 8601) — stamped both when every source accepted the buy and when the forward was terminalized, because the stamp is also what stops the background worker re-attempting a dead forward. Null means the forward has not been attempted or is still in flight. Read it with the per-source legs to tell a delivered buy from a refused one: a delivered buy carries an `upstreamMediaBuyId`.' type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdAt: description: When the buyer submitted the media buy (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: description: When the row was last modified — submission, decision, or forwarding stamp (ISO 8601). type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - kind - storefrontId - mediaBuyId - buyerCustomerId - submittedPayload - status - reviewedBy - reviewedAt - reviewerNotes - forwardedAt - createdAt - updatedAt additionalProperties: false DemandExchangeProduct: type: object properties: productId: type: string name: type: - string - 'null' description: type: - string - 'null' deliveryType: type: - string - 'null' pricing: description: Buyer-facing price for the pricing option the plan priced this product against (matched by the allocation pricing_option_id); when the plan named none, the first fixed-price option is used, else the first floor-price option, else the first option. Within the chosen option a fixed price is shown, else the floor. Null when the persisted product carried no priced option. type: - object - 'null' properties: model: type: - string - 'null' amount: type: - number - 'null' currency: type: - string - 'null' kind: type: - string - 'null' enum: - fixed - floor required: - model - amount - currency - kind additionalProperties: false allocationPercent: description: This product's share of the plan budget, exactly as the agent allocated it in the proposal (0–100). Null when the proposal carried no media plan for it. type: - number - 'null' allocationValue: description: allocationPercent applied to the buyer's committed point budget (budget_range where min===max). Null unless the buyer stated a true point budget — never a guess against an open range or a single ceiling/floor. type: - object - 'null' properties: amount: type: number currency: type: string required: - amount - currency additionalProperties: false formats: type: array items: type: object properties: agentUrl: type: - string - 'null' id: type: - string - 'null' required: - agentUrl - id additionalProperties: false snapshot: description: The persisted immutable product snapshot for expand-to-inspect. Null when the proposal artifact payload exceeded its size limit (complete=false). fedBy: description: The seller's own ingredients the engine consulted for THIS product line — its selected inventory bundles and signals, and the rate-card pricing facts matched against them. Empty for a pass recorded before compose provenance existed, or one whose provenance write failed; absence is silence and nothing is reconstructed. default: [] type: array items: $ref: '#/components/schemas/DemandExchangeFedBy' required: - productId - name - description - deliveryType - pricing - allocationPercent - allocationValue - formats - snapshot - fedBy additionalProperties: false DemandExchangeRevision: description: 'A seller-composed adjustment to a live demand exchange: silent while draft or awaiting approval, and a real pass on the exchange''s compose run once sent.' type: object properties: id: type: string exchangeId: type: string state: type: string enum: - draft - awaiting_approval - sent - discarded overrides: type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false composeResult: type: string enum: - ok - error composeError: description: The merchandising engine's own error, kept mounted (with the seller's declared overrides) when composition failed, rather than the sheet being torn down. allOf: - $ref: '#/components/schemas/DemandExchangeRevisionComposeError' proposalPreview: description: The draft response envelope, in the same shape the canonical proposal card already renders (redacted). Null when compose failed. proposalPreviewSnapshots: description: The draft product snapshots keyed by product id, paired with proposalPreview so the canonical proposal card renders a draft with no builder-specific projection. Null when compose failed. settlementCurrency: type: - string - 'null' buyerStatedCurrencies: description: Read once from the persisted brief request at compose time. A draft never converts into these or issues a rate hold — that is the buyer-facing response path's job, not a discardable draft's. type: - array - 'null' items: type: string composedByUserId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 composedAt: type: string approval: $ref: '#/components/schemas/DemandExchangeRevisionApproval' send: $ref: '#/components/schemas/DemandExchangeRevisionSend' sentProposalArtifactId: type: - string - 'null' delivery: description: 'Truthful buyer-visibility (build-5 ruling): null until sent. A sent revision always reports not_delivered/no_delivery_lane today — investigation found no seller-to-buyer lane for a subsequent proposal and no honest staging lane either. The UI states the buyer''s agent was not notified; it never claims a notification that did not happen.' type: - object - 'null' properties: status: type: string enum: - not_delivered reason: type: string enum: - no_delivery_lane required: - status - reason additionalProperties: false canApprove: description: False when the caller is this revision's own composer (maker-checker) or the revision is not awaiting approval. type: boolean canAmend: description: True for a draft (fresh or bounced back after rejection) composed by the caller; false once submitted, sent, or discarded, or when a different storefront user composed it. type: boolean canSubmit: description: True when the caller composed this draft, it hasn't been submitted, sent, or discarded, and its last compose succeeded. A draft whose compose failed can only be discarded or re-composed via amend. type: boolean canDiscard: description: True for a draft (fresh or bounced back after rejection) composed by the caller; false once submitted, sent, or discarded, or when a different storefront user composed it. type: boolean submissionGeneration: description: Bumped on every submit, resubmit, and amend. A decision must be made against this exact value or it is refused as stale. type: integer minimum: -9007199254740991 maximum: 9007199254740991 amendCount: description: How many times this row has been amended in place. Counts toward the lifetime adjustment cap alongside the row itself. type: integer minimum: -9007199254740991 maximum: 9007199254740991 required: - id - exchangeId - state - overrides - composeResult - composeError - proposalPreview - proposalPreviewSnapshots - settlementCurrency - buyerStatedCurrencies - composedByUserId - composedAt - approval - send - sentProposalArtifactId - delivery - canApprove - canAmend - canSubmit - canDiscard - submissionGeneration - amendCount additionalProperties: false FeedPreviewResponse: description: Response from POST /feed/preview and POST /feed/upload. Pass previewBaseline and revision to POST /feed/commit. type: object properties: feedId: description: Canonical inventory feed id shared by all transports (HITL, API_PUSH) for this source and contract. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ sourceId: description: External source_id string for this feed. type: string revision: $ref: '#/components/schemas/FeedRevisionEnvelope' previewBaseline: $ref: '#/components/schemas/FeedPreviewBaseline' required: - feedId - sourceId - revision - previewBaseline additionalProperties: false InventorySourceLifecycleStageSummary: description: Source-level lifecycle summary for a modular inventory source, aggregating setup gaps, runtime input requirements, HITL state, and module issues by stage. type: object properties: stage: description: Lifecycle stage a modular source module may implement. type: string enum: - LIST_ACCOUNTS - INGEST_AVAILS - SYNC_INVENTORY - GET_PRODUCTS - GET_MEDIA_BUYS - GET_ACCOUNT_RESOURCES - RESERVE_AVAILS - FINALIZE_BOOKING - RELEASE_BOOKING - RECONCILE_DELIVERY - SYNC_CREATIVES - TRAFFIC_CAMPAIGN - UPDATE_CAMPAIGN - SYNC_STATUS - IMPORT_REPORTING supported: type: boolean status: description: Operator-facing readiness status for a source-level lifecycle stage. UNSUPPORTED means every attached module declared what it runs and none of them runs this stage. NOT_DECLARED means a module that could run it is attached but the platform could not read what that module does, so whether it runs the stage is unknown rather than absent — and no seller configuration produces or clears that state. type: string enum: - UNSUPPORTED - NOT_DECLARED - MISSING_SETUP - RUNTIME_INPUTS_REQUIRED - HITL_PENDING - READY - BLOCKED modes: type: array items: description: 'How a modular source stage is fulfilled: automated, human-in-the-loop, or unsupported.' type: string enum: - AUTOMATED - HITL - UNSUPPORTED moduleInstanceIds: type: array items: type: string moduleNames: type: array items: type: string setupConfigured: type: boolean runtimeInputsRequired: type: boolean hitlRequired: type: boolean openWorkItemCount: type: integer minimum: 0 maximum: 9007199254740991 requiredRuntimeFieldSources: type: array items: description: Where a module contract field is expected to come from. type: string enum: - MODULE_CONFIG - INVENTORY_FEED - PRODUCT_METADATA - MEDIA_BUY_INPUT - CREATIVE_INPUT - REPORTING_UPLOAD - SYSTEM - MODULE_RESULT missingSetupFieldsBySource: type: array items: $ref: '#/components/schemas/InventorySourceContractFieldGroup' issues: type: array items: type: string required: - stage - supported - status - modes - moduleInstanceIds - moduleNames - setupConfigured - runtimeInputsRequired - hitlRequired - openWorkItemCount - requiredRuntimeFieldSources - missingSetupFieldsBySource - issues additionalProperties: false DemandExchangePassOutcome: description: Commercial outcome attributed to this pass. Today one run backs an exchange, so every pass shares the run-level outcome. type: object properties: result: type: string enum: - closed_won - closed_lost - pending wonValue: type: - object - 'null' properties: amount: type: number currency: type: string required: - amount - currency additionalProperties: false required: - result - wonValue additionalProperties: false CreateCadentDemoModularSourceBody: description: Creates or resets a demo modular inventory source backed by static avails, a booking ledger, and Cadent execution. type: object properties: sourceId: type: string minLength: 1 maxLength: 255 name: type: string minLength: 1 maxLength: 255 reset: default: true type: boolean seedAvails: default: true type: boolean cadentEndpointUrl: type: string format: uri UpdateModularSourceModuleConfigBody: description: Update non-secret configuration for a module on a modular inventory source. type: object properties: config: description: Non-secret module configuration values to write. Nested objects are deep-merged by default. type: object additionalProperties: {} merge: description: When true, deep-merge config into the existing module config. When false, replace the module config. default: true type: boolean status: description: Optional manual module status update. ACTIVE is derived by execution/readiness workflows and cannot be set through this config endpoint. Omit to leave status unchanged. type: string enum: - CONFIGURING - DISABLED - ERROR required: - config StorefrontMediaBuySummary: description: One buy on the storefront, at the seller list grain. type: object properties: mediaBuyId: description: The media buy id at this storefront grain (`sf_mb_…` for routed buys; the upstream source id for source-managed buys). type: string kind: description: 'Where this buy is managed: `routed` = forwarded through the storefront routing layer (approval queue + per-source routes); `esa` = managed by an ad server source upstream (`esa` is the stable wire value).' type: string enum: - routed - esa buyer: description: Who bought it. type: object properties: customerId: description: Buyer customer id (null for upstream source principals with no platform customer). type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: description: Buyer display name when known. type: - string - 'null' required: - customerId - name additionalProperties: false status: $ref: '#/components/schemas/SellerMediaBuyStatus' sourceStatus: description: The raw upstream status as persisted (route leg rollup or source status string). Null before anything was sent. type: - string - 'null' settlementMethod: description: 'The settlement method recorded for this booking: interchange means Interchange-cleared; seller means seller-cleared. Normal storefronts—including third-party sales-agent and finished-product/pass-through sources—are Interchange-cleared today. Seller-cleared storefront settlement is not yet configurable; seller currently appears only for official sales-adapter buys already settled under a downstream platform agreement. Null only for historical or upstream rows whose method was not recorded.' type: - string - 'null' enum: - interchange - seller pendingReason: description: Why the buy is not delivering yet (most-blocking leg), when derivable. Same vocabulary the buyer sees — one shared enum, never a status. allOf: - $ref: '#/components/schemas/MediaBuyPendingReason' pendingSince: description: When the current wait began, when known. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ errorCode: description: Structured error code of the latest failed exchange for this buy (ledger vocabulary, e.g. `unknown_product_ids`). Null when the latest exchange did not fail. type: - string - 'null' forwardOutcome: $ref: '#/components/schemas/SellerForwardOutcome' flightStart: description: Flight start ("asap" or ISO 8601) when known. type: - string - 'null' flightEnd: description: Flight end (ISO 8601) when known. type: - string - 'null' sourceCount: description: Number of source legs this buy fans out to (1 for source-managed buys). type: integer minimum: 0 maximum: 9007199254740991 esaId: description: Ad server source connection id for source-managed buys; null for routed. The wire field remains `esaId` for API compatibility. type: - string - 'null' createdAt: description: When the buy was received/created, when known. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ forwardedAt: description: When the buy was first successfully sent to a source. Null when nothing reached a source. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - mediaBuyId - kind - buyer - status - sourceStatus - settlementMethod - pendingReason - pendingSince - errorCode - forwardOutcome - flightStart - flightEnd - sourceCount - esaId - createdAt - forwardedAt additionalProperties: false SpringServeAdServerConfig: description: SpringServe (Magnite) adapter configuration. Credentials are forwarded to the managed ad-server source and never persisted on the local connection row. type: object properties: type: type: string enum: - springserve connectionContract: description: Pinned built-in SpringServe connection contract. Omit only for legacy clients that have not migrated yet. type: object properties: id: type: string minLength: 1 maxLength: 128 pattern: ^[a-z][a-z0-9_-]*$ version: type: integer maximum: 9007199254740991 minimum: 1 authenticationMethod: type: string enum: - none - bearer_token - api_key - credential_exchange - basic_auth - oauth2 - jwt - platform_service_account required: - id - version - authenticationMethod additionalProperties: false email: description: SpringServe login email. Required when authenticating with password grant; omit when using `apiToken`. type: string maxLength: 255 format: email pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$ password: description: SpringServe password. Required when authenticating with password grant. Write-only — never returned by the API or persisted by Scope3. type: string minLength: 1 apiToken: description: Pre-minted SpringServe API token. Write-only — only used when no email/password is supplied. Recommended for testing only; production deployments should use the email/password grant which auto-refreshes. type: string minLength: 1 environment: description: SpringServe environment. Only `production` is supported. default: production type: string enum: - production defaultDemandPartnerId: description: Optional default SpringServe demand partner id. type: integer maximum: 9007199254740991 minimum: 1 rateCurrency: description: Currency for SpringServe Campaign and Demand Tag rates. New clients should send it explicitly. When omitted by a legacy create client, the API materializes the confirmed storefront default; when omitted during credential rotation, it preserves the current ESA execution currency. type: string pattern: ^[A-Z]{3}$ required: - type StorefrontPricingFactOutput: description: Lightly structured seller value-pricing fact. Pricing facts anchor prices and floors; they are not product assembly templates. type: object properties: id: description: Stable operator-facing id for this pricing fact. Murph should preserve ids across rewrites when the fact is semantically the same. type: string minLength: 1 maxLength: 120 pattern: ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ label: description: Short display label for this pricing fact. example: Rich media packages type: string minLength: 1 maxLength: 160 appliesWhen: description: Natural-language applicability condition. This is intentionally not a rigid product template; the Merchandising Agent uses it as reasoning context. type: string minLength: 1 maxLength: 2000 hints: description: Optional structured hints for deterministic matching. Missing hints are fine. default: {} allOf: - $ref: '#/components/schemas/StorefrontPricingFactHintsOutput' pricing: $ref: '#/components/schemas/StorefrontPricingFactPriceOutput' strength: default: default description: '`hard_floor` is a must-not-go-below seller constraint. `default` is the preferred value-pricing anchor. `guidance` is advisory context only.' type: string enum: - hard_floor - default - guidance provenance: description: Where this pricing fact came from, such as "Uploaded 2026 rate card, page 3" or "Operator statement on setup call". type: string maxLength: 500 notes: description: Human-readable rationale or caveats for operators and Murph. type: string maxLength: 2000 required: - id - label - appliesWhen - hints - pricing - strength additionalProperties: false SellerAccountBindingFeedPreviewResult: type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ state: type: string enum: - preview_ready - validation_failed mode: type: string enum: - snapshot - delta sourceRevision: type: string impact: type: object properties: createCount: type: integer minimum: 0 maximum: 9007199254740991 updateCount: type: integer minimum: 0 maximum: 9007199254740991 archiveCount: type: integer minimum: 0 maximum: 9007199254740991 unchangedCount: type: integer minimum: 0 maximum: 9007199254740991 quarantineCount: type: integer minimum: 0 maximum: 9007199254740991 duplicateCount: type: integer minimum: 0 maximum: 9007199254740991 snapshotAbsenceArchiveCount: type: integer minimum: 0 maximum: 9007199254740991 required: - createCount - updateCount - archiveCount - unchangedCount - quarantineCount - duplicateCount - snapshotAbsenceArchiveCount additionalProperties: false diagnostics: type: array items: type: object properties: rowNumber: type: - integer - 'null' maximum: 9007199254740991 minimum: 1 code: type: string message: type: string required: - rowNumber - code - message additionalProperties: false diagnosticsTruncated: type: boolean previewToken: type: - string - 'null' previewExpiresAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - feedId - revisionId - state - mode - sourceRevision - impact - diagnostics - diagnosticsTruncated - previewToken - previewExpiresAt additionalProperties: false BusinessProfile: description: Operator-supplied business profile captured by Murph during storefront setup. type: object properties: summary: description: One-paragraph natural-language summary of the business (e.g. "30 properties across web, mobile, and CTV, primarily UK, sports and entertainment focus"). type: string maxLength: 2000 agentName: description: Deprecated agent-name field, kept for legacy compatibility only. Prefer the Storefront display name for buyer-facing naming; do not use this to create a separate persona. type: string minLength: 1 maxLength: 80 agentPersonality: description: Deprecated. An agent has no personality of its own — voice belongs to the brand, and is read from the brand manifest (`tone`). Nothing consumes this field; pass null to remove an existing legacy value. type: string minLength: 1 maxLength: 1000 propertyCount: description: Approximate number of owned properties / domains. type: integer minimum: 0 maximum: 10000 channels: description: Channels the operator sells across (ADCP channel codes — display, olv, ctv, social, audio, dooh). maxItems: 16 type: array items: description: Legacy V2 storefront channel code. Values round-trip unchanged; the Discovery Card projection, Marketplace filters, and outbound AdCP capabilities normalize `audio` to canonical `streaming_audio`. type: string enum: - display - olv - ctv - social - audio - dooh regions: description: Primary regions the business operates in (ISO 3166-1 alpha-2 country codes or group codes). example: - UK - EMEA maxItems: 64 type: array items: type: string pattern: ^[A-Z0-9_-]{2,32}$ verticals: description: Topic/vertical focus areas, free-text. example: - sports - entertainment maxItems: 32 type: array items: type: string minLength: 1 maxLength: 80 publisherDomains: description: Publisher domains/properties the Merchandising Agent should be authorized to sell through this Storefront. Omit when unknown; omission does not mean all domains are authorized. Domains are normalized to lowercase and deduplicated. example: - pitchside.co.uk - football.pitchside.co.uk maxItems: 128 type: array items: type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ evidenceUrls: description: URLs the operator pointed Murph at (media kits, about pages, etc.) so a future conversation can re-read the source material. New values must use HTTP(S). maxItems: 16 type: array items: type: string maxLength: 2048 format: uri notes: description: Free-form Murph-captured notes that did not fit into the structured fields. type: string maxLength: 4000 updatedBy: description: Identifier of the agent or user that last wrote this profile (e.g. "murph" or a userId). Audit-only. type: string maxLength: 120 FreeWheelSandboxModularSourceResponse: type: object properties: inventorySourceId: type: string sourceId: type: string projection: $ref: '#/components/schemas/InventorySourceRuntimeProjection' required: - inventorySourceId - sourceId - projection additionalProperties: false EsaWholesalePricingMode: description: 'Legacy source-level pricing preference. Product-level coverage is authoritative: ad-server-priced products are preserved and manual uploads fill only unresolved products, so pricing can be mixed within one source.' type: string enum: - ad_server_sync - manual_upload FeedCommitBody: description: Request body for POST /inventory-sources/:sourceId/feed/commit. type: object properties: feedId: description: Feed id returned by the preview call. type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ previewBaseline: description: Signed baseline object returned by the preview call. Pass it back unchanged. type: object properties: previewToken: type: string minLength: 1 revisionId: type: string minLength: 1 customerId: type: integer maximum: 9007199254740991 minimum: 1 sourceId: type: string minLength: 1 profileId: type: string minLength: 1 profileVersion: type: string minLength: 1 payloadDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ activeRevisionId: type: - string - 'null' minLength: 1 activeCursor: type: - string - 'null' minLength: 1 activeSnapshot: type: - string - 'null' minLength: 1 createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ staleErrorCode: type: string enum: - STALE_PREVIEW_BASELINE required: - previewToken - revisionId - customerId - sourceId - profileId - profileVersion - payloadDigest - activeRevisionId - activeCursor - activeSnapshot - createdAt - expiresAt - staleErrorCode additionalProperties: false revision: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryFeedRevisionSchema constraints: - FACT_IDS_UNIQUE_WITHIN_SOURCE_REVISION - FACT_SOURCES_MATCH_REVISION_SOURCE - FULL_REPLACEMENT_IS_NOT_PARTIALLY_VALID - COMMITTED_FULL_REPLACEMENT_IS_NOT_EMPTY - INVALID_REVISION_CANNOT_COMMIT required: true description: Full revision object returned by the preview call. Pass it back unchanged. type: object properties: schemaVersion: type: string enum: - 1.0.0 revisionId: type: string minLength: 1 sourceId: type: string minLength: 1 profileId: type: string minLength: 1 profileVersion: type: string minLength: 1 deliverySemantics: type: string enum: - FULL_REPLACEMENT - PATCH_UPSERT snapshot: type: string minLength: 1 cursor: type: string minLength: 1 observedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ coveredPeriod: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false idempotencyKey: type: string minLength: 1 contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ catalogRevision: type: string minLength: 1 provenance: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: ProvenanceSchema constraints: - FILE_REQUIRES_FILE_NAME - ADAPTER_REQUIRES_ADAPTER_ID required: true type: object properties: actorType: type: string enum: - API - FILE - HUMAN - ADAPTER actorId: type: string minLength: 1 adapterId: type: string minLength: 1 fileName: type: string minLength: 1 requestId: type: string minLength: 1 submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ required: - actorType - submittedAt - contentDigest additionalProperties: false correction: oneOf: - type: object properties: correctionId: type: string minLength: 1 targetType: type: string enum: - REVISION targetRevisionId: type: string minLength: 1 mode: type: string enum: - REPLACEMENT reason: type: string minLength: 1 required: - correctionId - targetType - targetRevisionId - mode - reason additionalProperties: false - type: object properties: correctionId: type: string minLength: 1 targetType: type: string enum: - FACT targetFactId: type: string minLength: 1 mode: type: string enum: - REPLACEMENT - PATCH reason: type: string minLength: 1 required: - correctionId - targetType - targetFactId - mode - reason additionalProperties: false type: object facts: type: array items: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: AvailabilityFactSchema constraints: - SCOPE_SOURCE_MATCHES_FACT_SOURCE - BOOKED_QUANTITY_UNIT_MATCHES_GROSS_UNIT - EMBEDDED_BOOKED_QUANTITY_DOES_NOT_EXCEED_GROSS_CAPACITY - GROSS_REQUIRES_BOOKED_QUANTITY_OR_TEMPORAL_FENCE - UNPROVEN_TEMPORAL_JOIN_IS_NOT_RESERVABLE - TEMPORAL_FENCE_MATCHES_ENCLOSING_FACT - PRODUCT_FORMAT_REQUIRES_PRODUCT_SCOPE required: true type: object properties: factId: type: string minLength: 1 sourceId: type: string minLength: 1 scope: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryScopeRefSchema constraints: - CANONICAL_COLLECTION_MAPPING_REQUIRED - EXACTLY_ONE_CANONICAL_COLLECTION_ID required: true anyOf: - type: object properties: scopeType: type: string enum: - component sourceId: type: string minLength: 1 kind: type: string enum: - placement - ad_unit - property externalId: type: string minLength: 1 required: - scopeType - sourceId - kind - externalId additionalProperties: false - type: object properties: scopeType: type: string enum: - component sourceId: type: string minLength: 1 kind: description: Canonical AdCP content Collection only, such as a series, publication, event series, or rotation. Generic pools and seller groupings are not Collections. type: string enum: - collection externalId: type: string minLength: 1 collectionSelector: description: Required mapping to exactly one Collection declared by publisher_domain in adagents.json. type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ collection_ids: type: array items: type: string required: - publisher_domain - collection_ids additionalProperties: {} required: - scopeType - sourceId - kind - externalId - collectionSelector additionalProperties: false - type: object properties: scopeType: type: string enum: - wholesale_product sourceId: type: string minLength: 1 productId: type: string minLength: 1 required: - scopeType - sourceId - productId additionalProperties: false dimensions: default: {} type: object additionalProperties: {} period: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false observedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ poolId: type: string minLength: 1 availability: type: object properties: basis: type: string enum: - NET_SELLABLE - GROSS quantity: type: object properties: unit: description: Profile-permitted quantity unit. The target profile allowlist remains pending. type: string minLength: 1 amount: type: number minimum: 0 required: - unit - amount additionalProperties: false upstreamBooked: type: object properties: unit: description: Profile-permitted quantity unit. The target profile allowlist remains pending. type: string minLength: 1 amount: type: number minimum: 0 required: - unit - amount additionalProperties: false temporalJoinFence: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: TemporalJoinFenceSchema constraints: - OBSERVED_SKEW_DERIVED_FROM_TIMESTAMPS - MONOTONIC_EVIDENCE_REMAINS_UNPROVEN - STATUS_MATCHES_SELECTED_PROOF - UNPROVEN_REQUIRES_DIAGNOSTIC required: true type: object properties: grossFactId: type: string minLength: 1 bookingFactId: type: string minLength: 1 sourceId: type: string minLength: 1 poolId: type: string minLength: 1 unit: type: string minLength: 1 period: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false strategy: type: string enum: - SAME_SNAPSHOT - MONOTONIC_WITHIN_SKEW grossSnapshot: type: string minLength: 1 bookingSnapshot: type: string minLength: 1 grossObservedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ bookingObservedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ observedSkewSeconds: type: number minimum: 0 status: type: string enum: - PROVEN - UNPROVEN diagnosticCode: type: string minLength: 1 required: - grossFactId - bookingFactId - sourceId - poolId - unit - period - strategy - grossSnapshot - bookingSnapshot - grossObservedThrough - bookingObservedThrough - observedSkewSeconds - status additionalProperties: false reservable: type: boolean required: - basis - quantity - reservable additionalProperties: false pricingOptions: default: [] type: array items: anyOf: - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpm currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - vcpm currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpc currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpcv currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpv currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: view_threshold: anyOf: - type: number - type: object properties: duration_seconds: type: number minimum: 1 required: - duration_seconds additionalProperties: {} required: - view_threshold additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpp currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: demographic_system: anyOf: - type: string enum: - nielsen - type: string enum: - barb - type: string enum: - agf - type: string enum: - oztam - type: string enum: - mediametrie - type: string enum: - custom demographic: type: string min_points: type: number minimum: 0 required: - demographic additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpa event_type: anyOf: - type: string enum: - page_view - type: string enum: - view_content - type: string enum: - select_content - type: string enum: - select_item - type: string enum: - search - type: string enum: - share - type: string enum: - add_to_cart - type: string enum: - remove_from_cart - type: string enum: - viewed_cart - type: string enum: - add_to_wishlist - type: string enum: - initiate_checkout - type: string enum: - add_payment_info - type: string enum: - purchase - type: string enum: - refund - type: string enum: - lead - type: string enum: - qualify_lead - type: string enum: - close_convert_lead - type: string enum: - disqualify_lead - type: string enum: - complete_registration - type: string enum: - subscribe - type: string enum: - follow - type: string enum: - content_view - type: string enum: - watch_milestone - type: string enum: - start_trial - type: string enum: - app_install - type: string enum: - app_launch - type: string enum: - contact - type: string enum: - schedule - type: string enum: - donate - type: string enum: - submit_application - type: string enum: - custom custom_event_name: type: string event_source_id: type: string currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - event_type - currency - fixed_price additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - flat_rate currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: type: type: string enum: - dooh sov_percentage: type: number minimum: 0 maximum: 100 loop_duration_seconds: type: number minimum: 1 min_plays_per_hour: type: number minimum: 1 venue_package: type: string duration_hours: type: number minimum: 0 daypart: type: string estimated_impressions: type: number minimum: 0 required: - type additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - time currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: time_unit: anyOf: - type: string enum: - hour - type: string enum: - day - type: string enum: - week - type: string enum: - month min_duration: type: number minimum: 1 max_duration: type: number minimum: 1 required: - time_unit additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} formatOptions: default: [] type: array items: anyOf: - type: object properties: scope: type: string enum: - publisher publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_option_id: type: string required: - scope - publisher_domain - format_option_id additionalProperties: {} - type: object properties: scope: type: string enum: - product format_option_id: type: string publisher_domain: not: {} required: - scope - format_option_id additionalProperties: {} sourceMetadata: default: {} type: object additionalProperties: {} provenance: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: ProvenanceSchema constraints: - FILE_REQUIRES_FILE_NAME - ADAPTER_REQUIRES_ADAPTER_ID required: true type: object properties: actorType: type: string enum: - API - FILE - HUMAN - ADAPTER actorId: type: string minLength: 1 adapterId: type: string minLength: 1 fileName: type: string minLength: 1 requestId: type: string minLength: 1 submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ required: - actorType - submittedAt - contentDigest additionalProperties: false required: - factId - sourceId - scope - period - observedAt - poolId - availability - provenance additionalProperties: false diagnostics: type: array items: type: object properties: code: type: string minLength: 1 severity: type: string enum: - ERROR - WARNING - INFO scope: type: string enum: - REVISION - ROW - FACT message: type: string minLength: 1 rowIndex: type: integer minimum: 0 maximum: 9007199254740991 factId: type: string minLength: 1 field: type: string minLength: 1 details: type: object additionalProperties: {} required: - code - severity - scope - message additionalProperties: false validationStatus: type: string enum: - VALID - INVALID - PARTIALLY_VALID commitStatus: type: string enum: - PREVIEW - COMMITTED - REJECTED required: - schemaVersion - revisionId - sourceId - profileId - profileVersion - deliverySemantics - idempotencyKey - contentDigest - provenance - facts - diagnostics - validationStatus - commitStatus additionalProperties: false required: - feedId - previewBaseline - revision CreateFreeWheelSandboxModularSourceBody: description: Creates or updates a FreeWheel sandbox modular inventory source. Credentials are platform-managed sandbox environment variables, not caller-supplied secrets or env var names. type: object properties: sourceId: type: string minLength: 1 maxLength: 255 name: type: string minLength: 1 maxLength: 255 advertiserId: type: string minLength: 1 maxLength: 255 PendingOperationsFailedForwardItem: description: One buy whose forward failed, with its gated action. type: object properties: mediaBuyId: type: string buyer: type: object properties: customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: type: - string - 'null' required: - customerId - name additionalProperties: false since: description: When the failure was recorded. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ terminalized: description: True when the platform has stopped retrying this buy (structural failure or retry window lapsed). type: boolean action: $ref: '#/components/schemas/SellerRecoveryAction' references: description: 'Pre-attached references for an escalation: the create idempotency key and request timestamp.' type: object properties: idempotencyKey: type: - string - 'null' requestedAt: type: - string - 'null' required: - idempotencyKey - requestedAt additionalProperties: false required: - mediaBuyId - buyer - since - terminalized - action - references additionalProperties: false IntelligenceRunProductPricingExplanation: description: Server-computed CPM pricing summary for a selected composition. type: object properties: baseCpm: type: - number - 'null' currency: type: - string - 'null' operatorDiscount: type: - number - 'null' finalCpm: type: - number - 'null' required: - baseCpm - currency - operatorDiscount - finalCpm additionalProperties: false DemandExchangePitchClaim: type: object properties: claimRef: description: Stable server-minted handle for this sentence, matching the claimRef on its fedBy receipts. Never blank. type: string minLength: 1 text: description: The sentence, as composed. Never blank. type: string minLength: 1 sources: description: 'Every reference that entitled this sentence to be made — the complete citation list, including the exchange''s own material (the brief''s stated fields, this pass''s composed products) and the platform''s own next-step verbs (''affordance'': ''refine'', ''create_media_buy''), none of which has a seller ingredient behind it. Never empty: a claim with no surviving source is dropped at composition time rather than rendered. ''corpus'' is reserved for the seller''s marketing corpus and is never present until that ingredient is wired.' minItems: 1 type: array items: type: object properties: kind: type: string enum: - brief - inventory_bundle - signal - pricing_fact - operating_instructions - composed_product - corpus - affordance ref: type: string minLength: 1 required: - kind - ref additionalProperties: false fedBy: description: 'The openable receipts behind this sentence: the seller''s own ingredients it cited, resolved to their owner Tasks exactly like a product row''s chips. A subset of sources — brief and composed-product references are real citations but are not seller ingredients, so they carry no owner. Empty when the claim cited only those, or when the claim''s provenance write failed.' default: [] type: array items: $ref: '#/components/schemas/DemandExchangeFedBy' required: - claimRef - text - sources - fedBy additionalProperties: false PendingOperationsFailedForwardGroup: description: Failed forwards grouped by structured error code. type: object properties: errorCode: description: Structured error code the group shares — a source outage reads as ONE row, not N. type: string recovery: type: - string - 'null' enum: - transient - correctable - structural action: description: The action class for every item in this group. allOf: - $ref: '#/components/schemas/SellerRecoveryAction' count: type: integer maximum: 9007199254740991 minimum: 1 items: type: array items: $ref: '#/components/schemas/PendingOperationsFailedForwardItem' required: - errorCode - recovery - action - count - items additionalProperties: false ReadinessCheck: description: Individual readiness check result type: object properties: id: type: string name: type: string description: type: string category: type: string status: description: Status of a readiness check. `optional` is reserved for checks that are explicitly skipped (e.g. billing in non-production environments) — they are not required before the storefront can start transacting. type: string enum: - complete - partial - missing - optional isBlocker: type: boolean method: type: string details: type: string action: description: Where this step resolves. Absent → the widget falls back to its own routing for the check id. type: string enum: - inline_currency - inline_operator_domain - link - policy - open - chat - recheck actionLabel: description: Outcome-named action label for this step (e.g. "Connect ad server", "Set currency") — names the task, not the tool. Absent → the widget derives a label from the check name. type: string actionUrl: description: Absolute application destination for a `link` action. Server-owned so every MCP Apps host executes the same destination without a model prompt. type: string format: uri actionValue: description: Current value used to seed an inline action control, when applicable. type: string compliance: description: Per-agent compliance results (present on agent_connectivity checks) type: array items: $ref: '#/components/schemas/AgentComplianceResult' requirement: description: 'Requirement classification for this storefront''s current selling path. ''hard'': must be resolved before the storefront can go live. ''soft'': advisory — improves outcomes but never blocks. ''platform_default'': the platform applied a sensible default (named in appliedDefault) that the seller can change later. The server always sets this; optional only for payload compatibility.' type: string enum: - hard - soft - platform_default appliedDefault: description: 'For ''platform_default'' checks: the default the platform applied, stated in seller terms, and how to change it.' type: string guidance: description: Present on every incomplete hard requirement. Omitted for complete or non-blocking checks. allOf: - $ref: '#/components/schemas/ReadinessBlockingGuidance' required: - id - name - description - category - status - isBlocker additionalProperties: false CreateFeedModularSourceBody: description: Creates a real seller modular inventory source backed by an uploaded/static avails feed module and, by default, the built-in booking ledger. Execution, reporting, and creative backend details are stored as non-secret setup metadata until matching modules are configured. type: object properties: sourceId: type: string minLength: 1 maxLength: 255 pattern: ^[a-z0-9][a-z0-9_-]*$ name: type: string minLength: 1 maxLength: 255 includeBookingLedger: default: true type: boolean availsSource: type: object properties: type: type: string enum: - upload - spreadsheet - api - manual - unknown cadence: type: string minLength: 1 maxLength: 2000 description: type: string minLength: 1 maxLength: 2000 booking: type: object properties: mode: type: string enum: - booking_ledger - manual - upstream_oms systemName: type: string minLength: 1 maxLength: 255 notes: type: string minLength: 1 maxLength: 2000 execution: type: object properties: mode: type: string enum: - manual - upstream_system - none systemName: type: string minLength: 1 maxLength: 255 notes: type: string minLength: 1 maxLength: 2000 reporting: type: object properties: mode: type: string enum: - upload - manual - upstream_export - api - none systemName: type: string minLength: 1 maxLength: 255 sampleAvailable: type: boolean notes: type: string minLength: 1 maxLength: 2000 creative: type: object properties: mode: type: string enum: - manual - upstream_system - none systemName: type: string minLength: 1 maxLength: 255 notes: type: string minLength: 1 maxLength: 2000 notes: type: string minLength: 1 maxLength: 2000 required: - name RetryForwardMediaBuyBody: description: Request body for retrying forwarding. The terminal override is an operator recovery control and is guarded against duplicate upstream writes. default: forceTerminal: false type: object properties: forceTerminal: description: Allow retrying an incorrectly terminalized approval only when every persisted source route is a failed, unsent leg. The request is rejected if any source has an upstream media-buy or task id. default: false type: boolean reason: description: Why this retry is being made — recorded against the attempt so a later reviewer can tell a considered recovery from a reflexive one. Strongly recommended with `forceTerminal`, which overrides a terminal state in front of an ad server. example: Dimension-derivation fix shipped in v4.118.0; GAM order absent. type: string minLength: 1 maxLength: 500 additionalProperties: false EsaInventorySync: description: Cached inventory-sync state for this managed ad-server source. Updated by the /webhooks/esa-sync receiver when the upstream service emits `sync_run.completed` / `sync_run.failed`, and by the /status polling fallback for missed deliveries. type: object properties: status: description: Last known inventory-sync state on the upstream managed source. `unknown` means we have no signal yet (row predates the sync tracking, no webhook or status poll has landed). Other values mirror the upstream managed-source vocabulary. type: - string - 'null' enum: - unknown - never_run - running - success - failed lastRunAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ completedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ itemCount: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 error: type: - string - 'null' updatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - status - lastRunAt - completedAt - itemCount - error - updatedAt additionalProperties: false StorefrontMediaBuyTimelineResponse: description: 'The seller-scoped projection of a buy''s exchange timeline: only this storefront''s legs; forwarded/response payloads minus platform-internal fields; no admin-only material (resolution cache internals, worker poll internals, cross-tenant audit rows).' type: object properties: mediaBuyId: type: string buyer: type: object properties: customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: type: - string - 'null' required: - customerId - name additionalProperties: false approval: description: The approval-queue row, when the buy rode the review flow. type: - object - 'null' properties: status: type: string submittedAt: type: string reviewedBy: type: - string - 'null' reviewedAt: type: - string - 'null' reviewerNotes: type: - string - 'null' forwardedAt: type: - string - 'null' submittedPayload: description: The buyer's submitted payload as it sits in the approval queue (already webhook-credential-free), minus platform-internal fields. type: - object - 'null' additionalProperties: {} required: - status - submittedAt - reviewedBy - reviewedAt - reviewerNotes - forwardedAt - submittedPayload additionalProperties: false stages: description: 'Buy-level stages (pre-fan-out): received, screened, decided, and any pre-dispatch failure.' type: array items: $ref: '#/components/schemas/SellerTimelineStage' legs: type: array items: $ref: '#/components/schemas/SellerTimelineLeg' eventsTruncated: description: True when more ledger events exist than were hydrated into this timeline. type: boolean required: - mediaBuyId - buyer - approval - stages - legs - eventsTruncated additionalProperties: false StorefrontTargetEntry: description: One discovered entry in a storefront onboarding plan target model. type: object properties: kind: type: string enum: - channel - format - property - product - signal - pricing value: description: The target value, e.g. "ctv", "premium homepage takeover", "podcast catalog". type: string sourceRef: description: Which inventory source carries it, when known. Matters for enterprise sellers whose storefronts run multiple sources — a gap must resolve to the source it should flow through. type: - string - 'null' provenance: type: string enum: - declared - observed - asked - buyer_requested - researched confidence: type: number minimum: 0 maximum: 1 evidenceRefs: type: array items: type: string status: type: string enum: - candidate - confirmed - expressed - declined required: - kind - value - sourceRef - provenance - confidence - evidenceRefs - status additionalProperties: false SellerDecisionRecord: description: Canonical seller-readable decision record projected from one storefront intelligence run and its attributed approval/commercial evidence. type: object properties: id: type: string status: type: string enum: - pending - responded - declined - failed - booked - delivered - rejected - unattributed createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ purpose: type: object properties: availability: type: string enum: - recorded - unavailable value: allOf: - $ref: '#/components/schemas/IntelligenceRunPurpose' required: - availability - value additionalProperties: false buyer: type: object properties: operatorDomain: type: - string - 'null' brandDomain: type: - string - 'null' country: type: - string - 'null' customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 required: - operatorDomain - brandDomain - country - customerId additionalProperties: false ask: type: object properties: brief: type: - string - 'null' buyingMode: type: string requestAsks: type: array items: type: string inputSnapshotAvailability: type: string enum: - recorded - unavailable required: - brief - buyingMode - requestAsks - inputSnapshotAvailability additionalProperties: false fit: type: object properties: disposition: type: - string - 'null' enum: - responded - declined_fit - declined_policy - not_live qualified: type: - boolean - 'null' reasonAxis: type: - string - 'null' enum: - fit - policy reason: type: - string - 'null' matchedProducts: type: array items: $ref: '#/components/schemas/IntelligenceRunProductExplanation' unavailableProducts: type: array items: $ref: '#/components/schemas/IntelligenceRunUnpricedProductExplanation' required: - disposition - qualified - reasonAxis - reason - matchedProducts - unavailableProducts additionalProperties: false posture: type: object properties: recommended: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror selected: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror rationale: type: - string - 'null' intensity: type: - string - 'null' enum: - low - medium - high signals: type: array items: type: string guidance: type: array items: type: string matchedPricingFactIds: type: array items: type: string operatingInstructionsVersion: type: integer minimum: -9007199254740991 maximum: 9007199254740991 matchedBuyerInstructionIds: type: array items: type: string override: type: object properties: availability: type: string enum: - recorded - unavailable actor: type: - string - 'null' required: - availability - actor additionalProperties: false acceptancePolicyVersion: type: object properties: availability: type: string enum: - recorded - unavailable value: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 required: - availability - value additionalProperties: false required: - recommended - selected - rationale - intensity - signals - guidance - matchedPricingFactIds - operatingInstructionsVersion - matchedBuyerInstructionIds - override - acceptancePolicyVersion additionalProperties: false response: type: object properties: status: type: string enum: - responded - withheld - failed - unavailable summary: type: string exactSentState: type: object properties: availability: type: string enum: - recorded - unavailable productCount: type: - integer - 'null' minimum: 0 maximum: 9007199254740991 proposalHistoryAvailability: type: string enum: - recorded - unavailable required: - availability - productCount - proposalHistoryAvailability additionalProperties: false negotiationChanges: type: object properties: requestAsks: type: array items: type: string refinementApplied: {} required: - requestAsks - refinementApplied additionalProperties: false required: - status - summary - exactSentState - negotiationChanges additionalProperties: false approval: type: object properties: availability: type: string enum: - recorded - unavailable id: type: - string - 'null' status: type: - string - 'null' enum: - pending - approved - rejected - revoked reviewedBy: type: - string - 'null' reviewedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ reviewerNotes: type: - string - 'null' forwardedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - availability - id - status - reviewedBy - reviewedAt - reviewerNotes - forwardedAt additionalProperties: false outcome: type: object properties: state: type: string enum: - pending - booked - delivered - rejected - failed - unattributed - unavailable eventType: type: - string - 'null' eventAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ mediaBuyId: type: - string - 'null' mediaBuyStatus: type: - string - 'null' pendingApprovalId: type: - string - 'null' bookedBudget: type: - number - 'null' deliveredImpressions: type: - number - 'null' deliveredSpend: type: - number - 'null' deliveredCurrency: type: - string - 'null' attribution: type: object properties: availability: type: string enum: - recorded - unavailable model: type: - string - 'null' matchedRunId: type: - string - 'null' matchedProductIds: type: array items: type: string required: - availability - model - matchedRunId - matchedProductIds additionalProperties: false required: - state - eventType - eventAt - mediaBuyId - mediaBuyStatus - pendingApprovalId - bookedBudget - deliveredImpressions - deliveredSpend - deliveredCurrency - attribution additionalProperties: false learning: type: object properties: analyticsEligibility: type: object properties: status: type: string enum: - eligible - ineligible - unavailable reason: type: string required: - status - reason additionalProperties: false postureContribution: type: object properties: availability: type: string enum: - recorded - unavailable selected: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror recommended: type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - availability - selected - recommended additionalProperties: false recommendationLineage: type: object properties: availability: type: string enum: - recorded - unavailable required: - availability additionalProperties: false required: - analyticsEligibility - postureContribution - recommendationLineage additionalProperties: false provenance: type: object properties: modelProvider: type: - string - 'null' modelName: type: string operatingInstructionsVersion: type: integer minimum: -9007199254740991 maximum: 9007199254740991 durationMs: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 required: - modelProvider - modelName - operatingInstructionsVersion - durationMs additionalProperties: false required: - id - status - createdAt - purpose - buyer - ask - fit - posture - response - approval - outcome - learning - provenance additionalProperties: false SourceDiagnostics: description: Per-inventory-source diagnostics for storefront setup and onboarding type: object properties: id: type: - string - 'null' sourceId: type: - string - 'null' name: type: string executionType: description: What backs this private upstream inventory source. `AGENT` is an external AdCP-compatible sales agent the Merchandising Agent connects to; `MANAGED_SALES_AGENT` is an operator-owned ad server with Interchange-managed sales-agent plumbing behind it; `LINKED_STOREFRONT` is wholesale inventory discovered automatically from the ambient pool of LISTED storefronts whose computed `canTransact` projection is true (resolved at runtime, never persisted as a source row); `MODULAR_SOURCE` is a composed inventory source assembled from private modules such as avails, booking, trafficking, and reporting. Storefront-level `ADAPTER` dispatch is configured on the storefront, not as an inventory source. type: string enum: - AGENT - MANAGED_SALES_AGENT - LINKED_STOREFRONT - MODULAR_SOURCE setupKind: description: Operator-facing setup family when it differs from the internal execution type. Clients fall back to executionType when omitted. type: string enum: - ad_server - modular - external_agent detailAction: description: Authorized portable specialist destination for this exact source. Omitted when no exact destination is exposed. allOf: - $ref: '#/components/schemas/SourceDetailAction' catalogMappingReadiness: description: Canonical Modular Source catalog progress and next action, reused without client-side re-derivation. type: object properties: progress: type: object properties: ready: type: integer minimum: 0 maximum: 9007199254740991 applicable: type: integer minimum: 0 maximum: 9007199254740991 percent: type: integer minimum: 0 maximum: 100 required: - ready - applicable - percent additionalProperties: false nextAction: allOf: - $ref: '#/components/schemas/CatalogMappingAction' required: - progress - nextAction additionalProperties: false cardPosture: $ref: '#/components/schemas/SourceCardPosture' sourceStatus: description: Inventory source lifecycle status type: string enum: - PENDING - ACTIVE - DISABLED agentId: type: - string - 'null' agentStatus: deprecated: true description: Deprecated compatibility projection of sourceStatus for external-agent sources. It is not an independent lifecycle signal; use sourceStatus. type: - string - 'null' enum: - PENDING - ACTIVE - DISABLED endpointUrl: type: - string - 'null' protocol: type: - string - 'null' enum: - MCP - A2A auth: type: object properties: required: type: boolean configured: type: boolean type: type: - string - 'null' required: - required - configured - type additionalProperties: false capabilities: type: object properties: products: type: string enum: - supported - unsupported - unknown createMediaBuy: type: string enum: - supported - unsupported - unknown updateMediaBuy: type: string enum: - supported - unsupported - unknown signals: type: string enum: - supported - unsupported - unknown wholesaleProducts: type: string enum: - supported - unsupported - unknown required: - products - createMediaBuy - updateMediaBuy - signals - wholesaleProducts additionalProperties: false productBuilder: type: - object - 'null' properties: mode: type: string enum: - composition - passthrough - unknown wholesaleProductCount: type: - number - 'null' buyerVisibleProductCount: type: - number - 'null' currencyMismatchProductCount: description: Of the authored products hidden from buyers, how many are hidden only because their operator fixed price is in a different currency than the storefront's settlement currency. null when the pantry audit did not run. type: - number - 'null' reportingStaleProductCount: description: Of the authored products hidden from buyers, how many are hidden only because their ad-server-reporting-derived pricing aged past the freshness ceiling (60 days without a successful catalog refresh). null when the pantry audit did not run. type: - number - 'null' signalCount: type: - number - 'null' catalogCacheCold: type: boolean declaredUnsupportedIngredients: type: boolean required: - mode - wholesaleProductCount - buyerVisibleProductCount - currencyMismatchProductCount - reportingStaleProductCount - signalCount - catalogCacheCold - declaredUnsupportedIngredients additionalProperties: false compliance: type: - object - 'null' properties: passed: type: boolean summary: type: string checkedAt: type: - string - 'null' trackCounts: type: object properties: total: type: number passing: type: number partial: type: number failing: type: number required: - total - passing - partial - failing additionalProperties: false required: - passed - summary - checkedAt - trackCounts additionalProperties: false debug: type: object properties: version: type: - string - 'null' syntheticCapabilities: type: - boolean - 'null' tools: type: array items: type: string supportedBillings: type: array items: type: string channels: type: array items: type: string countries: type: array items: type: string publisherDomains: type: array items: type: string requireOperatorAuth: type: - boolean - 'null' required: - version - syntheticCapabilities - tools - supportedBillings - channels - countries - publisherDomains - requireOperatorAuth additionalProperties: false lastActivity: type: - object - 'null' properties: action: type: string resourceType: type: string resourceId: type: - string - 'null' resourceName: type: - string - 'null' description: type: string timestamp: type: string required: - action - resourceType - resourceId - resourceName - description - timestamp additionalProperties: false health: type: object properties: status: type: string enum: - healthy - degraded - unhealthy - unknown lastError: type: - string - 'null' lastErrorCode: type: - string - 'null' lastErrorAt: type: - string - 'null' lastSuccessAt: type: - string - 'null' lastCheckedAt: type: - string - 'null' required: - status - lastError - lastErrorCode - lastErrorAt - lastSuccessAt - lastCheckedAt additionalProperties: false capabilityHealth: type: object properties: inventory: type: object properties: status: type: - string - 'null' enum: - healthy - degraded - unhealthy observations: type: array items: type: object properties: observer: type: string status: type: string enum: - healthy - degraded - unhealthy previousStatus: type: - string - 'null' enum: - healthy - degraded - unhealthy cause: type: - string - 'null' detail: type: - string - 'null' owner: type: - string - 'null' observedAt: type: string lastOkAt: type: - string - 'null' required: - observer - status - previousStatus - cause - detail - owner - observedAt - lastOkAt additionalProperties: false required: - status - observations additionalProperties: false reporting: type: object properties: status: type: - string - 'null' enum: - healthy - degraded - unhealthy observations: type: array items: type: object properties: observer: type: string status: type: string enum: - healthy - degraded - unhealthy previousStatus: type: - string - 'null' enum: - healthy - degraded - unhealthy cause: type: - string - 'null' detail: type: - string - 'null' owner: type: - string - 'null' observedAt: type: string lastOkAt: type: - string - 'null' required: - observer - status - previousStatus - cause - detail - owner - observedAt - lastOkAt additionalProperties: false required: - status - observations additionalProperties: false required: - inventory - reporting additionalProperties: false required: - id - sourceId - name - executionType - cardPosture - sourceStatus - agentId - agentStatus - endpointUrl - protocol - auth - capabilities - productBuilder - compliance - debug - lastActivity - health - capabilityHealth additionalProperties: false PropertyRosterResponse: description: 'The storefront property roster: every declared publisher domain with its resolved properties, canonical AdCP Collections, canonical creative formats, and authorization state. AAO publisher lookup supplies publisher and community formats while authorization remains a separate live-origin decision. `totals` describe the storefront; the returned arrays are response-bounded and `truncated` says where.' type: object properties: publishers: type: array items: type: object properties: domain: type: string provenance: type: string enum: - declared - crawled - discovered adagentsStatus: type: - string - 'null' enum: - resolved - no_adagents - invalid - error - pending authorizationStatus: type: - string - 'null' enum: - authorized - unauthorized - unknown authorizationReason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized lastSyncedAt: type: - string - 'null' formatCatalogSyncedAt: description: When AAO last returned a definitive format catalog for this publisher. This is independent of the live-origin authorization check. type: - string - 'null' properties: type: array items: type: object properties: propertyKey: type: string propertyId: type: - string - 'null' propertyType: type: - string - 'null' name: type: - string - 'null' identifiers: type: array items: type: object properties: type: type: string value: type: string required: - type - value additionalProperties: false tags: type: array items: type: string provenance: description: 'Origin of the identity record: the publisher-hosted adagents.json, a contributed AAO Registry record awaiting publisher-origin proof, or a property the seller declared conversationally before any publisher-origin declaration exists. Publisher-origin resolution supersedes a seller-declared record with the same property key.' type: string enum: - publisher_adagents - aao_registry - seller_declared authorization: description: 'Per-property authorization. `status: unauthorized` is definite — the publisher domain does not authorize us, so nothing under it is sellable. `authorized` is inherited from the domain (see `grain`), not proven against the agent selector. `unknown` means no publisher-origin declaration backs this property.' type: object properties: status: type: string enum: - authorized - unauthorized - unknown grain: type: string enum: - domain reason: type: - string - 'null' enum: - no_file - file_invalid - agent_not_listed - agent_untyped - agent_not_property_bound - authorized required: - status - grain - reason additionalProperties: false declaredBySellerAt: type: - string - 'null' firstSeenAt: type: string lastSeenAt: type: string required: - propertyKey - propertyId - propertyType - name - identifiers - tags - provenance - authorization - declaredBySellerAt - firstSeenAt - lastSeenAt additionalProperties: false collections: type: array items: type: object properties: collectionId: type: string name: type: - string - 'null' tags: type: array items: type: string provenance: description: 'Origin of the identity record: the publisher-hosted adagents.json, a contributed AAO Registry record awaiting publisher-origin proof, or a property the seller declared conversationally before any publisher-origin declaration exists. Publisher-origin resolution supersedes a seller-declared record with the same property key.' type: string enum: - publisher_adagents - aao_registry - seller_declared firstSeenAt: type: string lastSeenAt: type: string required: - collectionId - name - tags - provenance - firstSeenAt - lastSeenAt additionalProperties: false formats: type: array items: type: object properties: formatKey: type: string formatOptionId: type: - string - 'null' displayName: type: - string - 'null' formatKind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} appliesToPropertyIds: type: array items: type: string appliesToPropertyTags: type: array items: type: string applicablePropertyKeys: type: array items: type: string applicablePropertyKeysTruncated: type: boolean appliesToAllProperties: type: boolean sellerPreference: type: - string - 'null' experimental: type: - boolean - 'null' provenance: type: string enum: - publisher_adagents - aao_registry firstSeenAt: type: string lastSeenAt: type: string required: - formatKey - formatOptionId - displayName - formatKind - params - appliesToPropertyIds - appliesToPropertyTags - applicablePropertyKeys - applicablePropertyKeysTruncated - appliesToAllProperties - sellerPreference - experimental - provenance - firstSeenAt - lastSeenAt additionalProperties: false propertyCount: description: Total live properties on this domain. Greater than properties.length when the response was bounded. type: integer minimum: 0 maximum: 9007199254740991 collectionCount: description: Total live AdCP Collections on this domain. Greater than collections.length when the response was bounded. type: integer minimum: 0 maximum: 9007199254740991 formatCount: description: Total live creative formats on this domain. Greater than formats.length when the response was bounded. type: integer minimum: 0 maximum: 9007199254740991 required: - domain - provenance - adagentsStatus - authorizationStatus - authorizationReason - lastSyncedAt - formatCatalogSyncedAt - properties - collections - formats - propertyCount - collectionCount - formatCount additionalProperties: false totals: type: object properties: publishers: type: integer minimum: 0 maximum: 9007199254740991 authorizedPublishers: type: integer minimum: 0 maximum: 9007199254740991 properties: type: integer minimum: 0 maximum: 9007199254740991 collections: type: integer minimum: 0 maximum: 9007199254740991 formats: type: integer minimum: 0 maximum: 9007199254740991 required: - publishers - authorizedPublishers - properties - collections - formats additionalProperties: false truncated: description: True where the response omitted rows the storefront actually has. Compare the per-publisher counts against the returned arrays to see where. type: object properties: publishers: type: boolean properties: type: boolean collections: type: boolean formats: type: boolean required: - publishers - properties - collections - formats additionalProperties: false coverageApplies: description: False when selling rights come from a platform account connection rather than adagents.json. Do not report an authorization verdict as a problem when this is false. type: boolean required: - publishers - totals - truncated - coverageApplies additionalProperties: false BusinessProfileOutput: description: Operator-supplied business profile captured by Murph during storefront setup. type: object properties: summary: description: One-paragraph natural-language summary of the business (e.g. "30 properties across web, mobile, and CTV, primarily UK, sports and entertainment focus"). type: string maxLength: 2000 agentName: description: Deprecated agent-name field, kept for legacy compatibility only. Prefer the Storefront display name for buyer-facing naming; do not use this to create a separate persona. type: string minLength: 1 maxLength: 80 agentPersonality: description: Deprecated. An agent has no personality of its own — voice belongs to the brand, and is read from the brand manifest (`tone`). Nothing consumes this field; pass null to remove an existing legacy value. type: string minLength: 1 maxLength: 1000 propertyCount: description: Approximate number of owned properties / domains. type: integer minimum: 0 maximum: 10000 channels: description: Channels the operator sells across (ADCP channel codes — display, olv, ctv, social, audio, dooh). maxItems: 16 type: array items: description: Legacy V2 storefront channel code. Values round-trip unchanged; the Discovery Card projection, Marketplace filters, and outbound AdCP capabilities normalize `audio` to canonical `streaming_audio`. type: string enum: - display - olv - ctv - social - audio - dooh regions: description: Primary regions the business operates in (ISO 3166-1 alpha-2 country codes or group codes). example: - UK - EMEA maxItems: 64 type: array items: type: string pattern: ^[A-Z0-9_-]{2,32}$ verticals: description: Topic/vertical focus areas, free-text. example: - sports - entertainment maxItems: 32 type: array items: type: string minLength: 1 maxLength: 80 publisherDomains: description: Publisher domains/properties the Merchandising Agent should be authorized to sell through this Storefront. Omit when unknown; omission does not mean all domains are authorized. Domains are normalized to lowercase and deduplicated. example: - pitchside.co.uk - football.pitchside.co.uk maxItems: 128 type: array items: type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ evidenceUrls: description: URLs the operator pointed Murph at (media kits, about pages, etc.) so a future conversation can re-read the source material. New values must use HTTP(S). maxItems: 16 type: array items: type: string maxLength: 2048 format: uri notes: description: Free-form Murph-captured notes that did not fit into the structured fields. type: string maxLength: 4000 updatedBy: description: Identifier of the agent or user that last wrote this profile (e.g. "murph" or a userId). Audit-only. type: string maxLength: 120 additionalProperties: false EsaRefreshResult: description: Result of manually refreshing a managed ad-server source. `already_running` is informational and carries the upstream sync_run_ids for correlation. type: object properties: status: type: string enum: - started - already_running syncRunIds: default: {} type: object additionalProperties: type: string startedAt: default: null type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ runningSyncTypes: type: array items: type: string required: - status - syncRunIds - startedAt additionalProperties: false StorefrontLiveness: description: The projected storefront liveness verdict (AI-4698) — one derived status computed centrally and consumed by readiness, the seller-setup widget, and the storefront switcher. type: object properties: state: type: string enum: - setup - live - live_attention - live_critical reasonCode: type: string enum: - archived - paused_before_live - paused_after_live - setup_incomplete - settlement_ineligible - catalog_empty_live - go_live_requirement_regressed - degraded_source - trafficking_error - healthy reason: description: 'Human-readable line pairing with the dot, e.g. "Live — attention: pricing feed expires in 5 days" or "Not live — 2 steps remaining". Never shown without the dot naming the state (status-color-language rule 6).' type: string remainingSteps: description: Open go-live blocker count, present only for state "setup". Null for every other state. type: - integer - 'null' minimum: 0 maximum: 9007199254740991 actionPath: description: Application path (relative to the customer root, e.g. "/inventory-sources") of the surface that owns the fix, sourced from the readiness CHECK_ROUTING table. Null when the fix lives on the customer home surface (chat / seller-setup widget). Clients navigate to it; they never invent their own routing. type: - string - 'null' required: - state - reasonCode - reason - remainingSteps - actionPath additionalProperties: false InventorySourceContractFieldGroup: description: Contract fields grouped by source. type: object properties: source: description: Where a module contract field is expected to come from. type: string enum: - MODULE_CONFIG - INVENTORY_FEED - PRODUCT_METADATA - MEDIA_BUY_INPUT - CREATIVE_INPUT - REPORTING_UPLOAD - SYSTEM - MODULE_RESULT fields: type: array items: $ref: '#/components/schemas/InventorySourceContractField' required: - source - fields additionalProperties: false ReserveModularInventoryProductBody: description: Holds capacity against one modular inventory product projection. One of productId or availId is required. type: object properties: productId: type: string availId: type: string mediaBuyId: type: string minLength: 1 packageId: type: string buyerCustomerId: type: integer maximum: 9007199254740991 minimum: 1 requestedImpressions: type: integer maximum: 9007199254740991 minimum: 1 holdMinutes: type: integer maximum: 9007199254740991 minimum: 1 required: - mediaBuyId - buyerCustomerId - requestedImpressions PostCreativeReviewDecisionBody: description: Request body for the operator decide endpoint. Records a terminal decision against a pending creative review row. type: object properties: status: description: Decision to record. Must be `approved` or `rejected` — `revoked` is a separate gesture and is not allowed here. allOf: - $ref: '#/components/schemas/CreativeReviewDecisionStatus' reviewer_notes: description: Optional free-text note from the reviewer (e.g. reason for rejection). Visible to the buyer in their sync_creatives follow-up. type: string maxLength: 2000 required: - status UpdateHouseDiscountBody: description: Partial update for a rate-card discount. Only discountPercent and notes are mutable; house_domain and scope are immutable — delete and recreate to change either. type: object properties: discountPercent: description: Discount percent off the storefront quote for buys whose brand or operator resolves to this domain. 0–100. The larger of this and any buyer-specific instruction wins; the quote is floored at the wholesale cost. example: 20 type: number minimum: 0 maximum: 100 notes: type: - string - 'null' maxLength: 2000 StorefrontCompositionPricingOutput: description: 'Storefront composition pricing settings: fallback guidance percentile plus lightly structured seller pricing facts.' type: object properties: targetPercentile: default: p75 description: 'Deprecated. Historical auction-clearing percentile, retained for explainability only — it no longer sets the price. Pricing is value-led: the Merchandising Agent prices each brief to its value, bounded by wholesale floors and seller ceilings, never anchored to a clearing percentile.' type: string enum: - p50 - p75 - p90 rateCard: description: Seller product-pricing facts. Separate from Scope3 contract rate cards. default: facts: [] type: object properties: currency: description: Default ISO 4217 currency for pricing facts in this storefront rate card. example: USD type: string minLength: 3 maxLength: 3 facts: default: [] maxItems: 500 type: array items: $ref: '#/components/schemas/StorefrontPricingFactOutput' required: - facts additionalProperties: false required: - targetPercentile - rateCard additionalProperties: false StorefrontCapabilities: description: Which AdCP capabilities the storefront advertises to buyers. Product composition is derived from Source product-path readiness and entitlement. type: object properties: offersCreativeReview: description: Surfaces the creative review protocol surface to buyers. `sync_creatives` returns review-status fields; inline creatives in `create_media_buy` / `update_media_buy` flow through the storefront review gate. The operator policy (auto-approve vs manual queue) is separate config — this flag only governs whether the capability is advertised. default: false type: boolean offersCampaignApproval: description: Surfaces the campaign approval protocol surface to buyers. `create_media_buy` and material-change `update_media_buy` may return a submitted-task envelope until the operator decides. The operator policy (auto-approve vs manual queue, material-change threshold) is separate config. default: false type: boolean offersProductComposition: deprecated: true description: Read-only compatibility projection. True only while the customer has merchandising access and at least one active Source has a ready Storefront-built product path (`WHOLESALE`). default: false type: boolean required: - offersCreativeReview - offersCampaignApproval - offersProductComposition additionalProperties: false SetBuyerAutoApproveBody: description: Enable or disable per-buyer media-buy auto-approve for one buyer. The storefront is resolved from the operator's auth context, never the request body. type: object properties: enabled: description: true = this buyer's media buys auto-approve, skipping your review queue and acceptance-policy screen. false = remove the carve-out so the buyer follows the storefront default again. The row is kept either way for audit; it is never deleted. example: true type: boolean reason: description: Freeform operator note for why this buyer is (or is no longer) trusted (e.g. "Goldie/Coke — pre-cleared 2026 always-on"). Omit to preserve the existing note; pass null to clear it. type: - string - 'null' maxLength: 2000 required: - enabled InventorySourceLifecycleProjection: description: Setup-state projection for one lifecycle stage of a modular source module. This is configuration completeness, not a guarantee that runtime inputs, HITL work, or upstream booking/trafficking have completed. type: object properties: stage: description: Lifecycle stage a modular source module may implement. type: string enum: - LIST_ACCOUNTS - INGEST_AVAILS - SYNC_INVENTORY - GET_PRODUCTS - GET_MEDIA_BUYS - GET_ACCOUNT_RESOURCES - RESERVE_AVAILS - FINALIZE_BOOKING - RELEASE_BOOKING - RECONCILE_DELIVERY - SYNC_CREATIVES - TRAFFIC_CAMPAIGN - UPDATE_CAMPAIGN - SYNC_STATUS - IMPORT_REPORTING mode: description: 'How a modular source stage is fulfilled: automated, human-in-the-loop, or unsupported.' type: string enum: - AUTOMATED - HITL - UNSUPPORTED description: type: string workItemKind: type: string outputKeys: type: array items: type: string taskContract: allOf: - $ref: '#/components/schemas/InventorySourceModuleTaskContract' requiredFieldsBySource: type: array items: $ref: '#/components/schemas/InventorySourceContractFieldGroup' missingSetupFieldsBySource: type: array items: $ref: '#/components/schemas/InventorySourceContractFieldGroup' moduleConfigReady: type: boolean required: - stage - mode - description - outputKeys - requiredFieldsBySource - missingSetupFieldsBySource - moduleConfigReady additionalProperties: false BriefArtifactSummary: description: Brief artifact without the request payload (list view). type: object properties: id: type: string storefrontId: type: string buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 source: description: Capture surface (`live` = the AdCP get_products surface). type: string buyingMode: type: string adcpMajorVersion: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 schemaVersion: type: string redactionManifest: $ref: '#/components/schemas/ExchangeArtifactRedactionManifest' digest: description: sha-256 hex over the canonical (sorted-key) JSON of the redacted request — the content address. type: string byteSize: type: integer minimum: -9007199254740991 maximum: 9007199254740991 complete: description: False when the payload exceeded the size limit and only the envelope metadata was retained. type: boolean createdAt: type: string required: - id - storefrontId - buyerCustomerId - source - buyingMode - adcpMajorVersion - schemaVersion - redactionManifest - digest - byteSize - complete - createdAt additionalProperties: false DecideDemandExchangeRevisionBody: description: Approve or reject a revision awaiting approval. expectedSubmissionGeneration must match the revision's current submissionGeneration (as read) — a stale generation is refused rather than applied to a since-changed submission. Approving requires a decider distinct from the revision's composer (maker-checker); rejecting — including the composer withdrawing their own submission — has no such restriction because it creates no buyer-visible evidence. type: object properties: decision: type: string enum: - approve - reject notes: type: - string - 'null' maxLength: 2000 expectedSubmissionGeneration: type: integer minimum: 0 maximum: 9007199254740991 required: - decision - expectedSubmissionGeneration SellerAccountMappingExport: type: object properties: templateCsv: type: string currentBindingsCsv: type: string sourceAccountsCsv: type: string bindingCount: type: integer minimum: 0 maximum: 9007199254740991 sourceAccountCount: type: integer minimum: 0 maximum: 9007199254740991 truncated: type: boolean required: - templateCsv - currentBindingsCsv - sourceAccountsCsv - bindingCount - sourceAccountCount - truncated additionalProperties: false CadentDemoModularSourceResponse: type: object properties: inventorySourceId: type: string sourceId: type: string projection: $ref: '#/components/schemas/InventorySourceRuntimeProjection' products: type: array items: $ref: '#/components/schemas/ModularInventoryProduct' required: - inventorySourceId - sourceId - projection - products additionalProperties: false IntelligenceRunProductFormatExplanation: description: Creative format selected for an explained product. type: object properties: agentUrl: type: - string - 'null' id: type: - string - 'null' required: - agentUrl - id additionalProperties: false DemandExchangePitchRole: type: object properties: productId: description: A composed product id from this same pass. A role naming anything else is dropped at composition time. Never blank. type: string minLength: 1 role: description: The part this product plays in the strategy, in the seller's words (e.g. the anchor, the amplifier, the experiment). Free text because the shape of a plan is the seller's judgment, not a platform enum. type: string minLength: 1 claims: description: 'The fit argument: why this asset, for this outcome, for this buyer. Never empty — a role with no surviving claim is dropped, and the product still renders in the plan appendix from its own persisted row.' minItems: 1 type: array items: $ref: '#/components/schemas/DemandExchangePitchClaim' required: - productId - role - claims additionalProperties: false SellerAccountMappingList: type: object properties: items: type: array items: $ref: '#/components/schemas/SellerAccountMappingItem' sources: type: array items: $ref: '#/components/schemas/SellerAccountMappingSource' page: type: object properties: offset: type: integer minimum: 0 maximum: 9007199254740991 limit: type: integer minimum: 1 maximum: 100 total: type: integer minimum: 0 maximum: 9007199254740991 hasMore: type: boolean required: - offset - limit - total - hasMore additionalProperties: false required: - items - sources - page additionalProperties: false FreeWheelInventoryCapabilitiesResponse: type: object properties: adapter: type: string enum: - freewheel selectorTypes: type: array items: type: object properties: id: type: string enum: - site - site_section - site_group - series - video_group - ad_unit_package - ad_unit_node - standard_attribute label: type: string supportsParentFilter: type: boolean required: - id - label - supportsParentFilter additionalProperties: false pricingModels: type: array items: type: string targetingDimensions: type: array items: type: string optimizationGoals: type: array items: type: string required: - adapter - selectorTypes - pricingModels - targetingDimensions - optimizationGoals additionalProperties: false CreativeReviewEvaluationAnswer: description: Answer to an operator-supplied creative review question. type: object properties: question: description: Question the evaluator answered. type: string minLength: 1 answer: description: Short evaluator answer grounded in the submitted creative. type: string minLength: 1 confidence: description: Evaluator confidence in the answer, from 0 to 1. type: number minimum: 0 maximum: 1 required: - question - answer additionalProperties: false FinalizeModularInventoryBookingResponse: type: object properties: booking: $ref: '#/components/schemas/ReserveModularInventoryProductResponse' executionStatus: type: string enum: - PENDING_TRAFFICKING - BOOKED cadentCampaign: type: object additionalProperties: {} cadentRequestXml: type: string workItems: type: array items: type: object additionalProperties: {} projection: $ref: '#/components/schemas/InventorySourceRuntimeProjection' required: - booking - workItems - projection additionalProperties: false StorefrontOnboardingPlan: description: 'Durable per-storefront onboarding plan: target model + step-completion + phase-transition history.' type: object properties: version: description: Plan document schema version, for forward migration. type: integer minimum: -9007199254740991 maximum: 9007199254740991 target: type: array items: $ref: '#/components/schemas/StorefrontTargetEntry' steps: description: Step-completion records keyed by readiness check id. type: object additionalProperties: $ref: '#/components/schemas/OnboardingPlanStep' phaseTransitions: type: array items: $ref: '#/components/schemas/OnboardingPhaseTransition' lastUpdatedBy: description: Actor of the last write — e.g. "system", "murph", a userId. type: - string - 'null' lastUpdatedAt: type: string required: - version - target - steps - phaseTransitions - lastUpdatedBy - lastUpdatedAt additionalProperties: false ManagedSourceAccountRefreshResult: type: object properties: inventorySourceId: type: string observed: type: integer minimum: 0 maximum: 9007199254740991 archived: type: integer minimum: 0 maximum: 9007199254740991 authoritative: type: boolean truncated: type: boolean required: - inventorySourceId - observed - archived - authoritative - truncated additionalProperties: false HouseDiscountListResponse: description: List of house-scoped buyer-discount rows for a storefront. type: object properties: items: type: array items: $ref: '#/components/schemas/HouseDiscountResponse' total: type: integer minimum: 0 maximum: 9007199254740991 required: - items - total additionalProperties: false FeedRevisionEnvelope: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryFeedRevisionSchema constraints: - FACT_IDS_UNIQUE_WITHIN_SOURCE_REVISION - FACT_SOURCES_MATCH_REVISION_SOURCE - FULL_REPLACEMENT_IS_NOT_PARTIALLY_VALID - COMMITTED_FULL_REPLACEMENT_IS_NOT_EMPTY - INVALID_REVISION_CANNOT_COMMIT required: true description: Inventory feed revision envelope returned by preview, upload, commit, and push endpoints. Matches the InventoryFeedRevisionSchema contract. type: object properties: schemaVersion: type: string enum: - 1.0.0 revisionId: type: string minLength: 1 sourceId: type: string minLength: 1 profileId: type: string minLength: 1 profileVersion: type: string minLength: 1 deliverySemantics: type: string enum: - FULL_REPLACEMENT - PATCH_UPSERT snapshot: type: string minLength: 1 cursor: type: string minLength: 1 observedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ coveredPeriod: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false idempotencyKey: type: string minLength: 1 contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ catalogRevision: type: string minLength: 1 provenance: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: ProvenanceSchema constraints: - FILE_REQUIRES_FILE_NAME - ADAPTER_REQUIRES_ADAPTER_ID required: true type: object properties: actorType: type: string enum: - API - FILE - HUMAN - ADAPTER actorId: type: string minLength: 1 adapterId: type: string minLength: 1 fileName: type: string minLength: 1 requestId: type: string minLength: 1 submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ required: - actorType - submittedAt - contentDigest additionalProperties: false correction: oneOf: - type: object properties: correctionId: type: string minLength: 1 targetType: type: string enum: - REVISION targetRevisionId: type: string minLength: 1 mode: type: string enum: - REPLACEMENT reason: type: string minLength: 1 required: - correctionId - targetType - targetRevisionId - mode - reason additionalProperties: false - type: object properties: correctionId: type: string minLength: 1 targetType: type: string enum: - FACT targetFactId: type: string minLength: 1 mode: type: string enum: - REPLACEMENT - PATCH reason: type: string minLength: 1 required: - correctionId - targetType - targetFactId - mode - reason additionalProperties: false type: object facts: type: array items: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: AvailabilityFactSchema constraints: - SCOPE_SOURCE_MATCHES_FACT_SOURCE - BOOKED_QUANTITY_UNIT_MATCHES_GROSS_UNIT - EMBEDDED_BOOKED_QUANTITY_DOES_NOT_EXCEED_GROSS_CAPACITY - GROSS_REQUIRES_BOOKED_QUANTITY_OR_TEMPORAL_FENCE - UNPROVEN_TEMPORAL_JOIN_IS_NOT_RESERVABLE - TEMPORAL_FENCE_MATCHES_ENCLOSING_FACT - PRODUCT_FORMAT_REQUIRES_PRODUCT_SCOPE required: true type: object properties: factId: type: string minLength: 1 sourceId: type: string minLength: 1 scope: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryScopeRefSchema constraints: - CANONICAL_COLLECTION_MAPPING_REQUIRED - EXACTLY_ONE_CANONICAL_COLLECTION_ID required: true anyOf: - type: object properties: scopeType: type: string enum: - component sourceId: type: string minLength: 1 kind: type: string enum: - placement - ad_unit - property externalId: type: string minLength: 1 required: - scopeType - sourceId - kind - externalId additionalProperties: false - type: object properties: scopeType: type: string enum: - component sourceId: type: string minLength: 1 kind: description: Canonical AdCP content Collection only, such as a series, publication, event series, or rotation. Generic pools and seller groupings are not Collections. type: string enum: - collection externalId: type: string minLength: 1 collectionSelector: description: Required mapping to exactly one Collection declared by publisher_domain in adagents.json. type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ collection_ids: type: array items: type: string required: - publisher_domain - collection_ids additionalProperties: {} required: - scopeType - sourceId - kind - externalId - collectionSelector additionalProperties: false - type: object properties: scopeType: type: string enum: - wholesale_product sourceId: type: string minLength: 1 productId: type: string minLength: 1 required: - scopeType - sourceId - productId additionalProperties: false dimensions: default: {} type: object additionalProperties: {} period: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false observedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ poolId: type: string minLength: 1 availability: type: object properties: basis: type: string enum: - NET_SELLABLE - GROSS quantity: type: object properties: unit: description: Profile-permitted quantity unit. The target profile allowlist remains pending. type: string minLength: 1 amount: type: number minimum: 0 required: - unit - amount additionalProperties: false upstreamBooked: type: object properties: unit: description: Profile-permitted quantity unit. The target profile allowlist remains pending. type: string minLength: 1 amount: type: number minimum: 0 required: - unit - amount additionalProperties: false temporalJoinFence: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: TemporalJoinFenceSchema constraints: - OBSERVED_SKEW_DERIVED_FROM_TIMESTAMPS - MONOTONIC_EVIDENCE_REMAINS_UNPROVEN - STATUS_MATCHES_SELECTED_PROOF - UNPROVEN_REQUIRES_DIAGNOSTIC required: true type: object properties: grossFactId: type: string minLength: 1 bookingFactId: type: string minLength: 1 sourceId: type: string minLength: 1 poolId: type: string minLength: 1 unit: type: string minLength: 1 period: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: InventoryPeriodSchema constraints: - START_BEFORE_END required: true type: object properties: start: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ end: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ required: - start - end additionalProperties: false strategy: type: string enum: - SAME_SNAPSHOT - MONOTONIC_WITHIN_SKEW grossSnapshot: type: string minLength: 1 bookingSnapshot: type: string minLength: 1 grossObservedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ bookingObservedThrough: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ observedSkewSeconds: type: number minimum: 0 status: type: string enum: - PROVEN - UNPROVEN diagnosticCode: type: string minLength: 1 required: - grossFactId - bookingFactId - sourceId - poolId - unit - period - strategy - grossSnapshot - bookingSnapshot - grossObservedThrough - bookingObservedThrough - observedSkewSeconds - status additionalProperties: false reservable: type: boolean required: - basis - quantity - reservable additionalProperties: false pricingOptions: default: [] type: array items: anyOf: - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpm currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - vcpm currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpc currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpcv currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpv currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 max_bid: type: boolean price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: view_threshold: anyOf: - type: number - type: object properties: duration_seconds: type: number minimum: 1 required: - duration_seconds additionalProperties: {} required: - view_threshold additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpp currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: demographic_system: anyOf: - type: string enum: - nielsen - type: string enum: - barb - type: string enum: - agf - type: string enum: - oztam - type: string enum: - mediametrie - type: string enum: - custom demographic: type: string min_points: type: number minimum: 0 required: - demographic additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - cpa event_type: anyOf: - type: string enum: - page_view - type: string enum: - view_content - type: string enum: - select_content - type: string enum: - select_item - type: string enum: - search - type: string enum: - share - type: string enum: - add_to_cart - type: string enum: - remove_from_cart - type: string enum: - viewed_cart - type: string enum: - add_to_wishlist - type: string enum: - initiate_checkout - type: string enum: - add_payment_info - type: string enum: - purchase - type: string enum: - refund - type: string enum: - lead - type: string enum: - qualify_lead - type: string enum: - close_convert_lead - type: string enum: - disqualify_lead - type: string enum: - complete_registration - type: string enum: - subscribe - type: string enum: - follow - type: string enum: - content_view - type: string enum: - watch_milestone - type: string enum: - start_trial - type: string enum: - app_install - type: string enum: - app_launch - type: string enum: - contact - type: string enum: - schedule - type: string enum: - donate - type: string enum: - submit_application - type: string enum: - custom custom_event_name: type: string event_source_id: type: string currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - event_type - currency - fixed_price additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - flat_rate currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: type: type: string enum: - dooh sov_percentage: type: number minimum: 0 maximum: 100 loop_duration_seconds: type: number minimum: 1 min_plays_per_hour: type: number minimum: 1 venue_package: type: string duration_hours: type: number minimum: 0 daypart: type: string estimated_impressions: type: number minimum: 0 required: - type additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency additionalProperties: {} - type: object properties: pricing_option_id: type: string pricing_model: type: string enum: - time currency: type: string pattern: ^[A-Z]{3}$ fixed_price: type: number minimum: 0 floor_price: type: number minimum: 0 price_guidance: type: object properties: p25: type: number minimum: 0 p50: type: number minimum: 0 p75: type: number minimum: 0 p90: type: number minimum: 0 additionalProperties: {} parameters: type: object properties: time_unit: anyOf: - type: string enum: - hour - type: string enum: - day - type: string enum: - week - type: string enum: - month min_duration: type: number minimum: 1 max_duration: type: number minimum: 1 required: - time_unit additionalProperties: {} min_spend_per_package: type: number minimum: 0 price_breakdown: type: object properties: list_price: type: number adjustments: type: array items: type: object additionalProperties: {} required: - list_price - adjustments additionalProperties: {} eligible_adjustments: type: array items: anyOf: - type: string enum: - fee - type: string enum: - discount - type: string enum: - commission - type: string enum: - settlement required: - pricing_option_id - pricing_model - currency - parameters additionalProperties: {} formatOptions: default: [] type: array items: anyOf: - type: object properties: scope: type: string enum: - publisher publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_option_id: type: string required: - scope - publisher_domain - format_option_id additionalProperties: {} - type: object properties: scope: type: string enum: - product format_option_id: type: string publisher_domain: not: {} required: - scope - format_option_id additionalProperties: {} sourceMetadata: default: {} type: object additionalProperties: {} provenance: x-scope3-semantic-validation: vocabulary: urn:scope3:inventory-feed-contracts:semantic-validation:v1 canonicalValidator: ProvenanceSchema constraints: - FILE_REQUIRES_FILE_NAME - ADAPTER_REQUIRES_ADAPTER_ID required: true type: object properties: actorType: type: string enum: - API - FILE - HUMAN - ADAPTER actorId: type: string minLength: 1 adapterId: type: string minLength: 1 fileName: type: string minLength: 1 requestId: type: string minLength: 1 submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$ contentDigest: type: string pattern: ^sha256:[a-f0-9]{64}$ required: - actorType - submittedAt - contentDigest additionalProperties: false required: - factId - sourceId - scope - dimensions - period - observedAt - poolId - availability - pricingOptions - formatOptions - sourceMetadata - provenance additionalProperties: false diagnostics: type: array items: type: object properties: code: type: string minLength: 1 severity: type: string enum: - ERROR - WARNING - INFO scope: type: string enum: - REVISION - ROW - FACT message: type: string minLength: 1 rowIndex: type: integer minimum: 0 maximum: 9007199254740991 factId: type: string minLength: 1 field: type: string minLength: 1 details: type: object additionalProperties: {} required: - code - severity - scope - message additionalProperties: false validationStatus: type: string enum: - VALID - INVALID - PARTIALLY_VALID commitStatus: type: string enum: - PREVIEW - COMMITTED - REJECTED required: - schemaVersion - revisionId - sourceId - profileId - profileVersion - deliverySemantics - idempotencyKey - contentDigest - provenance - facts - diagnostics - validationStatus - commitStatus additionalProperties: false GetBriefArtifactResponse: type: object properties: data: $ref: '#/components/schemas/BriefArtifact' required: - data additionalProperties: false IntelligenceRunUnpricedProductExplanation: description: Composition the model considered but the platform omitted because it could not be priced authoritatively. type: object properties: name: type: - string - 'null' reasoning: type: - string - 'null' reason: type: string bundleIds: type: array items: type: string signalIds: type: array items: type: string required: - name - reasoning - reason - bundleIds - signalIds additionalProperties: false BriefArtifactListResponse: description: Brief artifacts for a storefront, newest first. type: object properties: data: type: array items: $ref: '#/components/schemas/BriefArtifactSummary' meta: $ref: '#/components/schemas/ExchangeArtifactPaginationMeta' required: - data - meta additionalProperties: false SellerAccountBindingFeedRevision: type: object properties: feedId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ revisionId: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ sourceRevision: type: string mode: type: string enum: - snapshot - delta state: type: string enum: - uploading - validating - preview_ready - validation_failed - commit_in_progress - committed - commit_failed - expired - cancelled impact: type: - object - 'null' properties: createCount: type: integer minimum: 0 maximum: 9007199254740991 updateCount: type: integer minimum: 0 maximum: 9007199254740991 archiveCount: type: integer minimum: 0 maximum: 9007199254740991 unchangedCount: type: integer minimum: 0 maximum: 9007199254740991 quarantineCount: type: integer minimum: 0 maximum: 9007199254740991 duplicateCount: type: integer minimum: 0 maximum: 9007199254740991 snapshotAbsenceArchiveCount: type: integer minimum: 0 maximum: 9007199254740991 required: - createCount - updateCount - archiveCount - unchangedCount - quarantineCount - duplicateCount - snapshotAbsenceArchiveCount additionalProperties: false diagnostics: type: array items: type: object properties: rowNumber: type: - integer - 'null' maximum: 9007199254740991 minimum: 1 code: type: string message: type: string required: - rowNumber - code - message additionalProperties: false diagnosticsTruncated: type: boolean uploadExpiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ previewExpiresAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ committedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - feedId - revisionId - sourceRevision - mode - state - impact - diagnostics - diagnosticsTruncated - uploadExpiresAt - previewExpiresAt - committedAt additionalProperties: false AmendDemandExchangeRevisionBody: description: Re-declare posture, price, and product-count overrides and re-compose a draft revision in place through the real merchandising engine. Valid only against a draft (fresh or rejected); clears any prior decision record and counts against the lifetime adjustment cap. type: object properties: overrides: type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false required: - overrides SellerAccountMappingSource: type: object properties: inventorySourceKey: type: string name: type: string executionType: type: string supportsNativeAccounts: type: boolean required: - inventorySourceKey - name - executionType - supportsNativeAccounts additionalProperties: false DiscoverAgentsResponse: type: object properties: domain: type: string operator: description: Agents registered to this operator domain type: object properties: domain: type: string member: type: - object - 'null' properties: slug: type: string display_name: type: string required: - slug - display_name additionalProperties: false agents: type: array items: type: object properties: url: type: string name: type: string type: type: string compliance: type: object additionalProperties: {} storyboards: type: array items: {} authorized_by: type: array items: {} required: - url - name - type additionalProperties: false required: - domain - member - agents additionalProperties: false publisher: description: Publisher record from the AAO registry or the adagents.json fallback type: object properties: domain: type: string member: type: - object - 'null' properties: slug: type: string display_name: type: string required: - slug - display_name additionalProperties: false adagents_valid: type: - boolean - 'null' discovery_method: description: How the live adagents.json was resolved, when one was. `ads_txt_managerdomain` means the domain hosts no file of its own and delegates via its ads.txt managerdomain (e.g. a Raptive/CafeMedia-managed publisher). Absent when no file resolved. type: string enum: - direct - authoritative_location - ads_txt_managerdomain manager_domain: description: Manager domain the file was resolved from when `discovery_method` is `ads_txt_managerdomain` (e.g. cafemedia.com); null otherwise. type: - string - 'null' resolved_url: description: URL the authoritative adagents.json was actually fetched from. type: - string - 'null' properties: type: array items: type: object additionalProperties: {} authorized_agents: type: array items: type: object additionalProperties: {} formats: description: The publisher's self-published creative formats (AdCP 3.1 `formats[]`), read through their canonical adagents.json. Present whenever a live adagents.json resolved; absent when only the registry mirror resolved. type: array items: type: object additionalProperties: {} hosting: description: 'The registry''s hosting verdict: `mode` (self-hosted / AAO-hosted / redirected / invalid / none) and `last_validated` (last crawl time; null = never crawled).' type: object properties: mode: type: string enum: - self - self_invalid - aao_hosted - self_redirected - none last_validated: type: - string - 'null' required: - mode - last_validated additionalProperties: false freshness: description: 'Provenance of the authorization verdict. `source: ''registry''` = the registry''s crawled verdict stood; `source: ''live_origin''` = the verdict lagged so the publisher''s live adagents.json was trusted. `recrawl_requested` marks that a re-crawl was requested to converge the mirror.' type: object properties: source: type: string enum: - registry - live_origin registry_adagents_valid: type: - boolean - 'null' last_validated: type: - string - 'null' recrawl_requested: type: boolean required: - source - registry_adagents_valid - last_validated additionalProperties: false required: - domain - member - adagents_valid - properties - authorized_agents additionalProperties: false required: - domain - operator - publisher additionalProperties: false IntelligenceRunResult: description: 'Outcome envelope: ok on success, error with code/message on failure, skipped when the pipeline short-circuited.' type: object properties: kind: type: string enum: - ok - error - skipped code: type: - string - 'null' message: type: - string - 'null' required: - kind - code - message additionalProperties: false DiscoveryCard: description: Canonical buyer-visible storefront identity, coverage declaration, and optional Advertising Policies disclosure. Unknown coverage never means worldwide or all channels. type: object properties: storefrontId: type: string platformId: type: string storefrontKind: type: string enum: - managed - external_pass_through displayName: type: string logoUrl: type: - string - 'null' logoBackground: type: - string - 'null' enum: - dark-bg - light-bg - transparent-bg description: type: - string - 'null' website: type: - string - 'null' brandColors: type: - object - 'null' additionalProperties: type: string channels: description: Aggregate channel facets for search and display. Do not combine these with aggregate countries as a cross-product coverage promise. type: array items: type: string countries: description: Aggregate ISO 3166-1 alpha-2 country facets for search and display. Do not combine these with aggregate channels as a cross-product coverage promise. type: array items: type: string pattern: ^[A-Z]{2}$ acceptsAllCountries: description: True only when the storefront explicitly accepts briefs from every country. type: boolean coverageDeclarations: description: Channel and country coverage claims preserved at their source boundaries. A combined filter matches only when one declaration satisfies both dimensions. type: array items: description: One source-level coverage claim. Channels and countries are correlated within this declaration; an empty dimension is unknown, not unrestricted. type: object properties: channels: description: Channels accepted by this correlated source declaration. type: array items: type: string countries: description: ISO 3166-1 alpha-2 countries accepted by this correlated source declaration. type: array items: type: string pattern: ^[A-Z]{2}$ acceptsAllCountries: description: True only when this correlated source declaration explicitly accepts every country. type: boolean required: - channels - countries - acceptsAllCountries additionalProperties: false advertisingPolicies: type: - string - 'null' maxLength: 10000 coverage: type: object properties: channels: type: string enum: - declared - partial - unknown countries: type: string enum: - declared - partial - unknown required: - channels - countries additionalProperties: false provenance: type: object properties: identity: type: object properties: displayName: type: string enum: - operator - registry - upstream_capabilities - unknown logoUrl: type: string enum: - operator - registry - upstream_capabilities - unknown description: type: string enum: - operator - registry - upstream_capabilities - unknown website: type: string enum: - operator - registry - upstream_capabilities - unknown brandColors: type: string enum: - operator - registry - upstream_capabilities - unknown required: - displayName - logoUrl - description - website - brandColors additionalProperties: false coverage: type: object properties: channels: type: string enum: - operator - registry - upstream_capabilities - unknown countries: type: string enum: - operator - registry - upstream_capabilities - unknown required: - channels - countries additionalProperties: false advertisingPolicies: type: string enum: - operator - registry - upstream_capabilities - unknown required: - identity - coverage - advertisingPolicies additionalProperties: false required: - storefrontId - platformId - storefrontKind - displayName - logoUrl - logoBackground - description - website - brandColors - channels - countries - acceptsAllCountries - coverageDeclarations - advertisingPolicies - coverage - provenance additionalProperties: false SellingDoctrineThresholds: type: object properties: minimumCategoryFit: description: The share of the brief's stated category and channel terms this catalogue must actually serve before the seller pitches in full. 1 means only a brief the catalogue covers completely earns a pitch; 0 means every brief does. type: number minimum: 0 maximum: 1 counterAppetite: description: How far below the pitch bar the seller will still answer, with a counter-pitch instead of a pass. 0 never counters — a brief that misses the bar is declined. 1 counters everything the catalogue touches at all. type: number minimum: 0 maximum: 1 floorPosture: description: What to do when the buyer states a budget and no composed line could be priced. 'hold_floor' declines rather than negotiate from nothing; 'flex_floor' counters and invites a re-brief. type: string enum: - hold_floor - flex_floor required: - minimumCategoryFit - counterAppetite - floorPosture additionalProperties: false EsaCanonicalProductFormatOption: description: URL-free AdCP 3.1 product format declaration. Canonical formats use format_kind plus params and never agent_url; publisher-backed options pair format_option_id with publisher_domain. type: object properties: format_option_id: type: string publisher_domain: description: Publisher catalog namespace for format_option_id. Omit for product-local format options. type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_kind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} required: - format_kind - params additionalProperties: false LaunchEsaResponse: description: Minted launch URL for the managed ad-server source admin UI. type: object properties: url: description: Single-use signed URL that drops the caller into the upstream managed-source admin UI. The signature is short-lived; clients should redirect immediately. type: string format: uri required: - url additionalProperties: false AdServerConfig: description: Discriminated union of supported ad-server configurations. Includes credentials for adapter types that authenticate with publisher-supplied credentials (FreeWheel, SpringServe); those credentials are forwarded to the managed ad-server source and never persisted on the local connection row. oneOf: - $ref: '#/components/schemas/GamAdServerConfig' - $ref: '#/components/schemas/FreeWheelAdServerConfig' - $ref: '#/components/schemas/SpringServeAdServerConfig' - $ref: '#/components/schemas/AdsWizzAdServerConfig' type: object discriminator: propertyName: type mapping: google_ad_manager: '#/components/schemas/GamAdServerConfig' freewheel: '#/components/schemas/FreeWheelAdServerConfig' springserve: '#/components/schemas/SpringServeAdServerConfig' adswizz: '#/components/schemas/AdsWizzAdServerConfig' InventorySourceModuleTaskContract: description: Runtime task contract emitted by a modular inventory source module for operator and Murph work queues. type: object properties: taskId: type: string stage: description: Lifecycle stage a modular source module may implement. type: string enum: - LIST_ACCOUNTS - INGEST_AVAILS - SYNC_INVENTORY - GET_PRODUCTS - GET_MEDIA_BUYS - GET_ACCOUNT_RESOURCES - RESERVE_AVAILS - FINALIZE_BOOKING - RELEASE_BOOKING - RECONCILE_DELIVERY - SYNC_CREATIVES - TRAFFIC_CAMPAIGN - UPDATE_CAMPAIGN - SYNC_STATUS - IMPORT_REPORTING automationMode: description: How a module runtime task is expected to complete, including whether a human fallback can complete it. type: string enum: - AUTOMATED - HITL - AUTOMATED_WITH_HITL_FALLBACK - UNSUPPORTED completionPolicy: description: Who is allowed to complete the runtime task represented by this lifecycle stage. type: string enum: - NO_TASK - MODULE_COMPLETES - HUMAN_COMPLETES - MODULE_OR_HUMAN_COMPLETES defaultActor: description: Default actor expected to perform this runtime task. type: string enum: - system - module - operator - murph workItemKind: type: string fallbackWorkItemKind: type: string operatorAction: type: string requiredInputKeys: type: array items: type: string requiredResultKeys: type: array items: type: string outputKeys: type: array items: type: string idempotencyKeyFields: type: array items: type: string retryable: type: boolean blocksStage: type: boolean required: - taskId - stage - automationMode - completionPolicy - defaultActor - requiredInputKeys - requiredResultKeys - outputKeys - retryable - blocksStage additionalProperties: false ModularInventoryProductsResponse: type: object properties: products: type: array items: $ref: '#/components/schemas/ModularInventoryProduct' required: - products additionalProperties: false ModularAvailsPreview: type: object properties: previewOnly: type: boolean enum: - true inputSource: type: string parsedAvailCount: type: integer minimum: 0 maximum: 9007199254740991 rejectedRowCount: type: integer minimum: 0 maximum: 9007199254740991 warningCount: type: integer minimum: 0 maximum: 9007199254740991 avails: type: array items: type: object properties: collectionId: description: Exact legacy field name for a static-avails v1 compatibility grouping/container identifier. It does not establish AdCP Collection identity. type: string minLength: 1 collectionName: description: Exact legacy field name for a static-avails v1 compatibility grouping/container label. It does not establish AdCP Collection identity. type: string minLength: 1 collectionDescription: description: Exact legacy field name for a static-avails v1 compatibility grouping/container description. It does not establish AdCP Collection identity. type: - string - 'null' channel: type: - string - 'null' formatOptions: minItems: 1 type: array items: type: object properties: format_option_id: type: string publisher_domain: description: Publisher catalog namespace for format_option_id. Omit for product-local format options. type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ format_kind: anyOf: - type: string enum: - image - type: string enum: - html5 - type: string enum: - display_tag - type: string enum: - image_carousel - type: string enum: - video_hosted - type: string enum: - video_vast - type: string enum: - audio_hosted - type: string enum: - audio_daast - type: string enum: - sponsored_placement - type: string enum: - native_in_feed - type: string enum: - responsive_creative - type: string enum: - agent_placement - type: string enum: - custom params: type: object additionalProperties: {} required: - format_kind - params additionalProperties: false publisherProperties: minItems: 1 type: array items: anyOf: - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - all required: - selection_type additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ selection_type: type: string enum: - by_id property_ids: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - publisher_domain - selection_type - property_ids additionalProperties: {} - type: object properties: publisher_domain: type: string pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$ publisher_domains: type: array items: type: string selection_type: type: string enum: - by_tag property_tags: type: array items: type: string pattern: ^[a-z0-9_]+$ required: - selection_type - property_tags additionalProperties: {} availId: type: string minLength: 1 name: type: string minLength: 1 startTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ endTime: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ impressionsCapacity: type: integer minimum: 0 maximum: 9007199254740991 upstreamBookedImpressions: type: integer minimum: 0 maximum: 9007199254740991 cpm: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 targeting: type: object additionalProperties: {} sourceMetadata: type: object additionalProperties: {} required: - collectionId - collectionName - formatOptions - publisherProperties - availId - name - startTime - endTime - impressionsCapacity additionalProperties: false rejectedRows: type: array items: type: object properties: rowNumber: type: integer maximum: 9007199254740991 minimum: 1 rawRow: type: object additionalProperties: {} diagnostics: minItems: 1 type: array items: type: object properties: rowNumber: type: integer maximum: 9007199254740991 minimum: 1 field: type: string minLength: 1 code: type: string enum: - REQUIRED_FIELD_MISSING - INVALID_DATE_TIME - INVALID_NUMBER - INVALID_CURRENCY - INVALID_CANONICAL_FORMATS - INVALID_PUBLISHER_PROPERTIES - GROSS_CAPACITY_NORMALIZED - GROSS_CAPACITY_ASSUMED_NET message: type: string minLength: 1 required: - rowNumber - code - message additionalProperties: false required: - rowNumber - rawRow - diagnostics additionalProperties: false warnings: type: array items: type: object properties: rowNumber: type: integer maximum: 9007199254740991 minimum: 1 field: type: string minLength: 1 code: type: string enum: - REQUIRED_FIELD_MISSING - INVALID_DATE_TIME - INVALID_NUMBER - INVALID_CURRENCY - INVALID_CANONICAL_FORMATS - INVALID_PUBLISHER_PROPERTIES - GROSS_CAPACITY_NORMALIZED - GROSS_CAPACITY_ASSUMED_NET message: type: string minLength: 1 required: - rowNumber - code - message additionalProperties: false note: type: string required: - previewOnly - inputSource - parsedAvailCount - rejectedRowCount - warningCount - avails - rejectedRows - warnings - note additionalProperties: false SourceForwardResult: description: Per-source outcome of one forwarding leg. type: object properties: sourceId: description: Identifier of the inventory source this leg targeted. type: string status: description: The source's AdCP task status for the forward call (e.g. `completed`, `failed`, `pending_start`). Says whether the source accepted the buy, not where the buy sits in its lifecycle. type: string upstreamMediaBuyId: description: Identifier the source assigned to the buy on its side. Present only once the source has accepted and recorded it. type: string required: - sourceId - status additionalProperties: {} DiagnosisAction: description: 'Typed inline action: `recheck` carries a portable named operation, `reconnect` opens the ad-server connect task, `open` opens a focused setup surface, `none` means nothing for the seller to do.' anyOf: - $ref: '#/components/schemas/SourceRecheckAction' - type: object properties: kind: type: string enum: - reconnect label: type: string required: - kind - label additionalProperties: false - type: object properties: kind: type: string enum: - open label: type: string required: - kind - label additionalProperties: false - type: object properties: kind: type: string enum: - none required: - kind additionalProperties: false PrepareSellerAccountBindingFeed: type: object properties: sourceRevision: type: string minLength: 1 maxLength: 200 mode: type: string enum: - snapshot - delta baseRevisionId: type: - string - 'null' format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ coveredInventorySourceKeys: minItems: 1 maxItems: 100 type: array items: type: string minLength: 1 maxLength: 128 file: type: object properties: name: type: string enum: - source_account_bindings.csv sha256: type: string pattern: ^[a-f0-9]{64}$ sizeBytes: type: integer maximum: 10000000 minimum: 1 rowCount: type: integer minimum: 0 maximum: 10000 required: - name - sha256 - sizeBytes - rowCount required: - sourceRevision - mode - coveredInventorySourceKeys - file additionalProperties: false CreateAcceptancePolicyBody: description: Request body for creating a new acceptance-policy version and optionally activating it atomically. type: object properties: content: description: Markdown acceptance policy used to evaluate advertiser categories, buyer-submitted creatives, and approval workflow requirements. type: string minLength: 1 maxLength: 50000 notes: description: Operator note describing why this version was created. Not surfaced to buyers. type: string maxLength: 2000 activate: description: When true, atomically make the new version active as part of the create. Defaults to false. default: false type: boolean required: - content LabelIntelligenceRunBody: description: Attach (or replace) an evaluator label on an intelligence-run row. The label is freeform JSON the eval workflow defines. type: object properties: label: type: object additionalProperties: {} required: - label ProposalArtifactSummary: description: Proposal artifact without the response/snapshot payloads (list view). type: object properties: id: type: string storefrontId: type: string buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 briefArtifactId: description: The brief artifact this proposal answered; null when the brief capture failed (the link is soft and never invented). type: - string - 'null' chefComposeRunId: description: The intelligence run that composed this proposal; null when the run record failed. type: - string - 'null' version: type: integer minimum: -9007199254740991 maximum: 9007199254740991 supersedesArtifactId: type: - string - 'null' schemaVersion: type: string redactionManifest: $ref: '#/components/schemas/ExchangeArtifactRedactionManifest' digest: type: string byteSize: type: integer minimum: -9007199254740991 maximum: 9007199254740991 complete: type: boolean createdAt: type: string required: - id - storefrontId - buyerCustomerId - briefArtifactId - chefComposeRunId - version - supersedesArtifactId - schemaVersion - redactionManifest - digest - byteSize - complete - createdAt additionalProperties: false SellerAccountMappingSummary: type: object properties: relationshipCount: type: integer minimum: 0 maximum: 9007199254740991 activeSourceCount: type: integer minimum: 0 maximum: 9007199254740991 coverage: type: object properties: bound: type: integer minimum: 0 maximum: 9007199254740991 not_required: type: integer minimum: 0 maximum: 9007199254740991 missing: type: integer minimum: 0 maximum: 9007199254740991 ambiguous: type: integer minimum: 0 maximum: 9007199254740991 stale: type: integer minimum: 0 maximum: 9007199254740991 required: - bound - not_required - missing - ambiguous - stale additionalProperties: false required: - relationshipCount - activeSourceCount - coverage additionalProperties: false PendingOperationsAwaitingSourceItem: description: One buy the source accepted asynchronously and is still moderating. type: object properties: mediaBuyId: type: string sourceId: type: string sourceName: type: - string - 'null' buyer: type: object properties: customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: type: - string - 'null' required: - customerId - name additionalProperties: false since: description: Waiting on source moderation since this instant. type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ taskId: description: The source's task id for the pending acceptance — their reference. type: - string - 'null' required: - mediaBuyId - sourceId - sourceName - buyer - since - taskId additionalProperties: false SellerForwardOutcome: description: 'How far forwarding to the underlying source(s) got: not_forwarded (nothing dispatched yet), all_completed (every source accepted inline), all_submitted (every source accepted asynchronously and is still finishing acceptance), partial (some sources accepted, some did not), failed (dispatch attempted, no source accepted).' type: string enum: - not_forwarded - all_completed - all_submitted - partial - failed StorefrontReadinessResponse: description: Storefront readiness assessment type: object properties: platformId: type: string status: description: Overall storefront readiness status type: string enum: - ready - blocked isPaused: description: Compatibility-named seller intake hold. True blocks discovery, new buys, and buyer edits but does not pause existing delivery. False is neutral and does not itself imply readiness. type: boolean canTransact: description: 'Canonical effective availability: non-paused, non-archived, and every current blocker complete.' type: boolean effectiveStatus: description: Derived storefront status. Never stored and never copied from adcp_agent.status. type: string enum: - archived - paused - blocked - live availabilityGuidance: description: Canonical explanation for a top-level paused or archived admission control. Check-specific blockers remain in checks[].guidance. allOf: - $ref: '#/components/schemas/ReadinessBlockingGuidance' checks: type: array items: $ref: '#/components/schemas/ReadinessCheck' publisherDomains: description: Configured publisher domains with current authorization and property-resolution status. type: array items: $ref: '#/components/schemas/StorefrontPublisherDomainReadiness' demandCoverage: $ref: '#/components/schemas/DemandCoverageSummary' sourceDiagnostics: type: array items: $ref: '#/components/schemas/SourceDiagnostics' diagnoses: description: Typed source-health diagnoses. Only `seller`-owned entries are tasks; `scope3`/`vendor`-owned entries are informational and never block readiness. type: array items: $ref: '#/components/schemas/SourceHealthDiagnosis' phase: $ref: '#/components/schemas/OnboardingPhase' onboardingPlan: description: The persisted onboarding plan (target model + phase-transition history), loaded and reconciled on this read. allOf: - $ref: '#/components/schemas/StorefrontOnboardingPlan' liveness: description: The projected storefront liveness verdict (AI-4698) — one derived status over settlement invariants, go-live blockers, post-live degradation, and multi-source/mode honesty. Authoritative for every surface (seller-setup widget, storefront switcher) when present. allOf: - $ref: '#/components/schemas/StorefrontLiveness' required: - platformId - status - isPaused - canTransact - effectiveStatus - checks - publisherDomains - demandCoverage - sourceDiagnostics - diagnoses - phase additionalProperties: false DemandExchange: description: 'The full story of one brief → proposal → result exchange: brief facts, ordered passes with product allocation + pricing rows, per-pass outcome, and an exchange-level result. Every number is traceable to a persisted artifact or outcome record; missing inputs render unavailable, never 0.' type: object properties: exchangeId: description: The compose-run id anchoring this exchange. type: string buyer: type: - string - 'null' provenance: description: 'How this brief reached the ledger: ''live'' = an AdCP get_products call from a buyer agent, ''uploaded'' = a seller-uploaded RFP/brief confirmed in chat (AI-4728). Reflects this run''s own intake origin (AI-5025), falling back to the linked brief artifact''s source column only for historical runs recorded before that origin was captured. Null when neither is available. An uploaded exchange is never presented as live buyer demand.' type: - string - 'null' runPurpose: description: 'The compose run''s own run_purpose. null means the run predates classification (an absent historical value, treated as real demand); a persisted value outside this build''s known set surfaces as ''unknown'', which consumers must treat exactly like a synthetic purpose — never as a live buyer. Together with provenance this is how the pass classifies the exchange into a matrix-ruling cell: any purpose other than ''live''/''unclassified'' (including ''unknown'') is never real buyer demand, regardless of what provenance says.' allOf: - $ref: '#/components/schemas/DemandExchangeRunPurpose' briefText: type: - string - 'null' briefFacts: allOf: - $ref: '#/components/schemas/DemandExchangeBriefFacts' briefArtifactId: type: - string - 'null' briefArtifactAvailable: description: False when no brief artifact was captured (historical run). Readers must say "brief unavailable" rather than reconstruct it. type: boolean proposalArtifactId: description: The most recent proposal artifact id (from the full persisted pass list, not the capped slice), for reference. type: - string - 'null' passesTruncated: description: True when the run had more persisted proposal artifacts than the pass cap; the widget discloses the cap rather than silently dropping older passes. type: boolean result: description: 'Exchange-level commercial result. Derivation rule: won if ANY pass is won; else lost if the most recent decided pass is lost; else pending. With one run per exchange today this equals the run outcome.' type: string enum: - closed_won - closed_lost - pending wonValue: description: Money won across the exchange, one entry per currency (both-or-nothing amount+currency per the AI-4726 money model; never summed cross-currency). Null when nothing won recorded a priced outcome. type: - array - 'null' items: type: object properties: amount: type: number currency: type: string required: - amount - currency additionalProperties: false statedBudget: description: The buyer's stated budget range. Surfaced at the exchange level so a lost exchange still shows the demand it represented (the AI-4726 lost-demand visibility). allOf: - $ref: '#/components/schemas/DemandExchangeBudgetRange' ledBy: type: - string - 'null' enum: - agent - human grade: type: - string - 'null' enum: - A - B - C - D - F feedback: type: - string - 'null' receivedAt: type: string respondedAt: type: - string - 'null' grouping: $ref: '#/components/schemas/DemandExchangeGrouping' passes: type: array items: $ref: '#/components/schemas/DemandExchangePass' adjustable: description: Whether Adjust is available on this exchange right now, from the shared eligibility rule the compose mutation re-checks (AI-5571). False for anything but classified live demand with a retained brief, active operating instructions, and lifetime adjustments remaining. type: boolean adjustabilityReason: description: Null when adjustable is true. Otherwise the server's own named reason — never a bare not-found — so the pass renders Adjust disabled with the reason instead of a button that fails when pressed. type: - string - 'null' enum: - not_live_demand - brief_not_retained - no_operating_instructions - adjustment_limit_reached - open_revision_exists openRevision: description: The exchange's open draft or awaiting-approval revision, surfaced separately from the pass list — a seller-composed revision is never mistaken for a captured pass until it is actually sent. allOf: - $ref: '#/components/schemas/DemandExchangeRevision' required: - exchangeId - buyer - provenance - runPurpose - briefText - briefFacts - briefArtifactId - briefArtifactAvailable - proposalArtifactId - passesTruncated - result - wonValue - statedBudget - ledBy - grade - feedback - receivedAt - respondedAt - grouping - passes - adjustable - adjustabilityReason - openRevision additionalProperties: false DemandExchangeBidDecision: type: object properties: disposition: description: What the seller's doctrine decided to do with this brief. 'pitch' = the brief fits, argue it in full. 'counter_pitch' = the literal ask does not fit but a credible reframe exists, carried by the honest counter. 'pass' = decline, with a short branded decline in the pitch's `decline` section. type: string enum: - pitch - counter_pitch - pass decidedBy: description: Which rule reached the disposition. 'no_products' = nothing composed, so there was no plan to argue for. 'floor_posture' = the buyer stated a budget and no line could be priced against it. 'no_comparable_terms' = the brief named no vertical or channel that could be compared, so fit was not measurable and the pass pitched. 'no_doctrine_configured' = this storefront has never set a selling doctrine, so there was no gate to apply and the brief was answered exactly as it would have been before doctrine existed. 'category_fit_met' / 'counter_appetite' / 'category_fit_below_pass_floor' = measured fit against the doctrine's pitch bar and the pass floor its counter appetite implies. type: string enum: - no_products - floor_posture - no_comparable_terms - no_doctrine_configured - category_fit_met - counter_appetite - category_fit_below_pass_floor threshold: description: The 0–1 fit share the measured fit was compared against, or null for the structural rules no threshold could have changed. type: - number - 'null' minimum: 0 maximum: 1 categoryFit: description: The measured share, from 0 to 1, of the brief's comparable terms this catalogue serves. Null means nothing comparable was named — genuinely not measurable, NOT a fit of zero, and readers must never render the two the same way. type: - number - 'null' minimum: 0 maximum: 1 doctrineVersion: description: The operating-instructions version whose doctrine decided this, or null when the platform default stood in. Same version a claim citing `operating_instructions` names, so the disposition receipt and a claim chip open the same Playbook. type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 doctrineVariant: description: 'The named doctrine the deciding thresholds correspond to. Derived from the thresholds themselves rather than the label the seller picked: a seller who adopts a named variant and then edits a number is running their own doctrine, which is what ''custom'' says.' type: string enum: - house_default - premium_scarcity_house - volume_partner - consultative - custom fedBy: description: 'The openable receipt behind this decision: the Playbook version whose doctrine decided, resolved to its owner Task exactly like a product row''s chips and a pitch claim''s chips. Same shape, same ledger, same code path — ''why did we pass on this brief?'' opens the thing that decided it rather than describing it. Empty when the platform default decided (there is no seller-authored version to open), or when the decision''s provenance write did not land.' default: [] type: array items: $ref: '#/components/schemas/DemandExchangeFedBy' required: - disposition - decidedBy - threshold - categoryFit - doctrineVersion - doctrineVariant - fedBy additionalProperties: false SellerAccountGrantReviewItem: type: object properties: grantId: type: string accountId: type: string displayName: type: string operatorDomain: type: string brandDomain: type: string sandbox: type: boolean buyerCustomerId: type: string requestedBilling: type: string version: type: integer maximum: 9007199254740991 minimum: 1 createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - grantId - accountId - displayName - operatorDomain - brandDomain - sandbox - buyerCustomerId - requestedBilling - version - createdAt additionalProperties: false AgentComplianceResult: description: Compliance assessment for a single agent type: object properties: agentId: type: string agentUrl: type: string passed: type: boolean tracks: type: array items: $ref: '#/components/schemas/ComplianceTrackResult' summary: description: One-line compliance headline type: string observations: description: Advisory observations from compliance checks type: array items: type: object properties: category: type: string severity: type: string enum: - info - suggestion - warning - error message: type: string required: - category - severity - message additionalProperties: false durationMs: type: number error: type: string required: - agentId - agentUrl - passed - tracks - summary - observations - durationMs additionalProperties: false ReleaseModularInventoryBookingBody: description: Releases a held modular inventory reservation or cancels a locally booked reservation. type: object properties: mediaBuyId: type: string minLength: 1 packageId: type: string buyerCustomerId: type: integer maximum: 9007199254740991 minimum: 1 availId: type: string minLength: 1 required: - mediaBuyId - buyerCustomerId - availId ReserveModularInventoryProductResponse: type: object properties: bookingId: type: string availId: type: string mediaBuyId: type: string packageId: type: string requestedImpressions: type: integer maximum: 9007199254740991 minimum: 1 status: type: string enum: - HELD - BOOKED - RELEASED - CANCELLED required: - bookingId - availId - mediaBuyId - packageId - requestedImpressions - status additionalProperties: false LearnedDefaultPostureResponse: description: The storefront learned default posture after a pin or clear operation. type: object properties: learnedDefault: description: The saved learned default posture, or null when none is set (e.g. after a clear). type: - object - 'null' properties: posture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror reason: type: - string - 'null' checkedAt: type: - string - 'null' required: - posture - reason - checkedAt additionalProperties: false required: - learnedDefault additionalProperties: false UploadModularAvailsFeedBody: type: object properties: file: format: binary description: CSV, JSON, XLS, or XLSX file, up to 10 MB. type: string required: - file ComposeDemandExchangeRevisionBody: description: Declare posture, price, and product-count overrides in the merchandising simulator's own grammar and compose a silent draft revision through the real merchandising engine. type: object properties: overrides: type: object properties: posture: type: object properties: selectedPosture: type: string enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - selectedPosture additionalProperties: false pricing: type: object properties: priceAdjustmentBasisPoints: type: integer minimum: -10000 maximum: 100000 floorCpm: type: object properties: amount: type: number minimum: 0 currency: type: string minLength: 3 maxLength: 3 required: - amount - currency additionalProperties: false additionalProperties: false rules: type: object properties: requiredBundleIds: maxItems: 100 type: array items: type: string minLength: 1 excludedBundleIds: maxItems: 100 type: array items: type: string minLength: 1 maxProducts: type: integer maximum: 100 minimum: 1 additionalProperties: false additionalProperties: false required: - overrides ReadinessBlockingGuidance: description: Canonical cause, buyer-path effect, evidence, and resolution for an incomplete hard readiness requirement. type: object properties: coverage: description: '`complete` when the canonical readiness catalog owns a resolution; `missing` makes an unregistered future blocker explicit.' type: string enum: - complete - missing stage: description: The blocker stops buyer-serving work at storefront transaction admission, before an inventory source receives `get_products`. type: string enum: - before_source_dispatch why: description: Current cause, using the check's live evidence. type: string effect: description: Buyer-path consequence. Consumers render this instead of inferring demand from source call counts. type: string fix: description: Smallest honest action that clears the blocker. type: string subjects: type: array items: type: object properties: kind: type: string enum: - inventory_source id: type: - string - 'null' name: type: string required: - kind - id - name additionalProperties: false evidence: oneOf: - type: object properties: kind: type: string enum: - billing_compatibility requiredSupportedBilling: type: string enum: - agent incompatibleSources: type: array items: type: object properties: sourceId: type: - string - 'null' sourceName: type: string advertisedSupportedBillings: type: array items: type: string required: - sourceId - sourceName - advertisedSupportedBillings additionalProperties: false required: - kind - requiredSupportedBilling - incompatibleSources additionalProperties: false type: object required: - coverage - stage - why - effect - fix - subjects additionalProperties: false IntelligenceRunNegotiationAnalytics: description: 'Compact seller-facing analytics derived from the buyer request and storefront response: refine counts, ask categories, product ids shown, and acknowledgement counts.' CreateBuyerInstructionsBody: description: Request body for creating a buyer-instructions row. (operatorDomain, brandDomain) is unique per storefront — duplicate scopes fail with a validation error; use PATCH instead. type: object properties: operatorDomain: description: 'Operator (e.g. agency/DSP) the row applies to, or null to match any operator. (operatorDomain, brandDomain) form the scope — one of the four shapes: house (both null), house+brand (brand only), operator (operator only), operator+brand (both).' example: nike.com type: - string - 'null' minLength: 1 maxLength: 253 brandDomain: description: Advertiser brand the row applies to, or null to match any brand. See operatorDomain for the four scope shapes. example: nike.com type: - string - 'null' minLength: 1 maxLength: 253 discountPercent: description: Discount percent off the storefront base price for buys that match this scope. Null = no discount contribution. example: 15 type: - number - 'null' minimum: 0 maximum: 100 notes: description: Freeform notes the Merchandising Agent applies to compositions for matching buyers (e.g. "Brand requires GroupM viewability ≥ 70%"). Null = no notes contribution. type: - string - 'null' maxLength: 2000 countries: description: Optional country filter. Null = row applies regardless of country. example: - US - CA minItems: 1 type: - array - 'null' items: type: string pattern: ^[A-Z]{2}$ required: - operatorDomain - brandDomain - discountPercent - notes - countries UpdateInventorySourceBody: description: Request body for updating an inventory source. Only the documented fields are writable. Unknown v2 extension keys are tolerated and ignored solely for legacy client compatibility. type: object properties: name: description: Updated display name type: string minLength: 1 maxLength: 255 executionType: description: '`AGENT` inventory sources can be updated here. `MANAGED_SALES_AGENT` and `MODULAR_SOURCE` lifecycle transitions happen through dedicated flows; `LINKED_STOREFRONT` sources are resolved at runtime from the ambient wholesale pool and have no lifecycle endpoint. Storefront-level `ADAPTER` dispatch is configured on the storefront, not as an inventory source.' type: string enum: - AGENT status: description: Updated source status (PENDING → ACTIVE, ACTIVE → DISABLED) type: string enum: - PENDING - ACTIVE - DISABLED description: description: Updated agent description type: string maxLength: 2000 endpointUrl: description: Updated agent endpoint URL type: string maxLength: 2048 format: uri protocol: description: Updated agent protocol type: string enum: - MCP - A2A authenticationType: description: Updated agent authentication type type: string enum: - API_KEY - NO_AUTH - JWT - OAUTH - BASIC_AUTH auth: description: 'Updated authentication credentials. Omit to keep existing credentials. For BASIC_AUTH agents, use { type: "basic", username, password }.' anyOf: - type: object properties: type: type: string enum: - jwt privateKey: type: string minLength: 1 issuer: type: string minLength: 1 subject: type: string minLength: 1 keyId: type: string minLength: 1 scope: type: string minLength: 1 tokenEndpointUrl: type: string format: uri audienceUrl: type: string format: uri algorithm: type: string enum: - ES256 - RS256 environment: type: string required: - type - privateKey - issuer - subject - keyId - scope - tokenEndpointUrl - audienceUrl - type: object properties: type: type: string enum: - bearer - apikey - api_key token: type: string minLength: 1 required: - type - token - type: object properties: type: type: string enum: - basic username: type: string minLength: 1 password: type: string required: - type - username - password - type: object properties: {} additionalProperties: false oauthAudience: description: OAuth audience / resource indicator for OAUTH agents (the protected-resource URI the agent gateway validates). Setting it re-mints the token with this `aud` claim and returns a fresh authorization URL to re-consent. Sent as both Auth0 `audience` and RFC 8707 `resource`. example: https://platform.example.com type: string maxLength: 2048 format: uri additionalProperties: false EsaCapability: description: Separately provisioned ad-server capability that can be re-checked. type: string enum: - reporting - forecasting DemandExchangeRevisionApproval: type: object properties: gate: description: Null before the revision is ever submitted. Cleared back to null (with decidedAt/decidedByUserId/notes) on every resubmission after a rejection, so a pending revision never reports a decision nobody has made against THIS submission. type: - string - 'null' enum: - pending - approved - rejected decidedByUserId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 decidedAt: type: - string - 'null' notes: type: - string - 'null' required: - gate - decidedByUserId - decidedAt - notes additionalProperties: false SetLearnedDefaultPostureBody: description: Pin or clear the storefront learned default negotiation posture. type: object properties: posture: description: The negotiation posture to pin as the storefront learned default, or null to clear it (revert to none). type: - string - 'null' enum: - direct_fit - hold_value - value_preserving_compromise - tradeoff_ladder - price_first - wholesale_mirror required: - posture SellerAccountMappingCoverage: type: object properties: inventorySourceKey: type: string coverage: type: string enum: - bound - not_required - missing - ambiguous - stale sourceExternalAccountId: type: - string - 'null' bindingVersion: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 nativeAccountGeneration: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 nativeAccountStatus: type: - string - 'null' listingVersion: type: - string - 'null' lastSeenAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ candidateCount: type: integer minimum: 0 maximum: 9007199254740991 required: - inventorySourceKey - coverage - sourceExternalAccountId - bindingVersion - nativeAccountGeneration - nativeAccountStatus - listingVersion - lastSeenAt - candidateCount additionalProperties: false EsaTestConnectionResponse: description: Result of probing the upstream managed ad-server source for reachability. type: object properties: success: type: boolean error: type: - string - 'null' errorCode: type: - string - 'null' remediation: type: - string - 'null' details: type: - object - 'null' additionalProperties: {} capabilityChecks: type: array items: $ref: '#/components/schemas/EsaAdapterCapabilityCheck' testedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - success - error - testedAt additionalProperties: false FeedModularSourceResponse: type: object properties: inventorySourceId: type: string sourceId: type: string projection: $ref: '#/components/schemas/InventorySourceRuntimeProjection' required: - inventorySourceId - sourceId - projection additionalProperties: false CommitSellerAccountBindingFeed: type: object properties: previewToken: type: string pattern: ^[A-Za-z0-9_-]{32,256}$ idempotencyKey: type: string minLength: 8 maxLength: 128 pattern: ^[A-Za-z0-9._:-]+$ partial: default: none type: string enum: - none - accepted_delta required: - previewToken - idempotencyKey additionalProperties: false SellerTimelineLeg: description: One source leg of the buy, as seen from the storefront. type: object properties: sourceId: type: string sourceName: type: - string - 'null' sourceKind: type: string currentStatus: description: Latest persisted upstream status for this leg. type: - string - 'null' forwardedAt: type: - string - 'null' responseReceivedAt: type: - string - 'null' theirReference: description: The source's own ids for this exchange — quote these to the source; they can look them up directly. type: object properties: mediaBuyId: type: - string - 'null' taskId: type: - string - 'null' required: - mediaBuyId - taskId additionalProperties: false platformReference: description: 'The Scope3 reference for this exchange: the create idempotency key (`sf:::`) paired with the request timestamp. Quote both together — the key is stable across the buy’s life, requests are not.' type: object properties: idempotencyKey: type: - string - 'null' requestedAt: type: - string - 'null' required: - idempotencyKey - requestedAt additionalProperties: false stages: description: Stages this leg reached, lifecycle order. type: array items: $ref: '#/components/schemas/SellerTimelineStage' forwardedPayload: description: 'The exact AdCP request sent to this source, minus platform-internal fields (webhook/push-notification config and signing material are projected out server-side). `{"pruned": true}` when retention removed the payload.' type: - object - 'null' additionalProperties: {} responsePayload: description: 'The source''s latest response as persisted, minus platform-internal fields. `{"pruned": true}` when retention removed the payload.' type: - object - 'null' additionalProperties: {} payloadHighlights: description: Trafficker-grade summary of the forwarded payload; null when nothing was forwarded. allOf: - $ref: '#/components/schemas/SellerPayloadHighlights' replayed: description: True when the captured response was an idempotency-cache replay — a historical snapshot, not current state. type: - boolean - 'null' note: description: Structural note (e.g. "the forward never succeeded — no route exists for this source"). type: - string - 'null' required: - sourceId - sourceName - sourceKind - currentStatus - forwardedAt - responseReceivedAt - theirReference - platformReference - stages - forwardedPayload - responsePayload - payloadHighlights - replayed - note additionalProperties: false StorefrontPricingFactHintsOutput: description: Optional best-effort hints for matching a seller pricing fact. These are not product assembly rules; the Merchandising Agent still reasons over the natural-language appliesWhen field. type: object properties: channels: description: AdCP channel codes (e.g. `olv`, `ctv`, `dooh`) this fact applies to. Unlike the free-text hint categories, channels are matched as EXACT codes against the product's seller-declared `channels` plus the broad channel family inferred from its creative format kind — never as substrings of names, ids, or tags. So a fact scoped to `["ctv"]` applies only to products that declare `ctv`; a `video_hosted` format on its own resolves to the broad `video` family, which cannot distinguish `olv` from `ctv`. Within the array any code may match (OR); across hint categories every populated category must match (AND). maxItems: 32 type: array items: type: string minLength: 1 maxLength: 80 creativeTerms: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 publisherDomains: maxItems: 128 type: array items: type: string maxLength: 253 pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ countries: maxItems: 64 type: array items: type: string pattern: ^[A-Z0-9_-]{2,32}$ advertiserVerticals: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 seasonality: maxItems: 32 type: array items: type: string minLength: 1 maxLength: 120 signalTags: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 placementTags: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 120 additionalProperties: false SellerAccountMappingItem: type: object properties: accountId: type: string operatorDomain: type: string brandDomain: type: string displayName: type: string sandbox: type: boolean grants: type: array items: type: object properties: status: type: string billing: type: - string - 'null' count: type: integer minimum: 0 maximum: 9007199254740991 required: - status - billing - count additionalProperties: false sourceCoverage: type: array items: $ref: '#/components/schemas/SellerAccountMappingCoverage' required: - accountId - operatorDomain - brandDomain - displayName - sandbox - grants - sourceCoverage additionalProperties: false IntelligenceRunResponse: description: 'A single storefront intelligence run: inputs, prompt, raw + parsed LLM output, persisted product ids, and result envelope.' type: object properties: id: type: string purpose: allOf: - $ref: '#/components/schemas/IntelligenceRunPurpose' storefrontId: type: string buyerCustomerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 operatingInstructionsVersion: type: integer minimum: -9007199254740991 maximum: 9007199254740991 buyerScope: $ref: '#/components/schemas/IntelligenceRunBuyerScope' buyerInstructions: $ref: '#/components/schemas/IntelligenceRunBuyerInstructions' brief: type: - string - 'null' buyingMode: type: string inventorySnapshot: {} prompt: type: string rawLlmOutput: {} parsedOutput: {} runRationale: type: - string - 'null' explanation: $ref: '#/components/schemas/IntelligenceRunExplanation' composedProductIds: type: array items: type: string result: $ref: '#/components/schemas/IntelligenceRunResult' modelProvider: type: - string - 'null' modelName: type: string durationMs: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 refineSnapshot: {} refinementAppliedSnapshot: {} requestAsks: type: array items: type: string shownProductsSnapshot: {} pricingSummary: {} negotiationSummary: $ref: '#/components/schemas/IntelligenceRunNegotiationAnalytics' commercialOutcome: {} evalLabel: {} createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - id - purpose - storefrontId - buyerCustomerId - operatingInstructionsVersion - buyerScope - buyerInstructions - brief - buyingMode - inventorySnapshot - prompt - rawLlmOutput - parsedOutput - runRationale - explanation - composedProductIds - result - modelProvider - modelName - durationMs - refineSnapshot - refinementAppliedSnapshot - requestAsks - shownProductsSnapshot - pricingSummary - negotiationSummary - commercialOutcome - evalLabel - createdAt additionalProperties: false StorefrontPricingFactPriceOutput: description: Value-pricing anchor extracted from seller rate cards, media kits, or operator instructions. type: object properties: pricingModel: description: AdCP pricing model this pricing fact anchors, sourced from the AdCP SDK vocabulary. A price shape the protocol has no model for — share of voice, a day-part premium — is a product-coverage gap to report, not a value to store. default: cpm type: string enum: - cpm - vcpm - cpc - cpcv - cpv - cpp - cpa - flat_rate - time currency: description: ISO 4217 currency for this pricing fact. Falls back to the storefront pricing currency when omitted. example: USD type: string minLength: 3 maxLength: 3 targetPrice: description: Preferred value-based buyer-facing price for this fact. This is a value anchor, not a cost-plus markup. type: number exclusiveMinimum: 0 floorPrice: description: Hard minimum buyer-facing price when this fact applies. Composition also floors at wholesale cost/floor. type: number minimum: 0 ceilingPrice: description: Optional maximum buyer-facing price when this fact applies. type: number exclusiveMinimum: 0 required: - pricingModel additionalProperties: false EsaOperationalIssue: description: A derived private operational issue for the managed ad-server source. These issues are computed by Interchange from the upstream status feed and are intended for the storefront operator. type: object properties: code: type: string severity: type: string enum: - warning - critical message: type: string affects: type: array items: type: string enum: - discovery - delivery - setup configurePath: type: - string - 'null' required: - code - severity - message - affects additionalProperties: false BuyerAutoApproveEligibleBuyer: description: A storefront-scoped buyer that is eligible for a per-buyer auto-approve override. type: object properties: buyerCustomerId: description: Customer id of a buyer that has submitted at least one media buy to this storefront. example: 804 type: integer maximum: 9007199254740991 minimum: 1 buyerName: description: Resolved buyer company/name for operator confirmation. Null if it cannot be resolved. example: Coca-Cola type: - string - 'null' mediaBuyCount: description: Number of media buys this buyer has submitted to the storefront. example: 12 type: integer maximum: 9007199254740991 minimum: 1 lastMediaBuyAt: description: When this buyer most recently submitted a media buy to the storefront. type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - buyerCustomerId - buyerName - mediaBuyCount - lastMediaBuyAt additionalProperties: false SellingDoctrineResponse: description: 'The doctrine an operating-instructions version carries, always resolved: a version with none reads the platform default with `isDefault: true`, so a reader never has to decide what absence means.' type: object properties: variant: type: string enum: - house_default - premium_scarcity_house - volume_partner - consultative - custom thresholds: $ref: '#/components/schemas/SellingDoctrineThresholds' isDefault: description: True when this version carries no stored doctrine and the platform default is standing in. A storefront is "configured" for doctrine purposes only once this is false on its active version. type: boolean required: - variant - thresholds - isDefault additionalProperties: false SellingDoctrineBody: description: 'The selling doctrine to store on this version. Either adopt one of the three named strategies — ''premium_scarcity_house'' (qualify hard, pass often, hold price), ''volume_partner'' (counter nearly everything, lead with packaging math), or ''consultative'' (counter-first, heavy honest counter, invite a re-brief) — or state the thresholds yourself. Supply EXACTLY ONE of `variant` or `thresholds` — a request carrying both, or neither, is rejected rather than resolved by precedence, because either resolution would silently discard half of what the caller asked for. Thresholds that match no named strategy read back as ''custom''. The platform''s own balance, ''house_default'', is not adoptable by name: it is what applies when no doctrine is set, so clear the doctrine to return to it.' anyOf: - $ref: '#/components/schemas/SellingDoctrineAdoptVariant' - $ref: '#/components/schemas/SellingDoctrineSetThresholds' DemandExchangePass: type: object properties: passId: type: string sequence: description: 1-based order of this pass within the exchange. type: integer minimum: -9007199254740991 maximum: 9007199254740991 version: description: Proposal artifact version within its supersedes chain. type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 kind: description: The run's buying mode ('brief' for a first response, 'refine' for a renegotiation pass). type: string createdAt: type: string planName: type: - string - 'null' planBriefAlignment: type: - string - 'null' planCount: description: How many media plans the proposal carried. Allocation is read from one selected plan (the committed plan if present, else the first draft); when this exceeds 1, a product unallocated here may be allocated in another plan and the widget discloses that rather than conflating the two. type: integer minimum: -9007199254740991 maximum: 9007199254740991 captureState: description: 'How completely this pass was persisted: ''captured'' = full response and snapshots stored; ''truncated'' = a proposal artifact exists but its response or product snapshots exceeded the size limit, so some detail (e.g. per-product snapshots) is absent though product rows still render; ''unavailable'' = no proposal artifact was captured for the run (historical / predates capture). Readers word the banner from this so a truncated pass is never described as predating capture.' type: string enum: - captured - truncated - unavailable artifactAvailable: description: True when a proposal response was persisted and product rows can render (captureState captured or truncated). False when no response was captured (captureState unavailable) — products render as unavailable, never reconstructed. type: boolean products: type: array items: $ref: '#/components/schemas/DemandExchangeProduct' productsTruncated: description: True when the pass had more products than the response cap; the widget discloses the cap rather than silently dropping rows. type: boolean outcome: $ref: '#/components/schemas/DemandExchangePassOutcome' origin: description: '''seller_adjusted'' when this pass was captured from a cleared AI-5571 revision send; ''agent'' otherwise. States authorship per pass so a seller-adjusted revision can never read as the agent''s first response.' type: string enum: - agent - seller_adjusted fedBy: description: 'The seller''s ingredients the engine resolved once for this whole pass — the Playbook version it composed under and the buyer''s resolved terms. Separate from a product''s own fedBy because these genuinely have no per-product attribution: they collapse into one prompt, and claiming otherwise would be an invention. Empty for a pass with no persisted provenance.' default: [] type: array items: $ref: '#/components/schemas/DemandExchangeFedBy' pitch: description: 'The composed argument for this pass (AI-5869), or null when none was composed — a pass that predates the pitch model, one whose composer failed or timed out, one for a seller not yet enrolled, one still composing, or one whose pitch lookup itself failed. Null renders exactly as the pass rendered before pitches existed: the plan, and nothing invented around it. `pitchStatus` says WHY it is null; `pitch` itself never changes shape.' default: null allOf: - $ref: '#/components/schemas/DemandExchangePitch' pitchStatus: description: 'The pitch''s lifecycle state, additive to `pitch` so a seller can tell the absences apart instead of reading one undifferentiated null: ''ready'' if and only if `pitch` is non-null; ''pending'' means the composer dispatched and has not resolved yet (durably recorded — a crash does not silently drop this to absent); ''absent'' means it resolved with no narrative, or was never dispatched; ''unavailable'' means the pitch lookup itself failed or timed out — a transient read fault, never a claim about whether a pitch exists. Render ''unavailable'' exactly like ''absent'': silence, never an error banner — it is not seller-actionable. A pass captured before this field existed reads as ''absent'' with `pitchAbsentReason: predates_pitch`, derived from the pass''s own timestamp rather than persisted.' default: absent type: string enum: - pending - ready - absent - unavailable pitchAbsentReason: description: 'Bounded, seller-safe reason `pitchStatus` is ''absent'' — never present for ''ready'', ''pending'', or ''unavailable'', never raw error text. ''not_enrolled'' = the storefront-pitch-composer flag was off for this seller (or, derived rather than persisted, no pitch row exists at all for a pass composed after the pitch model existed). ''composing_failed'' = a real model or verification fault. ''nothing_grounded'' = the composer answered but no claim survived citation grounding or the independent entailment check. ''superseded'' = a newer composition generation overtook this one before it resolved. ''timeout'' = the composer''s deadline was exceeded, or the crash-recovery retry sweep gave up after its one permitted retry. ''predates_pitch'' = derived, never persisted: this pass was composed before the pitch model existed at all, so it could never have had a row. ''unavailable'' carries no reason code at all — see `pitchStatus`.' default: null type: - string - 'null' enum: - not_enrolled - composing_failed - nothing_grounded - superseded - timeout - predates_pitch bidDecision: description: 'The qualification judgment this pass composed under (AI-5870), or null when none was recorded — a pass that predates the decision stage, or one composed for a seller not enrolled in the composer. Independent of `pitch`: a decision exists even when the narrative stage then failed, because ''we passed on this brief'' is a fact about the pass rather than about the composer''s luck. Readers render a ''pass'' honestly — the decline, never an empty pitch.' default: null allOf: - $ref: '#/components/schemas/DemandExchangeBidDecision' required: - passId - sequence - version - kind - createdAt - planName - planBriefAlignment - planCount - captureState - artifactAvailable - products - productsTruncated - outcome - origin - fedBy - pitch - pitchStatus - pitchAbsentReason - bidDecision additionalProperties: false SourceCardPosture: description: Server-owned seller posture for one source card. This is a bounded presentation verdict, not a universal source readiness boolean. oneOf: - type: object properties: state: type: string enum: - connected reasonCode: type: string enum: - connected explanation: type: string minLength: 1 required: - state - reasonCode - explanation additionalProperties: false - type: object properties: state: type: string enum: - needs_setup reasonCode: type: string enum: - source_not_active - authentication_required - products_unsupported - products_missing explanation: type: string minLength: 1 required: - state - reasonCode - explanation additionalProperties: false - type: object properties: state: type: string enum: - needs_attention reasonCode: type: string enum: - products_unverified - health_degraded - health_unverified explanation: type: string minLength: 1 required: - state - reasonCode - explanation additionalProperties: false type: object PendingOperationsCreativeReviewItem: description: One creative waiting on operator review. type: object properties: creativeId: type: string mediaBuyId: type: - string - 'null' buyer: type: object properties: customerId: type: - integer - 'null' minimum: -9007199254740991 maximum: 9007199254740991 name: type: - string - 'null' required: - customerId - name additionalProperties: false submittedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - creativeId - mediaBuyId - buyer - submittedAt additionalProperties: false EsaConnection: description: Storefront → managed ad-server source connection. A storefront can have multiple connections, each addressed by `id`. type: object properties: id: description: Stable id for this managed ad-server source. Use this id to address per-source actions (provision, deactivate, save ad-server config, etc.). A customer can have multiple managed sources. type: string customerId: description: Owning customer/storefront id. type: integer minimum: -9007199254740991 maximum: 9007199254740991 tenantId: description: Upstream managed-source id for the managed ad-server source. Null until provisioning succeeds. type: - string - 'null' mcpUrl: description: MCP endpoint exposed by the provisioned managed ad-server source. May be a relative path (e.g. `/mcp/`) — the consumer composes the absolute URL using the upstream base URL. type: - string - 'null' a2aUrl: description: A2A endpoint exposed by the provisioned managed ad-server source. May be a relative path (e.g. `/a2a`) — see `mcpUrl` for resolution. type: - string - 'null' adServer: description: Publisher-supplied ad-server config. Null if not yet collected. allOf: - $ref: '#/components/schemas/AdServerConfigView' serviceAccountEmail: description: Per-customer service-account email the publisher must grant access to in their ad server. Created when ad-server config is saved. Surfaced so the UI can show it during onboarding. type: - string - 'null' format: email pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$ lastError: description: Failure reason from the most recent provisioning or test-connection attempt. type: - string - 'null' lastErrorCode: description: Machine-readable classification of the most recent provisioning failure. `ADAPTER_NETWORK_NOT_FOUND` (typo), `ADAPTER_PERMISSION_DENIED` (GAM grant still propagating), `ADAPTER_INVALID_CREDENTIALS` (storefront service account broken), `ADAPTER_INVALID_CONFIG` (bad field-level config), and `ADAPTER_CONNECTION_FAILED` (transient blip) are the adapter probe failures. `INTERNAL_ERROR` indicates an upstream or platform problem. Null when there has been no failure or after a successful provision. type: - string - 'null' lastTestedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ provisionedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ deactivatedAt: type: - string - 'null' format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ createdAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ updatedAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ inventorySync: description: Cached inventory-sync state. Null when no signal has landed yet (no webhook delivered and no /status poll has run). allOf: - $ref: '#/components/schemas/EsaInventorySync' required: - id - customerId - tenantId - mcpUrl - a2aUrl - adServer - serviceAccountEmail - lastError - lastErrorCode - lastTestedAt - provisionedAt - deactivatedAt - createdAt - updatedAt - inventorySync additionalProperties: false ExchangeArtifactPaginationMeta: description: Offset pagination envelope shared by the list endpoints. type: object properties: pagination: type: object properties: skip: type: integer minimum: 0 maximum: 9007199254740991 take: type: integer minimum: 1 maximum: 9007199254740991 total: type: integer minimum: 0 maximum: 9007199254740991 hasMore: type: boolean required: - skip - take - total - hasMore additionalProperties: false required: - pagination additionalProperties: false OnboardingPhase: description: 'Seller onboarding phase, derived live from setup-mode + readiness: `pass_through` (a finished-products sales agent — no rungs) or the Crawl → Walk → Run progression for composition storefronts. Orients the seller ("you are in Phase 1 of 3").' type: string enum: - pass_through - crawl - walk - run securitySchemes: bearerAuth: type: http scheme: bearer description: API key or access token