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

# Billing and credits

> Read the credit balance, buy credits with machine payments, and manage automatic top-ups

export const ScarfPixel = () => <img referrerPolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=831669b6-b4bd-42cb-8832-2122c03e1d5f" alt="" width="1" height="1" style={{
  position: "absolute",
  width: 0,
  height: 0,
  opacity: 0,
  pointerEvents: "none"
}} />;

<ScarfPixel />

Non-Enterprise workspaces use scan credits for standard managed pentests. One credit costs \$1.00. Enterprise scans are included in the plan and do not consume the credit wallet. Retests and supply-chain dependency scans are also credit-exempt. These endpoints let an API caller or agent read the balance, buy credits, and manage automatic top-ups.

The scan price is calculated from the requested scope before launch. At the current default `ultra` tier, a standard code review or live test starts at 60 credits for one target, then adds 20 credits for each additional repository or domain. A local-source-only code review therefore starts at 60 credits; uploading source does not make the scan free. Other scan tiers and full-audit engagements have different estimates, so treat the estimate returned for the request as authoritative.

If a non-Enterprise workspace cannot cover the estimate, scan creation returns HTTP `402 Payment Required` with code `scan_credit_limit_reached`. The CLI maps this to exit code `5`. The rejected request creates no scan and consumes no credits. Validation and plan rejections that occur before launch also consume no credits.

The `402` body tells the caller how to recover. It leads with a credit purchase that is sized to the rejected request:

* `credits_to_buy` is the number of credits that the request needs above the current balance. Strix rounds it up to a whole credit and keeps it inside the top-up limits. When the route cannot estimate the request, the value is the default pack.
* `price_usd` is the price of `credits_to_buy` credits.
* `checkout_url` is a hosted checkout link for exactly `credits_to_buy` credits. Open it in a browser and pay. The field is present only when the token could call `POST /api/v1/billing/checkout` itself: the token has `billing:write`, has no `rbac_scopes`, and belongs to an admin or is a service token. When the field is absent, the `hint` names the billing page instead.
* `hint` is the one-line next step. The CLI prints it after the error.
* `topup_options` lists the recovery paths in the order that a headless caller should try them. Each option contains the API `method` and `path`, the matching `cli` command, and a `description`. The `POST` options also contain the request `body` to send.

```json theme={null}
{
  "detail": "Out of credits. Buy more to keep running pentests. Buy 14 credits ($14) at https://<checkout-host>/c/... (hosted checkout, opens in the browser). Then retry this request.",
  "requiredTier": "cloud",
  "code": "scan_credit_limit_reached",
  "hint": "Buy 14 credits ($14) at https://<checkout-host>/c/... (hosted checkout, opens in the browser). Then retry this request.",
  "checkout_url": "https://<checkout-host>/c/...",
  "credits_to_buy": 14,
  "price_usd": 14,
  "topup_url": "https://app.strix.ai/settings/billing",
  "topup_options": [
    { "method": "POST", "path": "/api/v1/billing/checkout", "body": { "product": "strix_top_up", "credits": 14 }, "cli": "strix cloud billing subscribe --plan strix_top_up --data '{\"credits\":14}'", "description": "Create a hosted checkout link for exactly the credits this request needs. The user pays in the browser. When the 402 already carries `checkout_url`, open that link instead of calling this." },
    { "method": "POST", "path": "/api/v1/billing/topup", "body": { "credits": 14 }, "cli": "strix cloud billing topup --credits 14", "description": "Opt-in machine payment for agents that hold a Stripe agent wallet. ..." },
    { "method": "GET", "path": "/api/v1/billing/credits", "cli": "strix cloud billing credits", "description": "Check the current credit balance." }
  ],
  "required_credits": 60,
  "available_credits": 46
}
```

Scan reruns, schedule creation with `also_run_now: true`, and manual schedule triggers return the same body. Chat requests on the Cloud plan return the same body with code `chat_credit_limit_reached` when the wallet is empty. Chat rejections use the default pack for `credits_to_buy` and do not contain `checkout_url`. See [Chat](/guides/chat) for how Chat uses credits.

The machine payment option (`POST /api/v1/billing/topup`) is for agents that hold a Stripe agent wallet. Callers without a wallet must skip it and use the hosted checkout.

When the workspace can still start the Cloud plan trial, the body also contains a `plan_trial` object after the top-up fields:

```json theme={null}
{
  "plan_trial": {
    "plan": "strix_cloud",
    "trial_days": 7,
    "includes": "PR security reviews on every pull request",
    "adds_scan_credits": false,
    "method": "POST",
    "path": "/api/v1/billing/checkout",
    "cli": "strix cloud billing subscribe --plan strix_cloud",
    "url": "https://app.strix.ai/settings/billing",
    "description": "Separately, the Cloud plan adds PR security reviews on every pull request (no scan credits) and starts with a free trial of up to 7 days: ..."
  }
}
```

The Cloud plan includes PR security reviews and does not include scan credits. `adds_scan_credits` is always `false`. A caller that needs to run a scan must buy credits, not start the trial. The `plan_trial` object is present only when the workspace has not subscribed before, can still start the trial, and checkout would not charge the caller at once. When the object is present, the `detail` text also mentions the trial. Use `plan` as the `product` value for `POST /api/v1/billing/checkout`. Subscribers, former subscribers, and workspaces with an ended trial receive the plain top-up guidance.

## Get the credit balance

```bash theme={null}
curl -X GET "https://app.strix.ai/api/v1/billing/credits" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
```

**Required scope:** `billing:read`

The response contains the current `balance`, `chat_balance`, and `price_per_credit_cents`. Scans reserve whole credits from `balance`. `chat_balance` gives the whole credits that Chat can still spend. It equals `balance`, or `balance` plus one while Chat holds the unspent part of a credit that it started to use. An Enterprise workspace may still have a wallet balance, but normal Enterprise scan launches and chats do not debit it.

## Buy credits with a machine payment

This endpoint accepts agent payments through the Stripe Machine Payments Protocol (MPP). The purchase requires an admin role on the workspace.

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/billing/topup" \
  -H "X-Strix-Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"credits": 20}'
```

**Required scope:** `billing:write`

Send the API token in the `X-Strix-Authorization` header for this endpoint. MPP uses the standard `Authorization` header for the payment credential.

The first request returns HTTP `402 Payment Required` with a payment challenge in the `WWW-Authenticate` header. Pay the challenge with an MPP wallet, for example the Stripe Link agent wallet, and retry the request with the payment credential. See the [Stripe machine payments documentation](https://docs.stripe.com/payments/machine) for wallet setup.

The challenge body also contains `checkout_url` and `wallet_setup`. `checkout_url` is a hosted checkout link for the same number of credits. It is present when the token could call `POST /api/v1/billing/checkout` itself. `wallet_setup` tells a caller without a wallet to open `checkout_url` and pay in the browser instead. The protocol headers of the challenge do not change.

```json theme={null}
{
  "checkout_url": "https://<checkout-host>/c/...",
  "wallet_setup": "Most users should skip this challenge and open checkout_url to pay for 20 credits in the browser. ..."
}
```

When the payment succeeds, the response confirms the grant:

```json theme={null}
{
  "credits_granted": 20,
  "duplicate": false,
  "reference": "pi_...",
  "balance": 40
}
```

Credit grants are idempotent on the payment `reference`. A retry with the same paid credential returns `duplicate: true` and grants no additional credits.

## Get automatic top-up settings

```bash theme={null}
curl -X GET "https://app.strix.ai/api/v1/billing/auto-topup" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
```

**Required scope:** `billing:read`

The response contains `enabled`, `topup_credits`, `monthly_cap_credits`, `chat_cap_credits`, and `used_this_month`.

## Update automatic top-up settings

Automatic top-ups charge the saved payment method of the workspace when the balance runs out. Scan launches and Chat turns both trigger a top-up. The same `topup_credits` and `monthly_cap_credits` apply to both. The `chat_cap_credits` limit applies to one chat. When the top-ups for a chat reach that limit, Strix pauses the chat instead of a new charge. Manual purchases and scans are not affected. The update requires an admin role on the workspace.

```bash theme={null}
curl -X PUT "https://app.strix.ai/api/v1/billing/auto-topup" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "topup_credits": 240,
    "monthly_cap_credits": 2400,
    "chat_cap_credits": 20
  }'
```

**Required scope:** `billing:write`

Set `monthly_cap_credits` to `null` to remove the monthly limit. Set `chat_cap_credits` to `null` to remove the limit for one chat. An omitted field keeps the stored value.

An admin can also lift the per-chat limit for a single chat, without a change to the workspace limit. Use `PUT /api/v1/chat/<CHAT_ID>/auto-topup-limit` with `{"lifted": true}`. The monthly cap still applies to that chat. See [Chat](/guides/chat#lift-the-per-chat-automatic-top-up-limit) for the details.

## Create a checkout link

Use this endpoint to buy a plan or a credit pack. The response contains a hosted checkout page. A person must open the page and complete the payment.

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/billing/checkout" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"product": "strix_cloud"}'
```

**Required scope:** `billing:write`

The accepted products are `strix_cloud` for the Cloud plan, `strix_startup` for an approved startup offer, and `strix_top_up` for a credit pack. The request needs an admin role on the workspace. The response contains `checkout_url`. The open-source CLI opens this page with the `strix cloud billing subscribe --plan strix_cloud` command.

## Create a billing portal link

The billing portal shows the invoices of the workspace. A person can change the payment method and the plan there.

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/billing/portal" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
```

**Required scope:** `billing:write`

The request needs an admin role on the workspace. The response contains `portal_url`.

If the workspace does not yet have a billing customer, the endpoint returns HTTP `409 Conflict` with instructions to subscribe first. Create a checkout link with the preceding endpoint, complete that handoff as a person, and then request the portal again. Provider failures return `502 Bad Gateway`; an on-premises deployment where the hosted portal is unavailable returns `400 Bad Request`.

The CLI equivalent is `strix cloud billing portal`. It prints or opens the hosted link; it never changes payment details by itself.

For machine-payment top-ups, `strix cloud billing topup --credits <N> --no-pay` prints the payment challenge without paying it. In an interactive terminal, the paying form asks for confirmation. In an agent, CI, or other non-interactive process, payment cannot proceed unless `--yes` is present; obtain the user's approval before running `strix cloud billing topup --credits <N> --yes`. The `--yes` and `--no-pay` options are mutually exclusive. `--yes` authorizes the CLI to invoke the configured wallet, but Link may still require the user to approve or complete the payment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.