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

# Create an order

> Send an order to a connected workspace. Every destination includes its
provider and Peeker `workspace_id`. For Smartlead, omit `client_id` to
use the main workspace or include it to use that client workspace.

Orders do not accept Smartlead login credentials, customer data, or
user data. A Smartlead Google order needs only the connected API key.
Smartlead Microsoft or mixed orders use the optional login pair saved
through `POST /workspaces`.

Use a bundle or custom sizing, never both. A normal order buys and
provisions its own domains. It never reserves, attaches, or changes
pre-warmed pool inventory. Only `POST /pool/attach` can do that.
Bundle orders may send `quantity`. A quantity of `2` doubles the
bundle domain and inbox counts; omitting it means `1`.
For a custom Google order, set `google_licenses` to `1`, `2`, or `3`.
Peeker creates that many Google inboxes on every submitted domain.




## OpenAPI

````yaml /openapi.yaml post /orders
openapi: 3.1.0
info:
  title: Peeker Partner API
  version: 1.0.0
  description: >
    White-label Peeker's email infrastructure: Google Workspace and Microsoft

    365 inboxes, deliverability monitoring, and self-healing domain swaps,

    from your own app. Create a provider workspace target, order licenses with
    imported or

    Peeker-managed domains, and Peeker's backend handles provisioning,

    DNS, forwarding, and lifecycle webhooks.


    Create a provider workspace target with `POST /workspaces`, then send its

    `wrk_...` ID to `POST /orders`. For Smartlead, create one main workspace,

    then add `client_id` to an order only when it should go to a client

    workspace. Omit it to order into the main workspace.


    ## Read first


    - **[Authentication](/authentication)**: bearer keys, live vs sandbox,
    request IDs.

    - **[Rate limits](/rate-limits)**: 600/min per key, 429 backoff.

    - **[Webhooks](/webhooks)**: signed events and delivery rules.

    - **[Async jobs](/concepts/async-jobs)**: what to poll vs subscribe to.

    - **[Best practices](/best-practices)**: errors, paging, idempotency.


    ## Concepts


    - **[Orders](/concepts/orders)**: statuses, sizing, pending actions, cancel.

    - **[Domains](/concepts/domains)**: inventory, `usable_for`, import,
    forwarding.

    - **[Bundles](/concepts/bundles)**: saved templates and capacity.

    - **[Swaps](/concepts/swaps)**: standard vs premium, renames.


    ## Workflow guides


    - **[Provider ordering](/guides/provider-ordering)** — create a provider
    workspace target and order through it.

    - **[Buying domains & ordering](/guides/buying-domains)** — the default
    flow: bundle, availability, order, webhooks.

    - **[Importing domains](/guides/importing-domains)** — bring in existing
    customer domains.

    - **[Forwarding](/guides/forwarding)** — point a domain at a marketing site.

    - **[How to implement domain swaps](/guides/domain-swaps)** — standard vs
    premium swaps.

    - **[Renaming inbox senders](/guides/user-name-swaps)** — change mailbox
    personas on a warm domain.


    ## Public ID prefixes


    | Prefix | Resource |

    | --- | --- |

    | `cus_` | Customer tracking record |

    | `wrk_` | Provider workspace |

    | `bun_` | Bundle |

    | `ord_` | Order |

    | `dom_` | Domain |

    | `pcl_` | Pool reservation |

    | `prp_` | Pool replacement |

    | `prl_` | Pool release |

    | `imp_` | Domain import job |

    | `fwj_` | Domain forwarding job |

    | `brj_` | Burned-domain replacement job |

    | `swp_` | Domain swap |

    | `act_` | Pending action |

    | `evt_` | Webhook event |
servers:
  - url: https://api.peeker.ai/partner/v1
    description: >-
      Same base URL for live and sandbox. The key prefix (`pk_live_…` /
      `pk_test_…`) picks the environment.
security:
  - BearerAuth: []
tags:
  - name: Account
    x-group: Account
    description: >
      Confirm an API key with `GET /me`. Returns environment (live or sandbox),

      permission preset, and the partner profile. See
      [Authentication](/authentication).
  - name: Provider workspaces
    x-group: Provider workspaces
    description: |
      A provider workspace is one reusable provider connection. Create it once,
      keep the returned `wrk_...` ID, and use it in orders and pool attach.
      Optional customer tracking stays on the target. Provider credentials stay
      internal and are never echoed.

      EmailBison requires a workspace API-user key. Super-admin keys are
      rejected. Instantly and Smartlead connections require `api_key`.
      Smartlead workspace creation takes a main API key and a label. Do not send
      `client_id` or customer data. Its login email and password are optional,
      but must be sent together. Google orders do not need the pair, and orders
      never accept it. Smartlead Microsoft orders and pool attach still use the
      workspace-saved pair. Add
      `client_id` to the order destination when the order belongs to a client
      workspace; omit it for the main workspace.
      PlusVibe setup requires `api_key`, remote `workspace_id`, and its login
      email/password pair so orders and pool attach work immediately. Instantly
      login credentials belong on an order destination.
  - name: Bundles
    x-group: Bundles
    description: |
      Saved order template sized by monthly sending volume (`bun_…`). Pass
      `bundle_id` on an order instead of custom license counts.

      Lifecycle: [How bundles work](/concepts/bundles).
  - name: Domains
    x-group: Domains
    description: >
      Sending domains in your partner account (`dom_…`). Same ID whether or not

      the domain is on an order.


      **Status values**


      | Value | What it means |

      | --- | --- |

      | `available` | The domain is in inventory but not on an order yet. |

      | `in_progress` | We're setting it up. |

      | `active` | Live and warming or healthy. |

      | `failed` | Something broke that we can't fix automatically. |

      | `action_required` | We need your help (e.g. update nameservers). |


      **Inventory vs connected**


      - `category=inventory` — yours but not on any order. Inventory rows
        don't include `provider`.
      - `category=connected` — on an active order. The row carries the link
        fields `provider`, `customer_id`, `order_id`, `usable_for`, and
        `forwarding_url`.

      **`usable_for` matrix**


      When you check a domain's availability:


      | Who's on the domain | `usable_for` |

      | --- | --- |

      | Nobody, or just Google | `["google", "microsoft"]` |

      | Microsoft (or both) | `["google"]` |

      | Premium / invalid / errored | not orderable; `available: false` with a
      `reason` |


      **Imports and forwarding are jobs**


      Both **import** and **forwarding** are async jobs. Posting to those

      endpoints starts the job and gives you back a row with `status:

      "in_progress"`. Poll the job's GET endpoint to see when it finishes:


      - Import jobs: prefix `imp_…`. Includes the `nameserver_groups` your
        customer needs to set at their registrar.
        - Forwarding jobs: prefix `fwj_…`. Already-correct domains are
          returned in `completed` with newly updated domains.
  - name: Domain pool
    x-group: Domain pool
    description: |
      Assign an exact quantity from pre-warmed Google inventory. Each domain
      needs at least one active Google inbox on a paid Google order (commonly
      two), complete provider mailbox identity, and no explicit burned provider
      result. Attach is all-or-nothing: full quantity or
      `insufficient_inventory` with no pool change. Attach and release are
      async. Poll the resource or subscribe to `pool.*` webhooks.

      Guide: [Pre-warmed pool](/guides/pre-warmed-pool).
  - name: Orders
    x-group: Orders
    description: |
      One purchase of domains plus Google and/or Microsoft licenses for one
      customer (`ord_…`). Use a saved `bundle_id` **or** custom license counts,
      never both. Requires `Idempotency-Key`.

      Lifecycle: [How orders work](/concepts/orders).
  - name: Domain swaps
    x-group: Domain swaps
    description: |
      Replace a domain inside an existing order without losing the order
      (`swp_…`). For persona-only changes use `POST /swaps/user_names`.

      Statuses and standard vs premium: [How swaps work](/concepts/swaps).
  - name: Webhooks
    x-group: Webhooks
    description: |
      Signed JSON POSTs for orders, domains, imports, forwarding, pool, and
      swaps. Register the URL and secret in the
      [Partner portal](https://app.peeker.ai/partner/webhooks). Event IDs look
      like `evt_01HZX`.

      Delivery is at least once (up to 5 attempts). Verify `Peeker-Signature`
      and dedupe `Peeker-Event-Id` for at least 24 hours.

      Full catalog: [Webhooks](/webhooks).
paths:
  /orders:
    post:
      tags:
        - Orders
      summary: Create an order
      description: |
        Send an order to a connected workspace. Every destination includes its
        provider and Peeker `workspace_id`. For Smartlead, omit `client_id` to
        use the main workspace or include it to use that client workspace.

        Orders do not accept Smartlead login credentials, customer data, or
        user data. A Smartlead Google order needs only the connected API key.
        Smartlead Microsoft or mixed orders use the optional login pair saved
        through `POST /workspaces`.

        Use a bundle or custom sizing, never both. A normal order buys and
        provisions its own domains. It never reserves, attaches, or changes
        pre-warmed pool inventory. Only `POST /pool/attach` can do that.
        Bundle orders may send `quantity`. A quantity of `2` doubles the
        bundle domain and inbox counts; omitting it means `1`.
        For a custom Google order, set `google_licenses` to `1`, `2`, or `3`.
        Peeker creates that many Google inboxes on every submitted domain.
      operationId: createStrictOrderV1
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StrictOrderRequest'
            examples:
              emailbison_microsoft_order:
                summary: Existing EmailBison workspace target
                value:
                  destination:
                    provider: emailbison
                    workspace_id: wrk_01HZX0EB1A2B3C4D5E6F7G8H
                  order:
                    microsoft_licenses: 1
                    microsoft_inboxes_per_domain: 25
                    domains:
                      - acme-mail.com
                    personas:
                      - first_name: Alex
                        last_name: Rivera
              instantly_google_order:
                summary: Existing Instantly workspace target
                value:
                  destination:
                    provider: instantly
                    workspace_id: wrk_01HZX0JN1A2B3C4D5E6F7G8H
                    login_credentials:
                      login_email: automation@agency.com
                      login_password: <instantly-login-password>
                  order:
                    google_licenses: 2
                    domains:
                      - acme-mail.com
                    personas:
                      - first_name: Alex
                        last_name: Rivera
              smartlead_google_order:
                summary: Smartlead client workspace
                value:
                  destination:
                    provider: smartlead
                    workspace_id: wrk_01HZX0SK1A2B3C4D5E6F7G8H
                    client_id: '366903'
                  order:
                    bundle_id: bun_01HZX0BK1A2B3C4D5E6F7G8H
                    domains:
                      - acme-mail.com
                    personas:
                      - first_name: Connor
                        last_name: Scale
                        usernames:
                          - connor
                          - connorscale
              plusvibe_google_order:
                summary: Existing PlusVibe target with workspace-saved login
                value:
                  destination:
                    provider: plusvibe
                    workspace_id: wrk_01HZX0PV1A2B3C4D5E6F7G8H
                  order:
                    google_licenses: 2
                    domains:
                      - acme-mail.com
                    personas:
                      - first_name: Alex
                        last_name: Rivera
      responses:
        '200':
          description: Order accepted, or the matching idempotent order returned.
          headers:
            Peeker-Request-Id:
              $ref: '#/components/headers/PeekerRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderEnvelope'
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ProviderUnavailable'
components:
  parameters:
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 256
      description: |
        Required for order creation. Pool attach also supports this header for
        durable retries. Workspace creation does not use it. The value is
        unique across the Partner account.
        Reuse it only with the same endpoint and unchanged request body. When
        retrying an Instantly order after
        `422 provider_login_credentials_required`, you may add or replace only
        `destination.login_credentials`; every other field must stay unchanged.
        For a Smartlead Microsoft or PlusVibe order with that error, repair the
        target through `POST /workspaces`, then retry the unchanged order with
        the same key.
        Retry `503 provider_unavailable` or `500 internal_error` with the same
        key and unchanged body.
        After pool attach returns `409 insufficient_inventory`, wait for pool
        inventory to be replenished, then retry the unchanged body with the
        same key. After `422 provider_login_credentials_required` or
        `422 provider_credentials_invalid`, repair the target workspace, then
        retry the unchanged body with the same key.
  schemas:
    StrictOrderRequest:
      type: object
      additionalProperties: false
      required:
        - destination
        - order
      properties:
        destination:
          $ref: '#/components/schemas/OrderDestination'
        order:
          $ref: '#/components/schemas/OrderInputFields'
    OrderEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/StrictOrderResult'
      example:
        data:
          order:
            order_id: ord_01HZX0QR1A2B3C4D5E6F7G8H
            status: in_progress
            domain_count: 1
            costs:
              total_cents: 3000
              currency: usd
              line_items:
                - type: domain_registration
                  quantity: 1
                  amount_cents: 1300
                - type: microsoft_license
                  quantity: 1
                  amount_cents: 1700
            renews_at: null
            created_at: '2026-07-09T12:10:00.000Z'
          customer_id: cus_01HZX0C6Z3K4M5N6P7Q8R9S0
          workspace_id: wrk_01HZX0PV1A2B3C4D5E6F7G8H
          destination:
            provider: plusvibe
            workspace_id: wrk_01HZX0PV1A2B3C4D5E6F7G8H
            name: Acme PlusVibe
          created:
            order: true
    OrderDestination:
      oneOf:
        - $ref: '#/components/schemas/EmailBisonOrderDestination'
        - $ref: '#/components/schemas/InstantlyOrderDestination'
        - $ref: '#/components/schemas/SmartleadOrderDestination'
        - $ref: '#/components/schemas/PlusVibeOrderDestination'
      discriminator:
        propertyName: provider
    OrderInputFields:
      type: object
      additionalProperties: false
      required:
        - domains
        - personas
      properties:
        bundle_id:
          type: string
          pattern: ^bun_
          description: Saved bundle ID. Don’t also send custom license fields.
          example: bun_01HZX0BK1A2B3C4D5E6F7G8H
        quantity:
          type: integer
          minimum: 1
          maximum: 100
          default: 1
          description: Number of bundle copies to order. Valid only with `bundle_id`.
          example: 2
        google_licenses:
          type: integer
          enum:
            - 1
            - 2
            - 3
          description: Google inboxes created on every submitted Google domain.
          example: 2
        microsoft_licenses:
          type: integer
          minimum: 0
          maximum: 5000
          description: >-
            How many Microsoft licenses (1 license = 1 domain). Custom orders
            only.
          example: 2
        microsoft_inboxes_per_domain:
          type: integer
          enum:
            - 25
            - 50
            - 75
            - 99
          description: Inboxes per Microsoft domain. Required with `microsoft_licenses`.
          example: 50
        forwarding_url:
          type: string
          format: uri
          maxLength: 2048
          description: Default site URL when a domain doesn’t set its own.
          example: https://acme.com
        domains:
          type: array
          minItems: 1
          maxItems: 5000
          items:
            $ref: '#/components/schemas/DomainInput'
        personas:
          type: array
          minItems: 1
          maxItems: 10
          items:
            $ref: '#/components/schemas/Persona'
      oneOf:
        - title: Saved bundle sizing
          required:
            - bundle_id
          not:
            anyOf:
              - required:
                  - google_licenses
              - required:
                  - microsoft_licenses
              - required:
                  - microsoft_inboxes_per_domain
        - title: Custom sizing
          anyOf:
            - title: Google licenses
              required:
                - google_licenses
              properties:
                google_licenses:
                  type: integer
                  minimum: 1
                  maximum: 3
            - title: Microsoft licenses
              required:
                - microsoft_licenses
              properties:
                microsoft_licenses:
                  type: integer
                  minimum: 1
          not:
            anyOf:
              - required:
                  - bundle_id
              - required:
                  - quantity
          allOf:
            - if:
                required:
                  - microsoft_licenses
                properties:
                  microsoft_licenses:
                    type: integer
                    minimum: 1
              then:
                required:
                  - microsoft_inboxes_per_domain
                properties:
                  microsoft_inboxes_per_domain:
                    type: integer
              else:
                not:
                  required:
                    - microsoft_inboxes_per_domain
    StrictOrderResult:
      type: object
      additionalProperties: false
      required:
        - order
        - workspace_id
        - destination
        - created
      properties:
        order:
          $ref: '#/components/schemas/OrderReceipt'
        customer_id:
          type: string
          pattern: ^cus_
          description: Present when the workspace target tracks a customer.
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker workspace target ID.
        destination:
          $ref: '#/components/schemas/DestinationResource'
        created:
          type: object
          additionalProperties: false
          required:
            - order
          properties:
            order:
              type: boolean
              description: >-
                `true` if this request created the order (false on an idempotent
                replay).
              example: true
    ErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: Stable machine-readable code. Branch on this field.
              enum:
                - invalid_request
                - unauthorized
                - forbidden
                - not_found
                - rate_limited
                - provider_not_supported
                - provider_mismatch
                - provider_credentials_invalid
                - provider_login_credentials_required
                - provider_unavailable
                - emailbison_super_admin_key
                - smartlead_connection_required
                - smartlead_client_id_required
                - smartlead_client_not_found
                - idempotency_key_required
                - idempotency_conflict
                - idempotency_in_progress
                - workspace_promotion_required
                - workspace_credentials_conflict
                - order_shape_conflict
                - domain_count_mismatch
                - insufficient_inventory
                - domain_not_imported
                - domains_not_submittable
                - premium_domain_not_supported
                - domain_not_usable_for_provider
                - domain_already_in_active_order
                - internal_error
              example: emailbison_super_admin_key
            message:
              type: string
              description: Human-readable explanation. Wording may change.
              example: >-
                Use an EmailBison workspace/user API key; super-admin keys are
                not accepted.
            request_id:
              type: string
              description: >-
                Stable request identifier, identical to the `Peeker-Request-Id`
                response header.
              example: 550e8400-e29b-41d4-a716-446655440000
            field:
              type: string
              description: Dot path to the invalid request property, when applicable.
              example: credentials.api_key
            details:
              type: object
              additionalProperties: true
              description: Structured context specific to `error.code`.
    EmailBisonOrderDestination:
      type: object
      additionalProperties: false
      required:
        - provider
        - workspace_id
      properties:
        provider:
          type: string
          enum:
            - emailbison
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker workspace ID returned by `POST /workspaces`.
    InstantlyOrderDestination:
      type: object
      additionalProperties: false
      required:
        - provider
        - workspace_id
      properties:
        provider:
          type: string
          enum:
            - instantly
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker workspace ID returned by `POST /workspaces`.
        login_credentials:
          allOf:
            - $ref: '#/components/schemas/ProviderLoginCredentials'
          description: >-
            Optional Instantly login used for this order and saved for later
            orders.
    SmartleadOrderDestination:
      type: object
      additionalProperties: false
      required:
        - provider
        - workspace_id
      properties:
        provider:
          type: string
          enum:
            - smartlead
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker ID for the connected Smartlead main workspace.
        client_id:
          type: string
          pattern: ^[1-9][0-9]*$
          maxLength: 64
          description: Optional Smartlead client ID. Omit it for the main workspace.
          example: '366903'
    PlusVibeOrderDestination:
      type: object
      additionalProperties: false
      required:
        - provider
        - workspace_id
      properties:
        provider:
          type: string
          enum:
            - plusvibe
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker workspace ID returned by `POST /workspaces`.
    DomainInput:
      oneOf:
        - type: string
          minLength: 1
          maxLength: 253
          example: acme-mail.com
        - type: object
          additionalProperties: false
          required:
            - domain
          properties:
            domain:
              type: string
              minLength: 1
              maxLength: 253
              example: shop-acme.com
            forwarding_url:
              type: string
              format: uri
              maxLength: 2048
              description: Optional site URL for this domain.
              example: https://shop.acme.com
    Persona:
      type: object
      additionalProperties: false
      required:
        - first_name
        - last_name
      properties:
        first_name:
          type: string
          minLength: 1
          maxLength: 128
          example: Alex
        last_name:
          type: string
          minLength: 1
          maxLength: 128
          example: Rivera
        usernames:
          type: array
          minItems: 1
          maxItems: 3
          uniqueItems: true
          description: |
            Optional mailbox names before the `@`. Peeker keeps these values
            and generates any missing Google seats from the persona name.
          items:
            type: string
            minLength: 1
            maxLength: 64
            pattern: ^[a-zA-Z0-9._-]+$
          example:
            - alex
            - alex.rivera
        profile_picture_url:
          type: string
          format: uri
          description: Optional public image URL. Private/local URLs are rejected.
          maxLength: 2048
          example: https://cdn.acme.com/alex.jpg
    OrderReceipt:
      type: object
      additionalProperties: false
      required:
        - order_id
        - status
        - domain_count
        - costs
        - renews_at
        - created_at
      properties:
        order_id:
          type: string
          pattern: ^ord_
          example: ord_01HZX0QR1A2B3C4D5E6F7G8H
        status:
          type: string
          enum:
            - in_progress
            - completed
            - failed
            - action_required
            - cancel_scheduled
            - cancelled
          example: in_progress
        domain_count:
          type: integer
          minimum: 0
          example: 1
        costs:
          type: object
          additionalProperties: false
          required:
            - total_cents
            - currency
            - line_items
          properties:
            total_cents:
              type: integer
              minimum: 0
            currency:
              type: string
              enum:
                - usd
              example: usd
            line_items:
              type: array
              items:
                $ref: '#/components/schemas/OrderLineItem'
        renews_at:
          type:
            - string
            - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
          example: '2026-07-09T12:10:00.000Z'
    DestinationResource:
      type: object
      required:
        - provider
        - workspace_id
        - name
      properties:
        provider:
          type: string
          enum:
            - emailbison
            - instantly
            - smartlead
            - plusvibe
        workspace_id:
          type: string
          pattern: ^wrk_
          description: Peeker workspace ID (`wrk_…`).
          example: wrk_01HZX0SK1A2B3C4D5E6F7G8H
        client_id:
          type: string
          pattern: ^[1-9][0-9]*$
          description: Smartlead client ID (Smartlead only).
          example: '366903'
        name:
          type: string
          description: Display name from the provider.
          example: Acme Client
    ProviderLoginCredentials:
      type: object
      additionalProperties: false
      required:
        - login_email
        - login_password
      properties:
        login_email:
          type: string
          format: email
          writeOnly: true
          maxLength: 320
          example: automation@agency.com
        login_password:
          type: string
          format: password
          writeOnly: true
          minLength: 1
          maxLength: 4096
          example: <provider-login-password>
      description: |
        Optional Instantly login used to provision an order. Peeker saves a
        valid pair for later Instantly orders. EmailBison, Smartlead, and
        PlusVibe reject this field.
    OrderLineItem:
      type: object
      required:
        - type
        - quantity
        - amount_cents
      properties:
        type:
          type: string
          enum:
            - domain_registration
            - google_license
            - microsoft_license
          example: google_license
        quantity:
          type: integer
          example: 4
        amount_cents:
          type: integer
          example: 10000
  headers:
    PeekerRequestId:
      description: Stable request identifier. Log it with the status and response body.
      schema:
        type: string
        example: 550e8400-e29b-41d4-a716-446655440000
  responses:
    InvalidRequest:
      description: Bad request body, or fields that don’t belong to this provider.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Unauthorized:
      description: Missing, invalid, or revoked API key.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Forbidden:
      description: Valid key, but it doesn’t allow this action.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    NotFound:
      description: >-
        A referenced workspace, customer, bundle, domain, or order was not
        found.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Conflict:
      description: Conflicts with an existing resource or idempotency key.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    UnprocessableEntity:
      description: Credentials missing/rejected, or the order can’t be processed as sent.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RateLimited:
      description: Too many requests. Wait `error.details.retry_after_seconds`, then retry.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: Unexpected server error. Retry with backoff and keep the request ID.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ProviderUnavailable:
      description: Provider is temporarily unavailable. Retry with backoff.
      headers:
        Peeker-Request-Id:
          $ref: '#/components/headers/PeekerRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Partner API key (`pk_live_…` or `pk_test_…`).
      x-default: Bearer pk_test_<your-test-key>

````