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

# Create or retry Checkout with a trusted publication decision

> Requires the customer credential's authenticated actor, billing:write,
live billing, and a server-signed publication assertion. The assertion
must use EdDSA, issuer promotion-auth-adapter, audience promotion-account,
operation checkout, and a positive lifetime of at most five minutes.
Its sub and team_id must match the customer credential, and its
operation_id, home_region, decision, success_url and cancel_url must
exactly match the body. The region must match the receiving cell.

The decision is committed with the fresh generation before Stripe
session creation. publication_failed preserves paid access without new
automatic promotion credit; standard uses existing eligibility checks.
Retry the same operation and body with a renewed assertion after a lost
response. Existing generations retain their original payer and decision.
A changed or retired operation conflicts; do not fall back to the legacy
creation route on an error or an older server's missing route.

Bodies over 4096 bytes and unknown fields are rejected. Redirects must
match the regional API's allowed billing redirect configuration.




## OpenAPI

````yaml https://raw.githubusercontent.com/superserve-ai/sandbox/refs/heads/main/api/openapi.yaml post /stripe/checkout-session/publication-decision
openapi: 3.1.0
info:
  title: Superserve API
  version: 0.1.0
  description: >
    Superserve provides sandbox infrastructure to run AI agents in the cloud.
    Powered by Firecracker MicroVMs.


    ## Sandbox lifecycle


    ```

    active <--> paused --> deleted

    ```


    A sandbox is `active` when running and `paused` after being paused. Resuming

    a paused sandbox returns it to `active`. Deleting releases all resources.


    | Endpoint | What it does |

    |----------|-------------|

    | `POST /sandboxes` | Create a new sandbox (optionally `from_template`) |

    | `PATCH /sandboxes/:id` | Partially update a running sandbox (e.g. network
    rules) |

    | `POST /sandboxes/:id/pause` | Snapshot full state, suspend the VM |

    | `POST /sandboxes/:id/resume` | Restore from snapshot, continue where it
    left off |

    | `DELETE /sandboxes/:id` | Delete sandbox and all resources |


    ## Sandbox environment


    By default sandboxes boot from the curated `superserve/base` template
    (Ubuntu 24.04,

    1 vCPU, 1 GB RAM, 4 GB disk, with Python 3.12, Node.js 22, npm, git, curl,

    and build-essential pre-installed). Callers can override with any template

    name (e.g. `superserve/python-3.11`, `superserve/node-22`) or a team-owned
    template UUID

    via the `from_template` field on `POST /sandboxes`.


    ## Files and commands


    `/files`, `/exec`, and `/exec/stream` run against a single sandbox and use

    its `X-Access-Token` (returned by create, resume, and activate), not the

    team API key. Two host forms reach them:


    - `https://sandbox.superserve.ai/...` with `X-Superserve-Sandbox-Id:
    <sandbox_id>`.

    - `https://boxd-{sandbox_id}.sandbox.superserve.ai/...` — no routing header
    needed.
  contact:
    name: Superserve Team
  license:
    name: Proprietary
servers:
  - url: https://api.superserve.ai
    description: Production
security: []
paths:
  /stripe/checkout-session/publication-decision:
    post:
      tags:
        - Billing
      summary: Create or retry Checkout with a trusted publication decision
      description: >
        Requires the customer credential's authenticated actor, billing:write,

        live billing, and a server-signed publication assertion. The assertion

        must use EdDSA, issuer promotion-auth-adapter, audience
        promotion-account,

        operation checkout, and a positive lifetime of at most five minutes.

        Its sub and team_id must match the customer credential, and its

        operation_id, home_region, decision, success_url and cancel_url must

        exactly match the body. The region must match the receiving cell.


        The decision is committed with the fresh generation before Stripe

        session creation. publication_failed preserves paid access without new

        automatic promotion credit; standard uses existing eligibility checks.

        Retry the same operation and body with a renewed assertion after a lost

        response. Existing generations retain their original payer and decision.

        A changed or retired operation conflicts; do not fall back to the legacy

        creation route on an error or an older server's missing route.


        Bodies over 4096 bytes and unknown fields are rejected. Redirects must

        match the regional API's allowed billing redirect configuration.
      operationId: createStripeCheckoutSessionWithPublicationDecision
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - operation_id
                - home_region
                - decision
                - success_url
                - cancel_url
              properties:
                operation_id:
                  type: string
                  format: uuid
                  description: >-
                    Stable random operation locator generated before the first
                    request.
                home_region:
                  type: string
                  enum:
                    - use
                    - usw
                decision:
                  type: string
                  enum:
                    - standard
                    - publication_failed
                success_url:
                  type: string
                  format: uri
                cancel_url:
                  type: string
                  format: uri
      responses:
        '200':
          description: Checkout session created or original session returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingSessionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: >-
            conflict — changed or closed intent, existing generation,
            reservation or subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          description: >-
            bad_gateway — Stripe creation failed; retain the original intent and
            uncertainty fence
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: service_unavailable — required billing configuration unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - apiKey: []
          promotionAccountAssertion: []
components:
  schemas:
    BillingSessionResponse:
      type: object
      required:
        - url
      properties:
        id:
          type: string
        url:
          type: string
          format: uri
    Error:
      type: object
      description: |
        Error envelope. `error.code` is a stable, machine-readable identifier
        (e.g. `bad_request`, `not_found`, `conflict`, `rate_limited`,
        `too_many_builds`, `too_many_templates`, `too_many_sandboxes`,
        `image_pull_failed`, `step_failed`, `snapshot_failed`,
        `start_cmd_failed`, `ready_cmd_failed`, `build_failed`).
        `error.message` is human-readable and may change between releases;
        clients should branch on `code`, not `message`.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Caller is authenticated but not allowed to perform the action
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: >
        Rate limit hit — the caller's per-team request budget is temporarily
        exhausted. Response body uses error code `rate_limited`. Retry after a
        short backoff; the bucket refills continuously.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
    promotionAccountAssertion:
      type: apiKey
      in: header
      name: X-Promotion-Account-Assertion
      description: >-
        Server-only Ed25519 JWT binding the authenticated actor and team to the
        exact Checkout intent.

````

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