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

# Billing checkout

> Billing checkout: request contract, authentication, parameters and response behavior for the Oddswire private pilot.

Test-only billing; owner session required for mutations, owner/admin for reads. Fixed test catalogue; enrollment ceiling controls source access. Checkout returns do not activate grants. Retry unresolved mutations with the same request UUID. UTC credit cycles, no usage refill, overage off, no Terminal billing or data rights granted.

`POST /v1/account/billing/checkout`

## Authentication

`AccountSession`

## Parameters

| Name | Location | Required | Description |
| - | - | - | - |
| `X-Oddswire-Account` | header | No | UUID of an account where the signed-in user is a member; defaults to their oldest account. |

## Request body

```json theme={null}
{
  "$ref": "#/components/schemas/BillingActionInput"
}
```

## Responses

| Status | Meaning |
| - | - |
| 200 | Account ledger response; no-store. Key secrets appear only once on creation/rotation. Lists contain at most 100 recent entries, active keys first. |
| 400 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 401 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 403 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 404 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 405 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 409 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 422 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 429 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 500 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 503 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |
| 504 | Structured problem; see [error handling](https://docs.oddswire.io/errors.md). |

Full request and response schemas: [OpenAPI](https://docs.oddswire.io/openapi.json). [Authentication](https://docs.oddswire.io/authentication.md) · [Prices and coverage](https://docs.oddswire.io/data.md) · [Errors and credits](https://docs.oddswire.io/errors.md).


## OpenAPI

````yaml POST /v1/account/billing/checkout
openapi: 3.1.2
info:
  description: >-
    Generated from canonical/account/usage DTOs and handler registries. Atomic
    included credits and durable usage, UTC monthly cycles, overage off. Full
    local response write/flush is the observable completion boundary; uncertain
    crash/outage deliveries recover free. Live Clerk login needs provider setup.
    Test-only Stripe billing uses signed durable receipts and reconciled app
    entitlements; real sandbox verification remains open. Dashboard and
    WebSocket are local pilots. Bounded history/as-of/lines and CSV/Parquet
    exports require separate current history/export grants and source-purpose
    reviews. Public launch remains gated. Namespaces are never joined by
    coincident IDs.
  title: Oddswire REST v1 local pilot
  version: 1.0.0
servers:
  - url: http://127.0.0.1:9113
security: []
externalDocs:
  description: WebSocket v1 AsyncAPI contract
  url: http://127.0.0.1:9113/asyncapi.json
paths:
  /v1/account/billing/checkout:
    post:
      summary: billingCheckout
      description: >-
        Test-only billing; owner session required for mutations, owner/admin for
        reads. Fixed test catalogue; enrollment ceiling controls source access.
        Checkout returns do not activate grants. Retry unresolved mutations with
        the same request UUID. UTC credit cycles, no usage refill, overage off,
        no Terminal billing or data rights granted.
      operationId: billingCheckout
      parameters:
        - description: >-
            UUID of an account where the signed-in user is a member; defaults to
            their oldest account.
          in: header
          name: X-Oddswire-Account
          required: false
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillingActionInput'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingActionPage'
          description: >-
            Account ledger response; no-store. Key secrets appear only once on
            creation/rotation. Lists contain at most 100 recent entries, active
            keys first.
          headers:
            X-Oddswire-Credit-Cost:
              $ref: '#/components/headers/X-Oddswire-Credit-Cost'
            X-Oddswire-Credits-Limit:
              $ref: '#/components/headers/X-Oddswire-Credits-Limit'
            X-Oddswire-Credits-Remaining:
              $ref: '#/components/headers/X-Oddswire-Credits-Remaining'
            X-Oddswire-Credits-Reserved:
              $ref: '#/components/headers/X-Oddswire-Credits-Reserved'
            X-Oddswire-Credits-Reset:
              $ref: '#/components/headers/X-Oddswire-Credits-Reset'
            X-Oddswire-Credits-Used:
              $ref: '#/components/headers/X-Oddswire-Credits-Used'
            X-Oddswire-Metering:
              $ref: '#/components/headers/X-Oddswire-Metering'
            X-Oddswire-Overage:
              $ref: '#/components/headers/X-Oddswire-Overage'
            X-Oddswire-Usage-State:
              $ref: '#/components/headers/X-Oddswire-Usage-State'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '400':
          $ref: '#/components/responses/Problem'
        '401':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Problem'
        '404':
          $ref: '#/components/responses/Problem'
        '405':
          $ref: '#/components/responses/Problem'
        '409':
          $ref: '#/components/responses/Problem'
        '422':
          $ref: '#/components/responses/Problem'
        '429':
          $ref: '#/components/responses/Problem'
        '500':
          $ref: '#/components/responses/Problem'
        '503':
          $ref: '#/components/responses/Problem'
        '504':
          $ref: '#/components/responses/Problem'
      security:
        - AccountSession: []
components:
  schemas:
    BillingActionInput:
      additionalProperties: false
      properties:
        amount_minor:
          type: integer
        invoice_id:
          type: string
        plan:
          type: string
        product:
          type: string
        request_key:
          type: string
        trial:
          type: boolean
      required:
        - request_key
        - product
      type: object
    BillingActionPage:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: '#/components/schemas/BillingActionResult'
          type: array
        meta:
          $ref: '#/components/schemas/Meta'
        missing:
          items:
            $ref: '#/components/schemas/Missing'
          type: array
      required:
        - data
        - missing
        - meta
      type: object
    BillingActionResult:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        detail:
          type: string
        id:
          type: string
        kind:
          type: string
        provider_id:
          type: string
        request:
          $ref: '#/components/schemas/BillingActionInput'
        retryable:
          type: boolean
        state:
          type: string
        url:
          type: string
      required:
        - retryable
        - id
        - state
        - detail
      type: object
    Meta:
      additionalProperties: false
      properties:
        consistency:
          type: string
        count:
          type: integer
        namespace:
          type: string
        next_cursor:
          type: string
        request_id:
          type: string
        sent_ts:
          format: date-time
          type: string
        snapshot_ts:
          format: date-time
          type: string
        version:
          type: string
      required:
        - version
        - request_id
        - sent_ts
        - snapshot_ts
        - next_cursor
        - count
        - consistency
      type: object
    Missing:
      additionalProperties: false
      properties:
        detail:
          type: string
        family:
          $ref: '#/components/schemas/Family'
        fixture_id:
          $ref: '#/components/schemas/ID'
        quote_key:
          type: string
        reason:
          type: string
        source_id:
          $ref: '#/components/schemas/ID'
      required:
        - reason
        - detail
      type: object
    Problem:
      additionalProperties: false
      properties:
        code:
          type: string
        detail:
          type: string
        invalid_params:
          items:
            $ref: '#/components/schemas/InvalidParam'
          type: array
        missing:
          items:
            $ref: '#/components/schemas/Missing'
          type: array
        request_id:
          type: string
        status:
          type: integer
        title:
          type: string
        type:
          type: string
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
        - invalid_params
        - missing
      type: object
    Family:
      enum:
        - 1x2
        - total
        - asian_handicap
      type: string
    ID:
      maximum: 9007199254740991
      minimum: 1
      type: integer
    InvalidParam:
      additionalProperties: false
      properties:
        name:
          type: string
        reason:
          type: string
      required:
        - name
        - reason
      type: object
  headers:
    X-Oddswire-Credit-Cost:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Credits-Limit:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Credits-Remaining:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Credits-Reserved:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Credits-Reset:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Credits-Used:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Metering:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Overage:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Oddswire-Usage-State:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
    X-Request-ID:
      description: >-
        Account-scoped admission snapshot where authenticated: remaining
        excludes holds; used counts settled calls. Cost 1 reserves one credit;
        actual charge settles only after complete local write/flush. Inspect
        free account/usage by request ID for final state. UTC reset is RFC3339;
        overage is off. Unknown credentials disclose no account counters.
      schema:
        type: string
  responses:
    Problem:
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
      description: >-
        Structured actionable problem; errors consume zero credits. Quota
        exhaustion/unconfigured returns 402 with counters/reset headers and free
        usage guidance. 429 Retry-After is separate abuse control. No database
        details or credentials.
      headers:
        X-Oddswire-Credit-Cost:
          $ref: '#/components/headers/X-Oddswire-Credit-Cost'
        X-Oddswire-Credits-Limit:
          $ref: '#/components/headers/X-Oddswire-Credits-Limit'
        X-Oddswire-Credits-Remaining:
          $ref: '#/components/headers/X-Oddswire-Credits-Remaining'
        X-Oddswire-Credits-Reserved:
          $ref: '#/components/headers/X-Oddswire-Credits-Reserved'
        X-Oddswire-Credits-Reset:
          $ref: '#/components/headers/X-Oddswire-Credits-Reset'
        X-Oddswire-Credits-Used:
          $ref: '#/components/headers/X-Oddswire-Credits-Used'
        X-Oddswire-Metering:
          $ref: '#/components/headers/X-Oddswire-Metering'
        X-Oddswire-Overage:
          $ref: '#/components/headers/X-Oddswire-Overage'
        X-Oddswire-Usage-State:
          $ref: '#/components/headers/X-Oddswire-Usage-State'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
  securitySchemes:
    AccountSession:
      description: >-
        Clerk session JWT, or one-hour CLI-only local session. No cookie
        authentication.
      scheme: bearer
      type: http

````

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