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

# Apply one reviewed sandbox-to-Live promotion plan

> Requires a production br_ API key with sandbox_promotions:apply, the exact studio grant, Idempotency-Key, and the reviewed plan version plus SHA-256. Content-Type must be application/json and the strict body limit is 32 KiB. Convex atomically rechecks current Live revisions and returns 409 if any conflict prevents the whole apply; a conflict never reports or implies partial success. A preparing or blocked plan cannot be applied.



## OpenAPI

````yaml https://api.batchrelay.com/openapi.json post /v1/studios/{studio_id}/sandbox-promotions/{promotion_id}/apply
openapi: 3.1.0
info:
  description: >-
    Provider-neutral print catalog and prepared-media validation. This document
    covers only routes owned by the Go service; it deliberately excludes
    migration-proxied order lifecycle routes and all provider payloads.
  license:
    name: Proprietary
    url: https://github.com/SENTINELITE/Batch-Relay-Go/blob/main/README.md
  title: Batch Relay API
  version: 1.0.1
servers:
  - url: https://api.batchrelay.com
security: []
tags:
  - description: Service health and the public API description.
    name: System
  - description: Test Mode session creation and API credential entry points.
    name: Authentication
  - description: >-
      Provider-neutral canonical catalog resources and platform-owned semantic
      definitions.
    name: Catalog
  - description: Studio-scoped guest checkout-link management.
    name: Checkout links
  - description: >-
      One-way operational event messages. Alert emails contain no message body
      and recipients read messages after Batch Relay authentication.
    name: Studio messages
  - description: >-
      Explicit, reviewable sandbox-to-Live promotion plans for forms, catalog,
      and storefront configuration.
    name: Sandbox promotions
  - description: Provider-neutral validation, quoting, and order lifecycle operations.
    name: Print orders
  - description: Managed fulfillment asset ingestion and metadata.
    name: Managed assets
  - description: Studio-scoped original asset upload sessions and objects.
    name: Studio assets
  - description: Prepared and confirmed event roster team changes.
    name: Event team changes
  - description: Authenticated studio, event, and form-management operations.
    name: Studio management
  - description: >-
      Authenticated studio retail catalog management. Draft and publication
      lifecycles are explicit per product or package.
    name: Studio catalog
  - description: >-
      Authenticated singular storefront assortment management. PATCH atomically
      publishes a new immutable assortment revision; no storefront draft
      lifecycle exists yet.
    name: Storefront
  - description: Managed media used by the studio retail catalog.
    name: Studio catalog assets
  - description: Template rendering job creation and retrieval.
    name: Template renders
  - description: >-
      Published browser-side template packages and short-lived server proof
      renders. Preview artifacts are never fulfillment artwork.
    name: Browser previews
  - description: API account and credential administration.
    name: API accounts
paths:
  /v1/studios/{studio_id}/sandbox-promotions/{promotion_id}/apply:
    parameters:
      - $ref: '#/components/parameters/ClientSurface'
      - $ref: '#/components/parameters/ClientVersion'
      - $ref: '#/components/parameters/InvocationMode'
    post:
      tags:
        - Sandbox promotions
      summary: Apply one reviewed sandbox-to-Live promotion plan
      description: >-
        Requires a production br_ API key with sandbox_promotions:apply, the
        exact studio grant, Idempotency-Key, and the reviewed plan version plus
        SHA-256. Content-Type must be application/json and the strict body limit
        is 32 KiB. Convex atomically rechecks current Live revisions and returns
        409 if any conflict prevents the whole apply; a conflict never reports
        or implies partial success. A preparing or blocked plan cannot be
        applied.
      operationId: applySandboxPromotion
      parameters:
        - $ref: '#/components/parameters/StudioID'
        - $ref: '#/components/parameters/SandboxPromotionID'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        content:
          application/json:
            examples:
              reviewed_plan:
                value:
                  expected_plan_version: 2
                  plan_sha256: >-
                    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
            schema:
              $ref: '#/components/schemas/SandboxPromotionApplyRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SandboxPromotion'
          description: Applied promotion status
        '400':
          $ref: '#/components/responses/IdempotencyKeyRequired'
        '401':
          $ref: '#/components/responses/APIKeyAuthenticationRequired'
        '403':
          $ref: '#/components/responses/SandboxPromotionForbidden'
        '404':
          $ref: '#/components/responses/SandboxPromotionNotFound'
        '409':
          $ref: '#/components/responses/SandboxPromotionConflict'
        '422':
          $ref: '#/components/responses/InvalidSandboxPromotion'
        '502':
          $ref: '#/components/responses/SandboxPromotionFailed'
        '503':
          $ref: '#/components/responses/SandboxPromotionUnavailable'
      security:
        - bearerAuth: []
components:
  parameters:
    ClientSurface:
      description: >-
        Untrusted optional analytics hint naming the calling client surface. It
        never affects authorization, routing, pricing, or behavior.
      in: header
      name: X-BatchRelay-Client-Surface
      required: false
      schema:
        maxLength: 100
        minLength: 1
        type: string
    ClientVersion:
      description: >-
        Untrusted optional analytics hint naming the calling client version. It
        never affects authorization, routing, pricing, or behavior.
      in: header
      name: X-BatchRelay-Client-Version
      required: false
      schema:
        maxLength: 100
        minLength: 1
        type: string
    InvocationMode:
      description: >-
        Untrusted optional analytics hint naming the invocation mode. It never
        affects authorization, routing, pricing, or behavior.
      in: header
      name: X-BatchRelay-Invocation-Mode
      required: false
      schema:
        maxLength: 100
        minLength: 1
        type: string
    StudioID:
      description: >-
        Stable public studio ID beginning with stu_. The API never selects a
        studio implicitly; a local CLI profile name is not a studio ID.
      in: path
      name: studio_id
      required: true
      schema:
        maxLength: 256
        minLength: 5
        pattern: ^stu_[A-Za-z0-9_-]+$
        type: string
    SandboxPromotionID:
      description: Opaque public promotion identifier.
      in: path
      name: promotion_id
      required: true
      schema:
        maxLength: 256
        minLength: 5
        pattern: ^spr_
        type: string
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: true
      schema:
        maxLength: 200
        minLength: 1
        type: string
  schemas:
    SandboxPromotionApplyRequest:
      additionalProperties: false
      properties:
        expected_plan_version:
          minimum: 1
          type: integer
        plan_sha256:
          pattern: ^[a-f0-9]{64}$
          type: string
      required:
        - expected_plan_version
        - plan_sha256
      type: object
    SandboxPromotion:
      additionalProperties: false
      description: >-
        An immutable, bounded review and lifecycle record. It never returns
        secret material, storage IDs/object keys, signed URLs, raw source
        documents, provider payloads, or customer-context prices. status is
        authoritative; lifecycle is a compatibility duplicate. preparing is a
        current state only: trusted internal media staging must settle before
        apply, without promising asynchronous readiness or byte-copy behavior to
        the API caller.
      properties:
        applied_sha256:
          pattern: ^[a-f0-9]{64}$
          type:
            - string
            - 'null'
        applied_version:
          minimum: 1
          type:
            - integer
            - 'null'
        errors:
          items:
            maxLength: 1000
            minLength: 1
            type: string
          maxItems: 100
          type: array
        expires_at:
          format: date-time
          type: string
        failure_code:
          maxLength: 80
          type:
            - string
            - 'null'
        failure_message:
          maxLength: 1000
          type:
            - string
            - 'null'
        id:
          maxLength: 256
          minLength: 5
          pattern: ^spr_
          type: string
        includes:
          items:
            $ref: '#/components/schemas/SandboxPromotionInclude'
          maxItems: 3
          minItems: 1
          type: array
          uniqueItems: true
        lifecycle:
          $ref: '#/components/schemas/SandboxPromotionStatus'
        mappings:
          items:
            $ref: '#/components/schemas/SandboxPromotionMapping'
          maxItems: 250
          type: array
        plan_sha256:
          pattern: ^[a-f0-9]{64}$
          type: string
        plan_version:
          minimum: 1
          type: integer
        resources:
          items:
            $ref: '#/components/schemas/SandboxPromotionResource'
          maxItems: 250
          type: array
        status:
          $ref: '#/components/schemas/SandboxPromotionStatus'
        studio_id:
          maxLength: 256
          minLength: 5
          pattern: ^stu_
          type: string
        warnings:
          items:
            maxLength: 1000
            minLength: 1
            type: string
          maxItems: 100
          type: array
      required:
        - id
        - studio_id
        - status
        - includes
        - plan_version
        - plan_sha256
        - resources
      type: object
    SandboxPromotionInclude:
      enum:
        - forms
        - catalog
        - storefront
      type: string
    SandboxPromotionStatus:
      enum:
        - preparing
        - ready
        - applying
        - applied
        - conflicted
        - failed
        - rolled_back
        - expired
      type: string
    SandboxPromotionMapping:
      additionalProperties: false
      properties:
        resource_type:
          maxLength: 80
          minLength: 1
          type: string
        source_id:
          maxLength: 256
          minLength: 1
          type: string
        target_id:
          maxLength: 256
          type: string
      required:
        - resource_type
        - source_id
      type: object
    SandboxPromotionResource:
      additionalProperties: false
      description: >-
        One bounded public resource action. IDs are Batch Relay public resource
        IDs, not database or storage IDs. changed_fields and the before/after
        SHA-256 values commit to every promoted field without exposing private
        snapshots, provider payloads, URLs, object keys, storage identifiers, or
        raw form data.
      properties:
        action:
          $ref: '#/components/schemas/SandboxPromotionAction'
        after:
          $ref: '#/components/schemas/SandboxPromotionUserVisibleFields'
        after_sha256:
          description: >-
            Lowercase SHA-256 commitment to the canonical privacy-safe after
            payload covering every promoted field.
          pattern: ^[a-f0-9]{64}$
          type: string
        before:
          $ref: '#/components/schemas/SandboxPromotionUserVisibleFields'
        before_sha256:
          description: >-
            Lowercase SHA-256 commitment to the canonical privacy-safe before
            payload. For a new resource it commits to the canonical empty
            payload.
          pattern: ^[a-f0-9]{64}$
          type: string
        blocking_errors:
          items:
            maxLength: 1000
            minLength: 1
            type: string
          maxItems: 25
          type: array
        changed_fields:
          description: >-
            All top-level promoted field names, in lower snake_case. These are
            safe field-name labels only, never values, IDs, storage identifiers,
            URLs, or provider data.
          items:
            pattern: ^[a-z][a-z0-9_]{0,79}$
            type: string
          maxItems: 32
          type: array
          uniqueItems: true
        resulting_target_version:
          minimum: 1
          type: integer
        source_id:
          maxLength: 256
          type: string
        source_version:
          minimum: 1
          type: integer
        target_id:
          maxLength: 256
          type: string
        target_version:
          minimum: 1
          type: integer
        type:
          maxLength: 80
          minLength: 1
          type: string
        warnings:
          items:
            maxLength: 1000
            minLength: 1
            type: string
          maxItems: 25
          type: array
      required:
        - type
        - action
        - changed_fields
        - before_sha256
        - after_sha256
      type: object
    Error:
      additionalProperties: false
      properties:
        code:
          description: Stable machine-readable error code.
          type: string
        docs_url:
          format: uri
          type: string
        error:
          description: Backward-compatible human-readable error.
          type: string
        message:
          type: string
        request_id:
          type: string
      required:
        - error
        - code
        - message
        - docs_url
        - request_id
      type: object
    SandboxPromotionAction:
      enum:
        - create
        - update
        - archive
        - no_op
        - block
      type: string
    SandboxPromotionUserVisibleFields:
      additionalProperties: false
      description: >-
        The only per-resource values exposed by the current promotion contract.
        price_cents is a studio catalog value, never a price tied to a customer
        context. Provider data, URLs, storage identifiers, raw document content,
        secret material, and customer context are excluded.
      properties:
        active:
          type: boolean
        description:
          maxLength: 2000
          minLength: 1
          type: string
        item_count:
          minimum: 0
          type: integer
        name:
          maxLength: 500
          minLength: 1
          type: string
        price_cents:
          minimum: 0
          type: integer
        status:
          maxLength: 80
          minLength: 1
          type: string
      type: object
  responses:
    IdempotencyKeyRequired:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: Idempotency-Key is required for this operation.
    APIKeyAuthenticationRequired:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: A valid Batch Relay API key or anonymous Test Mode session is required.
    SandboxPromotionForbidden:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: >-
        The credential is anonymous or Test Mode, lacks the required
        sandbox_promotions scope, or no longer has the exact studio grant.
    SandboxPromotionNotFound:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: >-
        The promotion does not exist or is not visible to this studio
        credential.
    SandboxPromotionConflict:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: >-
        The reviewed plan/applied version is stale, a newer Live edit prevents
        the requested mutation, or the idempotency key conflicts. No partial
        apply or rollback succeeds.
    InvalidSandboxPromotion:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: >-
        The JSON body, include selection, expected version, or SHA-256
        fingerprint is invalid.
    SandboxPromotionFailed:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: The trusted sandbox-promotion service could not complete this request.
    SandboxPromotionUnavailable:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: >-
        The trusted sandbox-promotion Convex functions are not configured or are
        temporarily unavailable.
  securitySchemes:
    bearerAuth:
      bearerFormat: Batch Relay API key or anonymous session
      description: >-
        Batch Relay scoped API key or an anonymous Test Mode session. Scope
        names document required capabilities. Anonymous sessions are
        sandbox-only and do not authorize studio, event, billing, or Live Mode
        operations.
      scheme: bearer
      type: http

````