# Usage and limits

Every answer says what the request used and what it cost, and a few limits decide when a request is refused. This page lists both, and where to read them again afterwards.

## Usage in each answer

Each API reports usage under its own field names and adds `cost`: the request's price in US dollars at your organization's rate.

| API | `usage` holds | Where |
|---|---|---|
| Chat Completions | `prompt_tokens`, `completion_tokens`, `total_tokens`, the cache and reasoning counts in `prompt_tokens_details` and `completion_tokens_details`, and `cost` | The body. On a stream, the last chunk. |
| Responses | `input_tokens`, `output_tokens`, `total_tokens`, the counts in `input_tokens_details` and `output_tokens_details`, and `cost` | The response object. On a stream, the final response in the last event. |
| Messages | `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` and `cost` | The message. On a stream, `message_delta`: `message_start` carries an early count and no `cost`. |
| Embeddings | `prompt_tokens`, `total_tokens` and `cost` | The body. |
| Images | On `POST /images`: `prompt_tokens`, `completion_tokens`, `total_tokens` and `cost`. On `POST /images/generations`: `input_tokens`, `output_tokens`, `total_tokens`, `input_tokens_details` and `cost`. | The body. |
| Speech to text | `seconds` and `cost` | The body. |
| Text to speech | None: the answer is audio. | [The generation record](#the-cost-of-a-finished-request). |
| Decisions | `input_tokens`, `output_tokens` and `cost` | The body. |

The fields are described where each API is: [Chat Completions](chat-completions.md#usage-and-cost), [Responses](responses.md#usage-and-cost), [Messages](messages.md#usage-and-cost), [Embeddings](embeddings.md#create-embeddings), [Images](images.md#the-answer), [Audio](audio.md#cost-and-the-generation-record) and [Decisions](decisions.md#the-answer). [Prompt caching](prompt-caching.md#read-the-cache-in-usage) lists the cache counts.

- `cost` is a JSON number. It includes any billed tool-search rounds, so it can be more than the counts times the listed prices. A model with no price reports `0`.
- A failed attempt that another provider replaced adds 0 to `cost`. A retry with the same `Idempotency-Key` returns the first call's `cost` and is not billed again: [Retries and idempotency](retries-and-idempotency.md#idempotency-key).
- `cost` is left out when any part of it is unknown, which happens when the provider reported no counts for a turn that delivered output: [When a provider reports no usage](#when-a-provider-reports-no-usage).
- On Chat Completions and Responses, a count that is `0` only because the provider reported nothing is named in `usage.unreported_token_details`. The names it can hold are `cached_tokens`, `cache_write_tokens`, `cache_write_1h_tokens` and `reasoning_tokens`. The `usage` in the last chunk of a Chat Completions stream from such a provider looks like this:

```json
{"prompt_tokens": 12, "completion_tokens": 7, "total_tokens": 19,
 "prompt_tokens_details": {"cached_tokens": 0}, "completion_tokens_details": {"reasoning_tokens": 0},
 "unreported_token_details": ["cached_tokens", "cache_write_tokens", "reasoning_tokens"],
 "cost": 0.000026}
```

- You do not need OpenRouter's `usage: {"include": true}`. llm.buzz drops it, names it in `x-sgr-ignored-parameters`, and sends `usage` and `cost` with every answer whose provider reported counts.

## The cost of a finished request

`GET /generation?id=` answers the record and cost of any finished request of your organization. The ID is `gen-` and the 32 hex digits of the request's `x-request-id`:

```bash
curl "https://api.llm.buzz/api/v1/generation?id=gen-..." \
  -H "Authorization: Bearer $LLM_BUZZ_KEY"
```

`total_cost` is what you were charged, in US dollars at your rate. Text to speech has no JSON body for its cost, so this record is where you read it. [Cost of a finished request](api-reference.md#cost-of-a-finished-request) lists the rest of the record. An error answer carries no `x-request-id`, so look for that request on the Logs page.

## When a provider reports no usage

Occasionally a provider answers without token counts, or with counts that are all zero. What llm.buzz charges depends on what the attempt delivered:

- A turn that finished without any text or tool output is charged an estimate of its prompt: llm.buzz's own count of the input tokens, with the cached share at the cached rate, and nothing for output. A finished turn is a stop, a stop cut by your token limit, or an empty completion on a stream that opened. The estimate applies to the request's last attempt, and an attempt that another provider replaced costs 0. The answer keeps the counts the provider sent: no `usage` on Chat Completions and Responses when it sent none, zeros otherwise, and zeros on Messages. Where the answer has a `usage`, its `cost` is the estimate. The generation record shows the estimate as `total_cost`.
- A turn that delivered text, reasoning text or a tool call, or ran a tool search, is charged what llm.buzz reserved when the attempt started: the most the attempt could cost, which is the prompt plus the output limit at the provider's prices and your organization's rate. The answer carries no `cost`: no `usage` on Chat Completions and Responses when the provider sent no counts, and zero counts on Messages. The generation record shows the amount as `total_cost`.

A lower `max_tokens` lowers the reserved amount. Without one, the output limit is the model's own ceiling, so a model with a large ceiling reserves more. On Chat Completions, Responses and Messages, a request whose last provider failed before its stream opened costs nothing when that provider answered an error status (a 5xx, its own 400 or a 429) or never received the request: you received nothing. The reserved amount is charged when the last provider timed out, when it failed after the request was sent, when a stream opened and then broke off without usage, and when you close a stream before the provider accepted the request ([Stopping a stream](streaming.md#stopping-a-stream)), because the provider may have generated output you never saw: [Retries and idempotency](retries-and-idempotency.md#inside-one-request). Embeddings, Images and Audio bill a failed last attempt by their own rules, often nothing: [Embeddings](embeddings.md#billing), [Images](images.md#billing) and [Audio](audio.md#billing).

## In the console

The console shows the same figures over time:

- [Activity](https://app.llm.buzz/console/activity) shows spend, requests, tokens, latency and error rate over 1 to 90 days, a per-day chart by model, and breakdowns by model, provider and calling app.
- [Logs](https://app.llm.buzz/console/logs) lists every request, filtered by state and model. A request opens to its route timeline: the attempts it made, in order.
- [Keys](https://app.llm.buzz/console/keys) lists each key with its limit against its spend, its spend today, this week and this month, its last use and its status.
- [Credits](https://app.llm.buzz/console/credits) shows your balance, the amount your running requests hold, and your credit history.

These pages show your own requests and keys. An organization's admins can switch Activity, Logs and Keys to the whole organization's.

llm.buzz does not serve OpenRouter's `/activity` or analytics routes: they answer 404 `unknown_route`. Read totals on Activity, and one request with `GET /generation`.

## Limits

| Limit | What you get | What to do |
|---|---|---|
| Your balance is spent | 402 `insufficient_credits`. A free model still answers. | Add credit on the Credits page, or turn on auto top-up: [Pricing](pricing.md#prepaid-credit). |
| A request could cost more than your balance | 402 `weight_exceeds_budget` | Add credit, or lower `max_tokens`. |
| Running requests hold what your balance leaves | 402 `in_flight_budget_exhausted`, with `Retry-After: 5` | Retry after the wait, or add credit. |
| Your organization's monthly budget is spent | 402 `insufficient_quota`, with `Retry-After`; the message names when the month resets | Wait for the reset, or ask an owner or admin of your organization to raise the budget on the console's Keys page. |
| A key's spending limit is reached | 403 `key_limit_exceeded`, with `metadata.resets_at` | Wait for `resets_at`, or raise the key's limit: [Authentication](authentication.md#spending-limits). |
| A free offer's allowance is used, and the model has no other provider | 429 `free_allowance_exceeded`. The per-minute limit carries `Retry-After: 60`. | Choose a paid model, or retry after a minute: [Pricing](pricing.md#free-offers). |
| Providers are throttling, or the model is at capacity | 429 `unavailable_route`, with `Retry-After` | Wait that long, then retry: [Retries and idempotency](retries-and-idempotency.md#your-retries). |
| The prompt fits no provider's context window | 400 `context_length_exceeded` | Shorten the prompt. A model's `context_length` is on its entry in the model list. |
| A request runs for 600 seconds | 504 `deadline_exceeded`. A stream ends with a timeout error and is billed for the prompt and the output you received. | Ask for a shorter answer, for example with a lower `max_tokens`. |
| The request body is over 64 MiB, or an audio file is over 25 MiB | 413 `request_too_large` | Send less. |

Chat Completions serves one completion per request, so `n` is 1. A request makes at most 8 provider calls, every fallback included; `gateway.retry` lowers that ceiling: [Retries and idempotency](retries-and-idempotency.md#the-gateway-object). 402 `weight_exceeds_budget` and `in_flight_budget_exhausted` apply when your balance is low, because llm.buzz then holds the most each running request could cost against it. [Errors](errors.md) lists every code, and each API's page lists the limits of its own.

## Check your key and credit

`GET /key` describes the key you send, with an inference key or a management key:

```bash
curl https://api.llm.buzz/api/v1/key \
  -H "Authorization: Bearer $LLM_BUZZ_KEY"
```

- `limit`, `limit_remaining` and `limit_reset` give the key's spending limit, what is left of it and its period (`daily`, `weekly`, `monthly`, or `null` for the key's whole life). `budgets` lists the limit with its `spend_usd`, `remaining_usd` and `resets_at`, the start of the next period, and is empty for a key without a limit.
- `usage`, `usage_daily`, `usage_weekly` and `usage_monthly` are the key's spend in US dollars over its life and in the current UTC day, week and month.
- `is_free_tier` is `true` until your organization has bought credit.
- `free_model_daily_requests` reads 0 for `limit`, `remaining` and `used`. `rate_limit` is deprecated and safe to ignore.

`GET /credits` answers your organization's credit and usage in US dollars. It takes a management key; an inference key gets 403 `management_key_required`:

```bash
curl https://api.llm.buzz/api/v1/credits \
  -H "Authorization: Bearer $LLM_BUZZ_MANAGEMENT_KEY"
```

```json
{"data": {"total_credits": 25.0, "total_usage": 3.25}}
```

An organization without credit gets zeros. [Authentication](authentication.md#create-a-key) explains the two kinds of key.
