> To find and run AgentRouter tools, connect to https://mcp.agentrouter.to/. To search this documentation, use https://docs.agentrouter.to/_mcp/server. Append .md to a page URL for Markdown. For the documentation index, see https://docs.agentrouter.to/llms.txt.

# Billing

## One wallet, exact amounts

Each account has one prepaid USD wallet. `available_usd` can be spent; `reserved_usd` is held for runs in flight. All amounts in the API are decimal strings (`"0.00035"`), stored and settled exactly — never floating point.

```bash
curl -s https://api.agentrouter.to/v1/wallet -H "Authorization: Bearer $AGENTROUTER_API_KEY"
curl -s https://api.agentrouter.to/v1/wallet/transactions?limit=20 -H "Authorization: Bearer $AGENTROUTER_API_KEY"
```

Every hold, charge, release, refund and top-up is an entry in the wallet ledger and points at its run, top-up or dispute.

A usage reset returns the remaining charges from each account’s latest 100 calls at the campaign cutoff. Free, failed and previously refunded calls count toward the 100. Usage and Wallet show the original charge and its net amount on the same row. The transactions API returns the underlying ledger entries by default. Pass `group_refunds=true` to see refunds on the original charges.

## How a price is set

`describe` shows the current terms in `pricing`:

* **Base price.** Either the cost the provider reports for the call (`basis: upstream_usd`, for example AnyAPI's `costUsd` or Exa's `costDollars.total`), or the provider units the call used times a per-unit rate (`basis: units`, for example Search1API, Context.dev and Hunter credits).
* **`price_multiplier`.** One number applied to the base: `"1"` list price, `"0.5"` half price, `"1.2"` a 20% markup, `"0"` free. AgentRouter sets it per tool; clients never send it.
* **`pricing_version`.** An immutable snapshot of those terms. Invoke must send it, and a run keeps its snapshot even if prices change while it runs or when it is recovered later.

The receipt shows `base_charge_usd` (before the multiplier), `price_multiplier` and `customer_charge_usd`, plus the usage the charge is based on.

## What is charged

| Outcome                       | Charged?                                                        | `billing.reason`                                                             |
| ----------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Provider returned data        | Yes, base × multiplier, capped at the hold                      | `charged` (or `charged_capped` when the calculated charge exceeded the hold) |
| Provider reported zero usage  | No                                                              | `zero_base`                                                                  |
| Empty result                  | As `describe` says for that tool (`pricing.rules.empty_result`) | `charged` or `waived_empty_result`                                           |
| Provider error                | No                                                              | `waived_provider_error`                                                      |
| AgentRouter error             | No                                                              | `waived_platform_error`                                                      |
| Stopped before completion     | No                                                              | `waived_stopped`                                                             |
| Timed out on the server       | No                                                              | `waived_timeout`                                                             |
| Usage could not be determined | No (reconciled by AgentRouter)                                  | `waived_unknown_cost`                                                        |
| Free promotion                | No                                                              | `free_promotion`                                                             |
| Blocked before running        | No                                                              | `blocked_before_execution`                                                   |

A result that is valid but not useful for your task is charged; if a correct input returned wrong or unusable data, open a [dispute](/concepts/feedback-and-disputes). Your client timing out never cancels, refunds or re-runs a call.

## Holds and `max_cost_usd`

Before running, AgentRouter moves the amount needed for the call from available to reserved balance. This **hold is not a final charge**; it prevents concurrent calls from spending the same funds. After the run settles, the actual charge is taken from the hold and the unused amount becomes available again.

### How much is held?

The connector supplies a fixed or input-dependent usage bound. AgentRouter converts that bound to USD, applies the run's locked `price_multiplier`, and rounds up to the ledger's 12-decimal precision:

**Hold = estimated provider cost bound × price multiplier.** For a unit-billed tool, the provider cost bound is estimated units × the unit rate. `describe` shows `max_per_call_usd` or the estimation rule.

The provider supplies its prices; AgentRouter's connector defines the bound used for reservation, including more expensive fallback routes where applicable. Some connectors use a fixed bound even for a small request, so the hold can be larger than the eventual charge.

`max_cost_usd` is your spending limit for the call, not the amount automatically held. Its default is `"0.50"`. If the required hold is higher than the effective limit, the call is blocked with `MAX_COST_EXCEEDED`; AgentRouter does not take a smaller hold and run anyway. [Budgets](/concepts/budgets) can lower that limit and also limit spend per day, week, month or in total.

### Can the final charge exceed the hold?

**No. Your final charge cannot exceed the hold accepted for that run, which is also bounded by its effective `max_cost_usd`.** If actual provider usage would produce a larger charge, AgentRouter absorbs the excess and the receipt reports `billing.reason: charged_capped`. You are not charged an additional amount later for that excess.

For example, with a price multiplier of `1`, a run that holds $0.0154 and ends with a reported provider cost of $0.02 charges you at most $0.0154. AgentRouter absorbs the remaining $0.0046, even if you allowed up to \$0.50 when invoking it. These amounts illustrate the rule, not a fixed price for every tool.

### Is releasing a hold a refund?

Releasing unused funds makes reserved balance available again; a refund returns money that was actually charged. For example, a $0.0154 hold followed by a $0.0006 charge releases $0.0148. If a later [dispute](/concepts/feedback-and-disputes) refunds the full charge, it returns another $0.0006. The hold and the charge are not two separate debits.

### What if my available balance cannot cover the hold?

The call is stopped **before the provider is invoked**. The API returns HTTP `402` with a Run whose `status` is `BLOCKED`, `error.code` is `INSUFFICIENT_BALANCE`, and `billing.reason` is `blocked_before_execution`. No funds are reserved or charged for that blocked call. A `TOP_UP` hint points to the payment-link flow.

The check uses `available_usd`: money already held by other runs is unavailable. For example, $0.01 available cannot cover a $0.0154 hold, even if similar calls previously settled for only \$0.0006. Concurrent requests cannot reserve more than the available balance.

Add funds, or wait for other runs to release enough unused balance, then invoke again. The blocked run is terminal: it does not queue or automatically resume when funds arrive. **If you used an `Idempotency-Key`, use a new key for this new attempt**; reusing the original key returns the same blocked run. Creating a top-up link alone does not add funds, and AgentRouter never tops up automatically.

## Free promotions

A tool with `price_multiplier: "0"` is free for the promotion's period. Free still has limits: a daily number of free calls per account and a total promotion budget. When either runs out the call is blocked (`FREE_CALL_QUOTA`, `PROMOTION_EXHAUSTED`) — it never becomes a paid call by itself. When a promotion ends, invoking with the old `pricing_version` returns `PRICING_CHANGED`; describe again and decide with the new price.

Free tools work with an empty wallet.

## Top-ups

* Add funds in [Settings → Wallet](https://www.agentrouter.to/settings/wallet), with `agentrouter topup --amount-usd 10`, or `POST /v1/wallet/topups`.
* A 5% service fee is added: $10 → $10.50 total. `POST /v1/wallet/topups/quote` returns the exact fee for any amount. Multipliers and promotions never apply to top-ups.
* Creating a top-up returns a payment link. **Funds arrive only after payment completes**; creating the link does not add money. An agent should give the link to the user and never pay it itself.
* AgentRouter never tops up automatically.

## Spending authority

Connecting a host (OAuth) or creating an API key lets that caller spend from your wallet within its permissions and your budgets. Each run records which key or host made it. Revoke a key or host at any time in [Settings → API](https://www.agentrouter.to/settings/api).