---
title: "Create Checkout Session Endpoint"
method: POST
path: "/v1/checkout/session"
tags: ["checkout"]
---

# Create Checkout Session Endpoint

`POST /v1/checkout/session`

## Request

- Base URL: `https://app.teetra.com` (the document declares no server; this is the origin it was published from)
- URL: `https://app.teetra.com/v1/checkout/session`
- Auth: none declared

Create a Stripe Checkout Session for subscription (Path B) for the AUTHENTICATED consumer.

WRITE-SIDE IDOR fix (R4 verify, issue 1 — see module docstring): requires the same
verified CONSUMER access token as ``/portal``. ``consumer_id`` is derived exclusively
from that token's subject and is what gets threaded into the Checkout Session's
(webhook-trusted) metadata — never anything the request body supplies. The Stripe
``customer_id`` handed to Checkout is looked up ONLY from that subject's own prior
linkage, never accepted from the caller.

## Request body

- CheckoutSessionRequest: Request payload to create a checkout session. Deliberately has NO ``consumer_id``/``consumer_subject_id``/``customer_id`` field (R4 verify, issue 1 — see module docstring). Those used to be identity inputs a caller could set to anything, including another subject's id; the consumer is now resolved SOLELY from the verified access token, and the Stripe customer is looked up from that subject's own prior linkage — never from anything the request body supplies. A caller that still sends these fields (an older client) has them silently ignored, matching ``CustomerPortalRequest``'s already-established precedent.
  - `price_id` string, required: Stripe Price ID for subscription
  - `success_url` string, nullable: Redirect URL upon successful checkout
  - `cancel_url` string, nullable: Redirect URL upon checkout cancellation
  - `customer_email` string, nullable: Customer email address
  - `adapter_id` string, nullable: Warrant Adapter ID
  - `conversion_id` string, nullable: Warrant Conversion ID
  - `managed_payments` boolean: Enable Stripe Managed Payments as MoR
  - `metadata` object, nullable: Custom session metadata. Reserved keys (warrant_adapter_id, warrant_consumer_id, warrant_conversion_id, path, mor) are ALWAYS overwritten server-side with the authoritative values and can never be set or overridden from here; the unprefixed aliases some downstream readers fall back to (adapter_id, consumer_id, conversion_id, amount_usd) are stripped entirely for the same reason (R5 verify, final sweep) — see app.billing.checkout.create_checkout_session.

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/teetra/apis/warrant.md) · [All operations](https://skmtc.dev/teetra/apis/warrant/llms.txt) · [OpenAPI document](https://skmtc.dev/teetra/apis/warrant/revisions/0e272d563cc4?raw)
