---
title: "Pricing & billing"
description: "pirouter is prepaid: you add credit to a workspace wallet, each request is charged for the tokens it used, a balance below the estimated cost returns 402, and a request refused before it reaches a provider is never charged."
canonical: "https://pirouter.ai/docs/guides/billing"
last-updated: "2026-10-17"
lang: "en"
source: "content/docs/en/guides/billing.mdx"
---

# Pricing & billing

pirouter is prepaid: you add credit to a workspace wallet, each request is charged for the tokens it used, a balance below the estimated cost returns 402, and a request refused before it reaches a provider is never charged.

Add credit to your workspace wallet first; each request is then charged to it for the tokens it actually used, at prices that differ by model. When the balance cannot cover a request's estimated cost, the request is refused with `402` before it is forwarded.

## The wallet

Each workspace has one wallet, held in US dollars. Every key in the workspace draws on it.

The wallet holds three kinds of credit, shown separately under **Credits** in the console:

| Credit    | Where it comes from                |
| --------- | ---------------------------------- |
| Gift      | Granted by pirouter                |
| Promo     | Granted by pirouter in a promotion |
| Purchased | Bought by you                      |

Signing up does not come with credit, and only pirouter grants gift and promo credit, so a new workspace starts with a balance of 0.

pirouter charges a wallet's gift credit first, then promo credit, then purchased credit.

While a request is running, the gateway reserves part of your credit for its estimated cost. When the request finishes it is settled at its actual usage, and the unused part of the reservation is released.

## Prices

Prices are per token and differ for each model. The [models page](https://pirouter.ai/models) lists input, output and cache prices for every model.

To read prices from the API: each model returned by `GET /v1/models` has a `pricing` object. Its numbers are US dollars per token.

| Field                  | What it prices                           |
| ---------------------- | ---------------------------------------- |
| `prompt`               | Input tokens                             |
| `completion`           | Output tokens                            |
| `input_cache_read`     | Input tokens read from the cache         |
| `input_cache_write`    | Input tokens written to the cache        |
| `input_cache_write_1h` | Input tokens written to the 1-hour cache |
| `internal_reasoning`   | Reasoning tokens                         |
| `image_token`          | Input image tokens                       |
| `image_output`         | Output image tokens                      |

A field the model has no price for is absent from `pricing`.

For what an image request is charged, see [Generate and edit images](https://pirouter.ai/docs/guides/images.md#billing).

### Long-context tiers

Some models have a separate price tier for long inputs, listed in `pricing.overrides`. Each tier has a `min_prompt_tokens`. When the input tokens of a request reach that threshold, the request is priced at that tier. When several tiers are reached, the one with the highest threshold applies.

### Limited-time discounts

The `pricing` in `GET /v1/models` is the list price. It does not include limited-time discounts.

While a discount is active, the models page shows both the price in effect and the list price. To read the price in effect from the API, call `GET /v1/models/{vendor}/{model}/endpoints`: for each provider, `pricing` is the price in effect, `list_pricing` is the list price, and `discount` gives the percentage in `percent_off` and the end time in `ends_at`.

Requests are settled at the price in effect.

### What one request cost

Open **Logs** in the console. Each request lists its input, output, cache read, cache write and reasoning tokens, and what the request cost.

If your client closes the connection before the response finishes, the usage up to that point is still charged.

### Requests that fail

A request refused before it is forwarded to a provider is never charged and is not in **Logs**: failed authentication, an insufficient balance, pirouter's rate limit, an unknown model, failed validation, no eligible provider, a model not served on the endpoint called, a context that is plainly too long, or a body over the size limit.

A request that reached a provider and failed appears in **Logs**. Whether it is charged depends on how it failed:

| What happened                                                                                                                                                                          | Charged                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| An attempt failed and the next attempt took over ([failover](https://pirouter.ai/docs/guides/routing.md#failover) or a [model fallback](https://pirouter.ai/docs/guides/fallbacks.md)) | Nothing for the failed attempt; you pay for the one that returned the response |
| The provider rejected the request with `400` or `422`                                                                                                                                  | Nothing                                                                        |
| No first byte within the [time limit](https://pirouter.ai/docs/guides/timeouts.md#timeouts)                                                                                            | Nothing                                                                        |
| An error event inside a stream, or the response cut off before its end                                                                                                                 | Nothing, including usage read before the cut                                   |
| Every attempt failed, and the last provider returned an error status such as `500`                                                                                                     | The estimated input                                                            |
| Your client closed the connection                                                                                                                                                      | The usage up to that point                                                     |

## Add credit

1. **Open Credits**

   Sign in to the [console](https://app.pirouter.ai), open **Credits** and click **Add credit**. Only workspace owners can add credit.

2. **Choose an amount and a payment method**

   One top-up is between $10 and $10,000, with at most two decimal places. You can pay by card, Alipay or WeChat Pay. Payment is completed on a page hosted by Stripe.

   > **Note:** The wallet is held in US dollars and the charge is made in Hong Kong dollars, at a fixed rate of 1 USD = 7.85 HKD. Any fraction of a Hong Kong cent is rounded up. A $10 top-up charges HK$78.50 and adds $10 of credit.

3. **Pay**

   When the payment completes, you land back in the console on a page showing the credit that was added. Confirmation can lag the page by a few seconds. If the page says it cannot confirm the payment yet, refresh your balance a little later. Do not pay a second time.

   The page shown after a successful payment links to the Stripe receipt. The link stops working after about 30 days.

## When the balance runs out

Before forwarding a request, the gateway checks the balance. The available balance is the sum of the three kinds of credit, minus what running requests have reserved. If it cannot cover the estimated cost of the request, the gateway returns `402` with the error code `insufficient_balance` and does not forward the request.

```json
{
  "error": {
    "message": "Your workspace balance cannot cover this request. Add credit to your pirouter wallet, then retry.",
    "type": "permission_error",
    "code": "insufficient_balance"
  }
}
```

A request that has already started is not cut off when the balance runs out. It is settled when it ends, which can take your purchased credit below zero. The next top-up pays off the negative amount first. While the balance is negative, every new request returns `402`.

> **Warning:** On a `402`, add credit and then retry. Do not retry `402` automatically in your code: until the balance changes, every attempt fails.

## What billing cannot do today

- **Invoices.** There are none today. The record of a top-up is the Stripe receipt.
- **Automatic top-up.** There is none today. Every top-up is a separate one-time payment.
- **Promo codes.** The top-up page has a field for one. It does not work yet.
