---
title: "Start a Stripe Checkout Session"
method: POST
path: "/v1/billing/checkout"
tags: ["billing"]
---

# Start a Stripe Checkout Session

`POST /v1/billing/checkout`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/billing/checkout`
- Auth: HTTP bearer

Create a hosted Checkout Session for a seat subscription or a credit pack; returns its URL.

## Headers

- `X-Tenant-Id` string, nullable

## Request body

- CheckoutRequest: POST /v1/billing/checkout body: start a Stripe Checkout Session. * ``subscription``: the flat Founding plan; ``plan``/``seats`` are ignored (a ``plan`` is still accepted for the legacy per-seat path when one is supplied). * ``topup``: a one-time ladder purchase; ``topup_tier`` is required. * ``credits``: the legacy per-unit pack; ``quantity`` applies.
  - `kind` 'subscription' | 'topup' | 'credits' | 'setup', required: What a checkout session buys. * ``SUBSCRIPTION``: the flat $45/mo Founding plan (no seats, no plan needed). * ``TOPUP``: a one-time credit purchase from the 7-tier ladder (``topup_tier``). * ``CREDITS``: the legacy one-time credit pack (per-unit ``quantity``); retained so the pre-v2 pack checkout keeps working until the ladder fully replaces it. * ``SETUP``: no charge; a ``mode=setup`` session that saves a card for auto-refill (started via the dedicated setup-session endpoint, not ``/billing/checkout``).
  - `plan` 'team' | 'business': A purchasable seat plan, mapped to a per-seat recurring Stripe price (legacy). Superseded by the flat Founding subscription (``CheckoutKind.SUBSCRIPTION`` needs no plan); kept so the legacy seat checkout path still validates for historical callers.
  - `seats` integer
  - `quantity` integer
  - `topup_tier` '10k' | '25k' | '50k' | '100k' | '300k' | '750k' | '2m': A rung of the 7-tier one-time top-up ladder (plan §1.3). The value is the settings suffix (``stripe_price_topup_<value>``) so the API name, the catalog key, and the settings field stay same-same.

## Response `200`

Successful Response

- CheckoutResponse: The hosted Checkout Session URL the dashboard redirects the buyer to.
  - `checkout_url` string, required
  - `session_id` string, required

## Other responses

- `400`: Malformed request (unknown plan, or no billing account yet).
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `409`: Conflict
- `422`: Validation error
- `502`: The payment provider call failed.
- `503`: Billing is not configured on this deployment.

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
