> ## Documentation Index
> Fetch the complete documentation index at: https://docs.interchange.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Update storefront

> Update the storefront configuration.



## OpenAPI

````yaml /v2/storefront-api-v2.yaml put /storefront
openapi: 3.0.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
security: []
tags:
  - name: Account
    description: Account management, service tokens, and preferences
  - name: Storefront
    description: Manage storefront and inventory sources
  - name: Storefront Agents
    description: List and manage registered sales, signals, and outcomes agents
  - name: Storefront Activity
    description: Audit log of configuration and inventory changes on the storefront
  - name: Storefront Billing
    description: Payout bank details and billing configuration for storefronts
  - name: AI Usage
    description: Storefront AI token usage visibility by model
  - name: MCP
    description: Model Context Protocol endpoints
paths:
  /storefront:
    servers:
      - url: https://api.interchange.io/api/v2
        description: Production server
    put:
      tags:
        - Storefront
      summary: Update storefront
      description: Update the storefront configuration.
      operationId: updateStorefront
      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: >-
                    Seller-owned pause override. New storefronts default to
                    false; effective transaction availability is derived from
                    pause, 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}$
                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
                  example: scope3.com
                  type: string
                  minLength: 1
                  maxLength: 255
                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.
                  nullable: true
                  type: string
                  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 businessProfile.regions,
                    projected onto the storefront card and qualification path.
                    Prefer businessProfile.regions. When both fields are sent
                    they must match. Mix of ISO 3166-1 alpha-2 country codes and
                    group codes (WORLDWIDE, EMEA, NORAM, LATAM, APAC, EU).
                  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
                  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: >-
                      ADCP channel code. `olv` is "online video"; the full set
                      is display, olv, ctv, social, audio, dooh.
                    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 demand
                    signals (RFPs, prospective briefs, weekly digests). Must be
                    set together with `demandContactEmail`. Pass null to clear
                    (both fields must be cleared together).
                  example: Pia Eberhardt
                  nullable: true
                  type: string
                  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
                  nullable: true
                  type: string
                  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: >-
                    Patch one or more capability flags. Rejected with VALIDATION
                    error if the storefront is locked because it has
                    ad-server-backed inventory sources and the patch would turn
                    any capability off.
                  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:
                      description: >-
                        Storefront composes sellable Products from underlying
                        inventory building blocks instead of passing raw
                        products through. Required for ad-server-backed sources
                        because raw ad-server inventory must be merchandised
                        into buyer-ready products — descriptions, pricing, and
                        packaging happen in the composition layer.
                      default: false
                      type: boolean
                setupIntent:
                  description: >-
                    Record the operator's declared selling intent. Unless
                    `capabilities` is patched explicitly in the same request,
                    this applies the matching preset: 'sell_through_scope3'
                    turns product composition on; 'third_party_connect' turns
                    all capability flags off (clean pass-through). Rejected with
                    VALIDATION error if set to 'third_party_connect' on a
                    storefront with ad-server-backed inventory sources — an
                    embedded sales agent is not a pass-through.
                  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: >-
                    Operator-supplied business profile captured during Murph-led
                    setup. Pass null to clear.
                  nullable: true
                  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
      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'
      security:
        - bearerAuth: []
components:
  schemas:
    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'
    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: >-
            Operator-supplied voice and merchandising guidance for buyer-facing
            interactions and reports. This is tone guidance for the
            Merchandising Agent, not a separate named persona.
          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: >-
              ADCP channel code. `olv` is "online video"; the full set is
              display, olv, ctv, social, audio, dooh.
            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.
          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
    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
          nullable: true
          type: string
        operatorDomain:
          description: Canonical operator domain
          example: scope3.com
          nullable: true
          type: string
        brandName:
          description: Brand name from AAO registry
          example: Scope3
          nullable: true
          type: string
        logoUrl:
          description: Logo URL from brand.json
          nullable: true
          type: string
        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.
          nullable: true
          type: string
          enum:
            - dark-bg
            - light-bg
            - transparent-bg
        membershipStatus:
          description: AAO membership tier. Null when the operator has not set a value.
          nullable: true
          type: string
          enum:
            - AAO_FOUNDING_MEMBER
            - AAO_MEMBER
            - NONE
        regions:
          description: >-
            Current Business Profile regions projected for storefront-card and
            qualification consumers, with the legacy regions column used only
            when no profile regions exist.
          type: array
          items:
            type: string
        description:
          description: Operator-curated description (overrides brand.json).
          nullable: true
          type: string
        channels:
          description: ADCP channel codes the storefront offers.
          type: array
          items:
            type: string
        website:
          description: Operator-curated website URL (overrides brand.json).
          nullable: true
          type: string
        demandContactName:
          description: Demand contact name. Null when the operator has not set one.
          nullable: true
          type: string
        demandContactEmail:
          description: Demand contact email. Null when the operator has not set one.
          nullable: true
          type: string
        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.
          nullable: true
          type: string
          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.
          nullable: true
          type: string
          enum:
            - sales
            - creative
            - signals
            - measurement
            - optimization
            - composite
        adapterCredentialMode:
          description: >-
            Adapter credential mode when routingMode is `ADAPTER`; null
            otherwise.
          nullable: true
          type: string
          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: >-
            Seller-owned pause override. 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.
          nullable: true
          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))$
        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: >-
            Which AdCP capabilities the storefront advertises. Locked on for
            ad-server-backed storefronts; opt-in for third-party.
          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`.
          nullable: true
          type: string
          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: >-
            True when the storefront has at least one ad-server-backed inventory
            source (`executionType=MANAGED_SALES_AGENT`). Locked storefronts
            reject capability writes that would turn any capability off.
          type: boolean
        advertiseAsAgent:
          description: >-
            Derived: `capabilitiesLocked || any(capabilities)`. When true, the
            storefront exposes itself as an AdCP agent and buyers should call
            the storefront URL. When false, the storefront is not advertised as
            a public agent; pass-through behavior is handled by the storefront
            wrapper when a buyer call reaches it.
          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.
          nullable: true
          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.
          nullable: true
          type: string
        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
        - description
        - channels
        - website
        - demandContactName
        - demandContactEmail
        - operatorDomainVerified
        - routingMode
        - adapterProviderType
        - adapterSourceKind
        - adapterCredentialMode
        - plan
        - transacting
        - isPaused
        - archivedAt
        - displayStatus
        - capabilities
        - compositionPricing
        - creativeApproval
        - mediaBuyApproval
        - capabilitiesLocked
        - advertiseAsAgent
        - createdAt
        - updatedAt
        - businessProfile
      additionalProperties: false
    ErrorResponse:
      description: Standard error response
      type: object
      properties:
        data:
          type: string
          nullable: true
          enum:
            - null
        error:
          $ref: '#/components/schemas/ApiError'
      required:
        - data
        - error
      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
    StorefrontCapabilities:
      description: >-
        Which AdCP capabilities the storefront advertises to buyers.
        Ad-server-backed storefronts have all three locked on; third-party
        storefronts default all off (passthrough).
      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:
          description: >-
            Storefront composes sellable Products from underlying inventory
            building blocks instead of passing raw products through. Required
            for ad-server-backed sources because raw ad-server inventory must be
            merchandised into buyer-ready products — descriptions, pricing, and
            packaging happen in the composition layer.
          default: false
          type: boolean
      required:
        - offersCreativeReview
        - offersCampaignApproval
        - offersProductComposition
      additionalProperties: false
    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
    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: >-
            Operator-supplied voice and merchandising guidance for buyer-facing
            interactions and reports. This is tone guidance for the
            Merchandising Agent, not a separate named persona.
          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: >-
              ADCP channel code. `olv` is "online video"; the full set is
              display, olv, ctv, social, audio, dooh.
            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.
          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
    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
    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
    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, such as cpm, vcpm,
            cpcv, cpv, cpc, cpa, flat_rate, time, or dooh.
          default: cpm
          type: string
          minLength: 1
          maxLength: 40
        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
          minimum: 0
          exclusiveMinimum: true
        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
          minimum: 0
          exclusiveMinimum: true
    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
    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
    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, such as cpm, vcpm,
            cpcv, cpv, cpc, cpa, flat_rate, time, or dooh.
          default: cpm
          type: string
          minLength: 1
          maxLength: 40
        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
          minimum: 0
          exclusiveMinimum: true
        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
          minimum: 0
          exclusiveMinimum: true
      required:
        - pricingModel
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key or access token

````