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

# Start checkout

> Create a Stripe Checkout session for a subscription or a credit pack.

Server-side checkout creation. Returns a Stripe-hosted URL; the caller
redirects the user there. Never expose the Stripe secret key to the
browser, this endpoint exists precisely to keep it server-side.

### Body

<ParamField body="price_id" type="string" required>
  Stripe price id. Must be one of the prices configured on the server
  (see [`GET /v1/stripe/catalog`](/api-reference/billing/catalog)).
  Hostile price ids are rejected with `400 invalid_args`.
</ParamField>

<ParamField body="success_url" type="string">
  Where to send the user after a successful payment. Default:
  `${origin}/PaymentSuccess?session_id={CHECKOUT_SESSION_ID}`.
</ParamField>

<ParamField body="cancel_url" type="string">
  Where to send the user if they bail out. Default:
  `${origin}/PaymentCancel`.
</ParamField>

### Response

```json theme={null}
{
  "url":        "https://checkout.stripe.com/c/pay/cs_test_...",
  "session_id": "cs_test_...",
  "kind":       "credit_pack"
}
```

`kind` is either `"subscription"` or `"credit_pack"`, useful when
the UI wants to show different post-checkout messaging.

### Errors

| Status | Code                     | Meaning                                           |
| ------ | ------------------------ | ------------------------------------------------- |
| 401    | `unauthenticated`        | Missing `Authorization` or `X-Lavendly-User-Id`.  |
| 400    | `invalid_args`           | Unknown `price_id` (not in the server's catalog). |
| 502    | `billing_upstream`       | Stripe returned a non-2xx.                        |
| 503    | `billing_not_configured` | `STRIPE_SECRET_KEY` not set on this deploy.       |
