---
title: "Start a Stripe Checkout session for a paid plan."
method: POST
path: "/v1/billing/checkout"
tags: ["Billing"]
---

# Start a Stripe Checkout session for a paid plan.

`POST /v1/billing/checkout`

## Request

- Base URL: `https://api.inboxy.net`
- URL: `https://api.inboxy.net/v1/billing/checkout`
- Auth: HTTP bearer

Requires `manage` scope. Refuses if the account already has an active subscription (`already_subscribed`, 409 — use `/v1/billing/change-plan` to switch tiers instead). `plan_id` must name a real, paid, currently-purchasable plan (`bad_request`, 400, for an unknown or free plan_id; `plan_unavailable`, 404, for a real paid plan with no `stripe_price_id` yet). The billing cycle anchor is pinned to the next 1st-of-the-month UTC boundary regardless of when checkout completes.

## Request body

- BillingCheckoutRequest
  - `plan_id` string, required: A paid plan's immutable id, e.g. `standard_v1`. Free plans and unpurchasable plans (no `stripe_price_id` yet) are rejected.

## Response `200`

Checkout session created — redirect the caller to `url`.

- object
  - `url` string, uri, required

## Other responses

- `400`: Malformed request.
- `403`: Token lacks the required scope.
- `404`: `plan_unavailable` — plan exists but isn't purchasable yet.
- `409`: `already_subscribed` — use `/v1/billing/change-plan` instead.

---

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