---
title: "Usage accounting"
subtitle: "Get the tokens of every call in the response, and look up its cost later by log ID."
---

Every gateway call returns the usage the provider reported, and every call writes a log with its usage and cost. You don't need extra parameters to get usage, and you can fetch the full accounting for any call afterwards with the ID in its `X-Respan-Log-Id` header.

<Tabs>
<Tab title="cURL">
```bash
curl -i https://gateway.respan.ai/v1/chat/completions \
  -H "Authorization: Bearer $RESPAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
```
</Tab>
<Tab title="Python">
```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://gateway.respan.ai/v1",
    api_key=os.environ["RESPAN_API_KEY"],
)

raw = client.chat.completions.with_raw_response.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Hello!"}],
)
response = raw.parse()
print(response.usage)
print(raw.headers.get("x-respan-log-id"))
```
</Tab>
<Tab title="TypeScript">
```typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://gateway.respan.ai/v1",
  apiKey: process.env.RESPAN_API_KEY,
});

const { data, response } = await client.chat.completions
  .create({
    model: "gpt-5.5",
    messages: [{ role: "user", content: "Hello!" }],
  })
  .withResponse();
console.log(data.usage);
console.log(response.headers.get("x-respan-log-id"));
```
</Tab>
</Tabs>

| Where | What you get | When |
|---|---|---|
| [`usage` in the response](#usage-in-the-response) | Tokens as the provider reported them | With every response |
| [Final stream chunk](#streaming) | The same `usage`, after the last content chunk | When you set `stream_options.include_usage` |
| [Look up by log ID](#look-up-a-call) | Tokens, cost, latency, and the full log | Any time within your retention period |
| [Logs](#in-logs) | The same, in the platform | Any time within your retention period |

## Usage in the response

The response keeps the provider's usage in the format you called. On Chat Completions:

```json
{
  "id": "chatcmpl-...",
  "model": "gpt-5.5",
  "choices": [ ... ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 9,
    "total_tokens": 21,
    "prompt_tokens_details": {"cached_tokens": 0},
    "completion_tokens_details": {"reasoning_tokens": 0}
  }
}
```

Anthropic Messages returns `usage` with `input_tokens`, `output_tokens`, `cache_read_input_tokens`, and `cache_creation_input_tokens`. Gemini returns `usageMetadata`. Cached and reasoning tokens appear where the provider reports them.

## Streaming

Set `stream_options.include_usage: true` and the last chunk before `[DONE]` carries `usage`, with an empty `choices` array.

```bash
curl https://gateway.respan.ai/v1/chat/completions \
  -H "Authorization: Bearer $RESPAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'
```

The gateway asks the provider for usage on every stream, even when you don't set `include_usage`, so the log is always priced from real usage. It only adds the usage chunk to your stream when you ask for it. See [Streaming](/docs/ai-gateway/requests/chat-completions#streaming).

## Look up a call

Every response, streamed or not, and every refused request that wrote a log, carries two headers:

| Header | What it names |
|---|---|
| `X-Respan-Log-Id` | The call's log (for a request that ran tools, its first log, the root of the trace) |
| `X-Respan-Gateway-Request-Id` | The whole request. Every log the request writes carries it. |

Fetch the log with [Get a span](/docs/apis/spans/get-span) on `https://api.respan.ai`:

```bash
curl https://api.respan.ai/api/request-logs/$LOG_ID/ \
  -H "Authorization: Bearer $RESPAN_API_KEY"
```

The fields to read:

| Field | Description |
|---|---|
| `prompt_tokens`, `completion_tokens`, `total_request_tokens` | Input, output, and total tokens |
| `prompt_cache_hit_tokens`, `prompt_cache_creation_tokens` | Cached input tokens read and written |
| `reasoning_tokens` | Reasoning tokens |
| `cost` | Cost in USD |
| `latency`, `time_to_first_token` | Seconds end to end, and to the first token on a stream |
| `model`, `provider_id` | The model and provider that answered |
| `status_code`, `error_code` | How the call ended |

A log is published when its call ends, so look it up after the response completes. To get every call of a request that ran tools, use [Get a trace](/docs/apis/traces/get-trace) with the trace ID (your `trace_unique_id`, or the `X-Respan-Gateway-Request-Id`).

## Units by modality

Each log is typed by what it is, and measured in that modality's unit:

| Log type | Measured in |
|---|---|
| `chat` | Input and output tokens, including cached, reasoning, and audio tokens |
| `embedding` | Input tokens |
| `image` | Image output tokens, and input images on an edit |
| `speech` | Minutes of audio made |
| `transcription` | Minutes of audio sent |
| `video` | Seconds of video served |
| `tool` | No tokens, $0 |

A realtime session is logged once, when it ends, as one streamed `chat` log priced on its text and audio tokens.

## How cost is computed

A log's `cost` is the provider's usage times the model's prices in the catalog, including cache reads and writes, fast mode, and region where the provider prices them. For providers that report their own charge (OpenRouter, xAI, Perplexity), the log uses that charge. The same cost is computed whether the call ran on Respan credits or on [your own key](/docs/ai-gateway/spend/credits-vs-byok#byok), so your reports cover both. A refused request is $0.

See [Pricing and credits](/docs/ai-gateway/spend/credits-vs-byok) for how a cost is charged to your balance.

## In Logs

Open **Gateway** › **Logs** and paste the `X-Respan-Log-Id` value into the search. The side panel shows tokens, cost, and latency, and the **Config** tab shows the **Billing method**. See [Logs](/docs/ai-gateway/observability/logs-and-traces).

## Next steps

- [Reports](/docs/ai-gateway/observability/reports): totals by model, customer, or key over time.
- [Budgets and limits](/docs/ai-gateway/spend/budgets-and-limits): stop spend at a cap.
- [Pricing and credits](/docs/ai-gateway/spend/credits-vs-byok): who pays for a call.
