---
title: "Create a checkout session for one of the clinic's own programs"
method: POST
path: "/api/v1/checkout/sessions"
tags: ["Checkout Sessions"]
---

# Create a checkout session for one of the clinic's own programs

`POST /api/v1/checkout/sessions`

## Request

- Base URL: `https://api-dev.fusehealth.com`
- URL: `https://api-dev.fusehealth.com/api/v1/checkout/sessions`
- Auth: API key in header `x-api-key`

Creates the session bookkeeping row for the FUSE-hosted, iframe-isolated intake+checkout component. Computes and stores questionnaireVersionHash (the legal audit trail — sha256 over the program's questionnaire content at creation time) and returns an opaque sessionToken + embedUrl the brand mounts in an iframe. This is the ONE endpoint a PUBLISHABLE key (`fuse_pk_…`) may call — every other endpoint on this surface, including GET /checkout/sessions/{id}, 403s a publishable key with `KEY_KIND_NOT_ALLOWED`. Publishable keys are additionally hard rate-limited on this route.

## Request body

- CheckoutSessionCreate
  - `programId` string, uuid, required: Must belong to the key's own clinic (404 otherwise).
  - `metadata` object: Brand-supplied data, stored verbatim and capped at 16 KiB (DB CHECK constraint plus model-layer validation). FUSE never displays or acts on it, with one exception: the marketing-attribution keys lead_id (or legacy leadId), utm_source, utm_medium, utm_campaign, utm_content, gclid and fbclid are copied onto the resulting order and echoed on the intake.started webhook. Every other key is ignored.
  - `successUrl` unknown

## Response `201`

Created

- object
  - `success` boolean
  - `data` CheckoutSessionCreated
    - `sessionId` string, uuid
    - `sessionToken` string: Opaque, HMAC-signed, short-lived (~30 min) credential for the embed page (not this API-key-authenticated surface) to load and render the session's questionnaire.
    - `embedUrl` string, uri: Mount this in an iframe on the brand's page.
    - `expiresAt` string, date-time

## Other responses

- `400`: Bad request (missing/invalid programId, metadata, or successUrl) or NO_QUESTIONNAIRE_CONFIGURED
- `401`: Missing, invalid, inactive, or expired API key (or JWT)
- `403`: Insufficient scope (INSUFFICIENT_SCOPE) — read-only key attempted a write
- `404`: Resource not found (or not owned by the key's clinic)
- `429`: Rate limit exceeded for this key. Respect the `Retry-After` header. Applies to every endpoint.

---

[API](https://skmtc.dev/fusehealth/apis/fuse-brand-api-external.md) · [All operations](https://skmtc.dev/fusehealth/apis/fuse-brand-api-external/llms.txt) · [OpenAPI document](https://skmtc.dev/fusehealth/apis/fuse-brand-api-external/revisions/50821832728c?raw)
