---
title: "Charge the saved card for credits, or start Stripe Checkout"
method: POST
path: "/v1/billing/team/{team_id}/purchase-credits"
tags: ["billing"]
---

# Charge the saved card for credits, or start Stripe Checkout

`POST /v1/billing/team/{team_id}/purchase-credits`

## Request

- Base URL: `https://api.pioneer.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.pioneer.ai/v1/billing/team/{team_id}/purchase-credits`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer
- TypeScript: <https://skmtc.dev/pioneer/apis/brain-api/docs/v1/billing/team/:team_id/purchase-credits/post.ts> (a function with typed inputs; its response is checked against the schema)

Charge the saved card, or start Checkout when that is not possible.

Teams with a default payment method are charged in place and credits are
granted here. Teams without a usable card, or whose bank requires a 3DS
challenge, still go through hosted Checkout; the
``checkout.session.completed`` webhook applies those credits.

Args:
    request: Raw request, required by the rate limiter.
    team_id: Team the credits are bought for.
    body: Purchase amount, attempt id, and the Checkout return URLs.
    auth: Caller identity; payment enforcement is off because this route is
        how a team with no funds acquires them.

Returns:
    ``checkout_url`` set when the buyer must finish on Stripe; ``None``
    when the saved card was charged and credits are already on the balance.

Raises:
    HTTPException: 403 without MANAGE_BILLING; 400 when a Stripe customer
        cannot be resolved; 402 when the saved card is declined; 500 when
        payment succeeded but the grant failed; 502 or 503 when Stripe
        cannot start a session.

## Path parameters

- `team_id` string, required

## Request body

- PurchaseCreditsRequest: Request to buy credits, in place on the saved card or via Checkout.
  - `amount_usd` number, required: Amount in USD to purchase (max $500 per transaction)
  - `success_url` string, required: URL Stripe redirects to after a successful payment
  - `cancel_url` string, required: URL Stripe redirects to if the purchase is cancelled
  - `attempt_id` string, nullable: Caller-generated id for this purchase attempt, stable across retries of it (e.g. a UUID). Guarantees the card is charged once per attempt; omit and same-minute retries are collapsed instead.

## Response `200`

Successful Response

- PurchaseCreditsResponse: Response after a credit purchase attempt. ``checkout_url`` is set when the buyer must finish on Stripe Checkout. It is ``None`` when a saved card was charged and credits are already granted.
  - `success` boolean, required
  - `checkout_url` string, nullable: Stripe-hosted Checkout URL to redirect the user to
  - `message` string: Human-readable status detail

## Other responses

- `422`: Validation Error

## Changes

- **2026-09-24** `0e5e86e2bae5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pioneer/apis/brain-api/changes/v1/billing/team/:team_id/purchase-credits/post.md)

---

[API](https://skmtc.dev/pioneer/apis/brain-api.md) - [All operations](https://skmtc.dev/pioneer/apis/brain-api/llms.txt) - [OpenAPI document](https://skmtc.dev/pioneer/apis/brain-api/revisions/0e5e86e2bae5?raw)
