> ## 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.

# Reactivate an order subscription

> Reactivate eligible domains in an order before their scheduled cancellation
takes effect. Existing renewal dates stay the same.

Omit `domains` to reactivate all pending domains, or provide domain IDs to
select specific ones.

If service has already ended, the API returns `202 supplier_message_drafted`.
This prepares a reactivation request but does not restore service or restart
billing. Contact support to complete reactivation.

Requires a full-access API key and an `Idempotency-Key`. Reuse the same key
when retrying the same request.

### Reactivate all pending domains

Send `{}` to restore all eligible pending domains in the order. Replace the
order ID and API key below with your values. Reuse the same Idempotency-Key
when retrying this request.

```bash
curl --request POST \
  --url 'https://api.peeker.ai/partner/v1/orders/ord_YOUR_ORDER_ID/reactivate' \
  --header 'Authorization: Bearer pk_live_YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: reactivate-YOUR_ORDER_ID-001' \
  --data '{}'
```




## OpenAPI

````yaml openapi.yaml POST /orders/{id}/reactivate
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/{id}/reactivate:
    parameters:
      - in: path
        name: id
        required: true
        description: Order ID (`ord_…`).
        schema:
          type: string
    post:
      tags:
        - Orders
      summary: Reactivate an order subscription
      description: >
        Reactivate eligible domains in an order before their scheduled
        cancellation

        takes effect. Existing renewal dates stay the same.


        Omit `domains` to reactivate all pending domains, or provide domain IDs
        to

        select specific ones.


        If service has already ended, the API returns `202
        supplier_message_drafted`.

        This prepares a reactivation request but does not restore service or
        restart

        billing. Contact support to complete reactivation.


        Requires a full-access API key and an `Idempotency-Key`. Reuse the same
        key

        when retrying the same request.


        ### Reactivate all pending domains


        Send `{}` to restore all eligible pending domains in the order. Replace
        the

        order ID and API key below with your values. Reuse the same
        Idempotency-Key

        when retrying this request.


        ```bash

        curl --request POST \
          --url 'https://api.peeker.ai/partner/v1/orders/ord_YOUR_ORDER_ID/reactivate' \
          --header 'Authorization: Bearer pk_live_YOUR_API_KEY' \
          --header 'Content-Type: application/json' \
          --header 'Idempotency-Key: reactivate-YOUR_ORDER_ID-001' \
          --data '{}'
        ```
      operationId: reactivateOrder
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          description: >-
            Use a unique key for each request. Reuse it for retries with the
            same order and domain selection; changing either with the same key
            returns 409.
          schema:
            type: string
            minLength: 1
            maxLength: 256
      requestBody:
        required: false
        content:
          application/json:
            example: {}
            schema:
              type: object
              additionalProperties: false
              properties:
                domains:
                  description: >-
                    Optional domain IDs from this order. Every selected domain
                    must be eligible; the request does not return partial
                    success. If the order contains both pending and ended
                    domains, select one group at a time.
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    type: string
                    pattern: ^dom_
      responses:
        '200':
          description: >
            Scheduled cancellation withdrawn for the selected wallet-funded
            domains.

            Existing renewal dates stay the same. Domain registration renewal
            resumes

            only if this order's cancellation disabled it; separate renewal
            opt-outs

            remain disabled.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: object
                    required:
                      - id
                      - status
                      - domains
                    properties:
                      id:
                        type: string
                      status:
                        type: string
                        enum:
                          - reactivated
                      domains:
                        type: array
                        items:
                          type: object
                          required:
                            - id
                            - domain
                            - renews_at
                          properties:
                            id:
                              type: string
                            domain:
                              type: string
                            renews_at:
                              type: string
                              format: date-time
        '202':
          description: >
            A reactivation request has been prepared for manual follow-up. No
            request

            has been sent to the supplier, and service and billing have not
            resumed.

            The existing tenant, subscription, billing dates, and wallet balance
            stay

            the same. Contact support to complete reactivation.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: object
                    required:
                      - id
                      - status
                      - domains
                    properties:
                      id:
                        type: string
                      status:
                        type: string
                        enum:
                          - supplier_message_drafted
                      domains:
                        type: array
                        items:
                          type: object
                          required:
                            - id
                            - domain
                            - status
                          properties:
                            id:
                              type: string
                            domain:
                              type: string
                            status:
                              type: string
                              enum:
                                - supplier_message_drafted
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/InvalidRequest'
          description: >
            The request cannot proceed. This can happen when an Idempotency-Key
            is

            reused with a different order or domain selection, selected domains
            are

            not eligible, pending and ended domains are mixed, or the supplier
            or

            tenant cannot be confirmed. Scheduled cancellations paid through
            Stripe

            and cancellations already handed to a supplier require support.
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  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'
    RateLimited:
      description: >-
        Too many requests. Wait `Retry-After` seconds (also in
        `error.details.retry_after_seconds`), then retry.
      headers:
        Retry-After:
          description: Seconds to wait before retrying; capacity is not reserved.
          schema:
            type: integer
            minimum: 1
        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'
  headers:
    PeekerRequestId:
      description: Stable request identifier. Log it with the status and response body.
      schema:
        type: string
        example: 550e8400-e29b-41d4-a716-446655440000
  schemas:
    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`.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Partner API key (`pk_live_…` or `pk_test_…`).
      x-default: Bearer pk_test_<your-test-key>

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.