---
title: "Start an upgrade: a Stripe-hosted Checkout Session"
method: POST
path: "/v1/billing/checkout"
tags: ["Billing"]
---

# Start an upgrade: a Stripe-hosted Checkout Session

`POST /v1/billing/checkout`

## Request

- Base URL: `https://api.galleyrender.com`
- URL: `https://api.galleyrender.com/v1/billing/checkout`
- Auth: HTTP bearer

Returns a hosted Checkout URL for one paid plan. Open `url` in a browser and pay there — Galley never sees a card. The session carries the plan's flat price and its metered overage price, and Stripe Tax is calculated on the page.

**The plan does not change when this returns.** It changes when Stripe delivers `checkout.session.completed` and `customer.subscription.created` to our webhook, a second or two later. Poll `GET /v1/account` and read `subscription.status`.

The account must have a verified email address: the invoice, the receipt and every dunning message go to it. A keyless trial gets `permission_error` naming the call that fixes it.

## Request body

- CheckoutRequest
  - `plan` 'solo' | 'starter' | 'growth' | 'scale', required: The paid plan to subscribe to. `free` is not a checkout — it is a portal cancellation.
  - `interval` 'month' | 'year': Annual is ten months for twelve.
  - `success_url` string: Where Stripe returns on success. https on galleyrender.com only.
  - `cancel_url` string: Where Stripe returns if the customer backs out.

## Response `200`

A Checkout Session. Nothing has been charged.

- CheckoutSession
  - `object` 'checkout_session', required
  - `id` string, required
  - `url` string, required: The hosted page. Open it in a browser.
  - `expires_at` string, date-time, nullable
  - `account` string
  - `plan` 'solo' | 'starter' | 'growth' | 'scale', required
  - `interval` 'month' | 'year', required
  - `price_usd` number
  - `included_renders` integer: The plan's included quantity each month, in meter units: a PDF page is 2.5, an image 1. Solo's 500 is 200 PDF pages or 500 images. The name predates the page weighting and is kept for compatibility.
  - `overage_usd_per_render` number: Dollars per meter unit past the allowance — the price of one image. A PDF page is 2.5 of them: $0.015 on Solo, $0.01 on the larger plans.
  - `current_plan` string
  - `next_step` string
  - `note` string

## Other responses

- `400`: `invalid_request` — unknown `plan`, bad `interval`, or a return URL off galleyrender.com.
- `401`: `authentication_error`.
- `403`: `permission_error` — the account has no verified email address.

---

[API](https://skmtc.dev/galleyrender/apis/galley-render-api.md) · [All operations](https://skmtc.dev/galleyrender/apis/galley-render-api/llms.txt) · [OpenAPI document](https://skmtc.dev/galleyrender/apis/galley-render-api/revisions/a85d68468cd2?raw)
