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

# Get a checkout session

> Verify a hosted or embedded checkout on your server.



## OpenAPI

````yaml api-reference/v1/openapi.json GET /checkout-sessions/{id}
openapi: 3.1.0
info:
  title: Laces Partner API
  version: 1.0.0
  summary: Show your organization's races and sell entries from your own website.
  description: >-
    The Laces Partner API, served at `https://connect.laces.run/v1`. Every path
    is relative to that server URL, which already ends in `/v1`.


    Authenticate with a **bearer token** from `POST /oauth/token` (server side)
    or, on the routes that allow it, a **publishable key** in
    `X-Laces-Publishable-Key` (browser side, from an allowed domain). Keys are
    uppercase and case-sensitive: send them exactly as issued.


    There is one environment, production. Payments made through the API are
    real.


    Money is integer minor units. Every route except the token endpoint answers
    in the Laces envelope `{ code, message, data | error, error_code }`; branch
    on `error_code`, never on `message` or `error`.


    Every response carries an `X-Request-Id` header (`req_…`). Quote it to
    support@laces.run when something goes wrong. Browsers can read
    `X-Request-Id` and `Retry-After` (both are CORS-exposed). Rate-limited
    routes also send the standard `RateLimit-Limit`, `RateLimit-Remaining` and
    `RateLimit-Reset` headers.


    Partner credentials are accepted on this host only. Sent to `api.laces.run`
    (the Laces app's own API), any partner credential is refused with `401
    partner_credential_not_accepted`.
  contact:
    name: Laces support
    email: support@laces.run
    url: https://docs.laces.run
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://connect.laces.run/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: OAuth 2.0 client credentials.
  - name: Events
    description: Your organization's races that are on sale.
  - name: Checkout sessions
    description: 'Laces-hosted checkout: redirect or embedded.'
  - name: Orders
    description: Create, pay and read orders from your own UI.
  - name: Webhook events
    description: Requests Laces sends to your webhook endpoint.
  - name: Health
    description: Liveness probe.
paths:
  /checkout-sessions/{id}:
    get:
      tags:
        - Checkout sessions
      summary: Get a checkout session
      description: >-
        **Server-side verification** of a hosted or embedded checkout. Require
        `status: "complete"` and match `client_reference_id` to your own record
        before fulfilling. Never fulfil on the redirect or the laces.js
        `onSuccess` callback alone.


        Bearer token only (a publishable key is `403 credential_not_permitted`),
        scope `checkout_sessions:write`. `status` is derived from the linked
        order. Expired sessions are deleted by a cleanup policy some time after
        they expire, after which this returns `404`: record the outcome while
        the session exists, or rely on the order and its webhooks.
      operationId: getCheckoutSession
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          example: LCSCS-EXAMPLESESSN234EXAMPL
      responses:
        '200':
          description: The session.
          content:
            application/json:
              schema:
                type: object
                required:
                  - code
                  - message
                  - data
                properties:
                  code:
                    type: integer
                    description: HTTP status, repeated in the body.
                    examples:
                      - 200
                  message:
                    type: string
                    examples:
                      - Checkout session retrieved successfully
                  data:
                    $ref: '#/components/schemas/CheckoutSession'
              example:
                code: 200
                message: Checkout session retrieved successfully
                data:
                  id: LCSCS-EXAMPLESESSN234EXAMPL
                  status: complete
                  ui_mode: redirect
                  event_id: q3Zk9mVx
                  client_reference_id: cart-8841
                  order:
                    id: Hk2mQ8vR
                    code: LC-7K2M9X
                    status: paid
                    total: 52400
                    currency: UGX
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - bearerAuth: []
        - oauth2:
            - checkout_sessions:write
components:
  schemas:
    CheckoutSession:
      type: object
      properties:
        id:
          type: string
          examples:
            - LCSCS-EXAMPLESESSN234EXAMPL
        status:
          type: string
          description: >-
            `open`: not paid yet. `complete`: the linked order is paid (also
            when later refunded). `expired`: 24 hours passed without a paid
            order.
          enum:
            - open
            - complete
            - expired
        ui_mode:
          type: string
          enum:
            - redirect
            - embedded
        event_id:
          type: string
        client_reference_id:
          type:
            - string
            - 'null'
        order:
          oneOf:
            - type: object
              properties:
                id:
                  type: string
                code:
                  type: string
                status:
                  type: string
                  enum:
                    - cart
                    - payment_initiated
                    - prompt_sent
                    - paid
                    - failed
                    - expired
                    - cancelled
                    - refunded
                    - partially_refunded
                    - chargeback_flagged
                total:
                  type: integer
                currency:
                  type: string
              required:
                - id
                - code
                - status
                - total
                - currency
            - type: 'null'
          description: >-
            The most recent order created through the session; `null` until the
            buyer starts a cart.
      required:
        - id
        - status
        - ui_mode
        - event_id
        - client_reference_id
        - order
    Error:
      type: object
      properties:
        code:
          type: integer
          description: HTTP status, repeated in the body.
        message:
          type: string
          description: Short outcome. Do not branch on it; it may be reworded.
        error:
          type: string
          description: Human-readable detail. May be reworded; never parse it.
        error_code:
          type: string
          description: >-
            Stable machine-readable code. **Branch on this.** Present on every
            Partner API error, including `429 rate_limited`, `404 not_found` for
            unknown routes and `500 server_error`. See the [error
            reference](/concepts/errors).
        details:
          type: object
          properties:
            retry_after_seconds:
              type: integer
          description: Only on `409 prompt_in_progress`.
      required:
        - code
        - message
        - error
        - error_code
      description: The Laces error envelope.
  headers:
    X-Request-Id:
      description: >-
        Unique id of this request (`req_…`). On every response, readable from
        browsers. Quote it to support.
      schema:
        type: string
      example: req_V1StGXR8Z5jdHi6BmyTq
    Retry-After:
      description: Whole seconds to wait before retrying. Readable from browsers.
      schema:
        type: integer
    RateLimit-Limit:
      description: Requests allowed in the current window.
      schema:
        type: integer
    RateLimit-Remaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimit-Reset:
      description: Seconds until the window resets.
      schema:
        type: integer
  responses:
    Unauthorized:
      description: >-
        No credential, an invalid or expired token, or an invalid publishable
        key. Comes with `WWW-Authenticate: Bearer realm="laces-partner"`.
        Revoking or regenerating keys can take up to a minute to reach every
        server.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthorized:
              summary: unauthorized
              value:
                code: 401
                message: Unauthorized
                error: Missing credentials
                error_code: unauthorized
            invalid_token:
              summary: invalid_token
              value:
                code: 401
                message: Unauthorized
                error: Invalid or expired access token
                error_code: invalid_token
            invalid_key:
              summary: invalid_key
              value:
                code: 401
                message: Unauthorized
                error: Invalid publishable key
                error_code: invalid_key
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    Forbidden:
      description: >-
        The credential is not allowed here: a missing scope (scope changes take
        up to about a minute to apply), a publishable key on a bearer-only
        route, or a publishable key from an origin that is not an allowed
        domain.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            insufficient_scope:
              summary: insufficient_scope
              value:
                code: 403
                message: Forbidden
                error: 'Missing scope: orders:read'
                error_code: insufficient_scope
            credential_not_permitted:
              summary: credential_not_permitted
              value:
                code: 403
                message: Forbidden
                error: This endpoint does not accept a publishable key
                error_code: credential_not_permitted
            origin_not_allowed:
              summary: origin_not_allowed
              value:
                code: 403
                message: Forbidden
                error: This origin is not allowed for this key
                error_code: origin_not_allowed
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    NotFound:
      description: >-
        Not found, or it belongs to another organization (the same answer, so
        existence never leaks).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            not_found:
              summary: not_found
              value:
                code: 404
                message: Not found
                error: Event not found
                error_code: not_found
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    RateLimited:
      description: >-
        Rate limited. Wait `Retry-After` seconds. Limits are per API client
        (reads about 300 a minute, writes about 60) and, for publishable keys,
        also per IP (about 120 a minute).
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: 429
            message: Too many requests, please slow down
            error: rate_limited
            error_code: rate_limited
    ServerError:
      description: >-
        Unexpected failure. Retry with backoff, reusing the same
        `Idempotency-Key`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            server_error:
              summary: server_error
              value:
                code: 500
                message: An unexpected error occurred
                error: Something went wrong
                error_code: server_error
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: LCSTOK-…-X (opaque)
      description: >-
        A token from `POST /oauth/token`, valid 1 hour. Paste it as `LCSTOK-…-X`
        (without the word Bearer).
    oauth2:
      type: oauth2
      description: >-
        OAuth 2.0 client credentials. The token it yields is the `bearerAuth`
        token.
      flows:
        clientCredentials:
          tokenUrl: https://connect.laces.run/v1/oauth/token
          scopes:
            events:read: List and read events
            orders:write: Create and pay orders
            orders:read: >-
              List and read orders, including buyer personal data (off by
              default)
            checkout_sessions:write: Create and read checkout sessions

````

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