---
title: "Create Checkout"
method: POST
path: "/billing/checkout"
tags: ["billing"]
---

# Create Checkout

`POST /billing/checkout`

## Request

- Base URL: `https://api.seal.net` (the document declares no server; this is the origin it was published from)
- URL: `https://api.seal.net/billing/checkout`
- Auth: none declared

Create a Stripe Checkout Session for a seal upgrade.

Moved server-side in CF-3, made durable in ISSUE-0609. See module
docstring for the full contract.

## Request body

- CheckoutRequest: POST /billing/checkout body. `seal_id` lives in the body (not the URL) because the legacy frontend route signed contracts with this exact shape. Public URL surface stability beats path-style aesthetics here. `ValidSealId` from `_common.py` is a `Path()`-bound dependency (it parses the seal_id off the URL) so we can't use it as a field type. The inline validator below mirrors the same regex (`SEAL_ID_PATTERN`) so the two sites can't drift.
  - `tier` string, required: Tier code: 5gb | 50gb | 500gb
  - `seal_id` string, required: Seal ID (8-char base64url)

## Response `200`

Successful Response

- CheckoutResponse: The payment page: `/pay` with Stripe's form (see `_pay_url`).
  - `url` string, required

## Other responses

- `422`: Validation Error

---

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