Skip to main content
POST
/
api
/
v1
/
billing
/
checkout
Create a top-up checkout
curl --request POST \
  --url https://api.example.com/api/v1/billing/checkout \
  --header 'Content-Type: application/json' \
  --data '
{
  "amount_cents": 123,
  "scope": "<string>",
  "success_url": "<string>"
}
'
Top up credits against the caller’s personal balance or an organization’s shared team billing pool. Returns a hosted checkout URL your application opens in a new tab or redirects the user to.

Authentication

Requires a Bearer token with the billing scope. See Authentication.

Body

amount_cents
integer
required
Amount to add, in cents. Minimum 500 (5.00),maximum100000(5.00), maximum `100000` (1,000.00).
scope
string
"user" (default when personal) or "org" (default when the caller is inside a team and holds manageBilling). When "org", the top-up lands on the team’s shared credit pool at organizations.polar_customer_id and all subsequent team-scoped API usage draws from that pool until it’s depleted.
success_url
string
Optional. URL to redirect the user to after successful checkout. Defaults to /dashboard/billing?topup=success (or /dashboard/billing?topup=success&scope=team when scope: "org").

Example: personal top-up

curl
curl -X POST "https://api.hitheo.ai/api/v1/billing/checkout" \
  -H "Authorization: Bearer $THEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount_cents": 2500 }'

Example: team top-up

curl
curl -X POST "https://api.hitheo.ai/api/v1/billing/checkout" \
  -H "Authorization: Bearer $THEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount_cents": 10000, "scope": "org" }'
SDK
// Fund the team pool. Admins with `manageBilling` can call this; any
// other scope returns 403.
const { checkout_url } = await theo.billingCheckout({
  amount_cents: 10_000,
  scope: "org",
});
window.open(checkout_url, "_blank");

Response

{
  "checkout_url": "https://checkout.hitheo.ai/...",
  "scope": "org"
}

Errors

StatusCodeMeaning
400missing_amountamount_cents missing or not an integer.
400amount_too_lowBelow the $5.00 minimum.
400amount_too_highAbove the $1,000.00 maximum.
400org_context_requiredRequested scope: "org" without an active team.
402team_payment_method_requiredTeam key creation blocked until the team funds billing. Retry after a checkout.
403permission_deniedCaller lacks manageBilling in the active team.
503billing_unavailableBilling isn’t configured on this deployment.

Lifecycle

  1. Client calls this endpoint with amount_cents and optional scope.
  2. The billing service reserves the right customer (personal or team), creates a checkout session, and returns checkout_url.
  3. The user completes checkout.
  4. A background webhook routes the top-up to the correct credit pool (user vs team) and marks the customer as having a payment method on file.
  5. Subsequent API usage drafts from the funded pool.