---
title: "Usage & spend – Superbot API"
canonical_url: "https://superbot.gg/developers/usage"
last_updated: "2026-09-25"
summary: "What your keys and account spent: per request, per day, bucketed and across apps."
---

> Markdown twin of https://superbot.gg/developers/usage (the HTML page is canonical).
> The site index for agents is /llms.txt; every content page has a twin at its path plus `.md`.

# Usage & spend

What your keys and account spent: per request, per day, bucketed and across apps.

Base URL: `https://superbot.gg`. Errors: [https://superbot.gg/developers#errors](https://superbot.gg/developers#errors). Spec: [https://superbot.gg/docs/openapi.json](https://superbot.gg/docs/openapi.json).

## Operations

- [Get usage over a window](https://superbot.gg/developers/usage/getUsage.md): `GET /v1/usage`
- [List usage per request](https://superbot.gg/developers/usage/listUsageRequests.md): `GET /v1/usage/requests`
- [Get usage per UTC day](https://superbot.gg/developers/usage/getUsageDaily.md): `GET /v1/usage/daily`
- [Get usage bucketed and grouped](https://superbot.gg/developers/usage/getUsageBreakdown.md): `GET /v1/usage/breakdown`
- [Export usage rows](https://superbot.gg/developers/usage/exportUsage.md): `GET /v1/usage/export`
- [Get the credit balance](https://superbot.gg/developers/usage/getCredits.md): `GET /v1/credits`
- [Get AI spend across apps](https://superbot.gg/developers/usage/getSpend.md): `GET /v1/spend`
- [Get a usage report](https://superbot.gg/developers/usage/getUsageReport.md): `GET /v1/usage/report`

## Get usage over a window

`GET /v1/usage`

With a caller key (or `key=<id>` from a session): that key’s burn over `window`, OpenRouter generation shape. From a session without `key`: paid-versus-list spend over `period`.

- Operation id: `getUsage`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `window` | string | optional | Key usage window; default day. One of `day`, `week`, `month`. |
| `key` | string | optional | Key id to read (sessions only; a caller key reads itself). |
| `period` | string | optional | Account spend period (session without `key`); default week. One of `week`, `month`, `all`. |

### Response 200

The key aggregate, or the account period projection.

`application/json`: UsageAggregate | UsagePeriod.

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## List usage per request

`GET /v1/usage/requests`

One generation per request, newest first.

- Operation id: `listUsageRequests`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | optional | Key id to read (sessions only). |
| `limit` | integer | optional | Rows to return, 1-100; default 20. |

### Response 200

The generations.

`application/json`: UsageGenerationList.

- `object` (string, required): One of `list`.
- `data` (array of UsageGeneration, required)
  - `request_id` (string)
  - `native_tokens_prompt` (number, required)
  - `native_tokens_completion` (number, required)
  - `cache_read` (number, required)
  - `cache_write` (number, required)
  - `total_cost` (number, required): USD at vendor list price.
  - `cache_discount` (number, required)
  - `is_byok` (boolean, required)
  - `model` (string)
  - `key_label` (string)
  - `session_id` (string)
  - `latency_ms` (number)
  - `ttft_ms` (number)
  - `status` (integer, required)
  - `ts` (string, required)

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage/requests" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage/requests`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage/requests",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Get usage per UTC day

`GET /v1/usage/daily`

The account’s usage per UTC day across every key, with totals.

- Operation id: `getUsageDaily`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string (date) | optional | YYYY-MM-DD; default 30 days before `to`. |
| `to` | string (date) | optional | YYYY-MM-DD; default today (UTC). |

### Response 200

One row per day.

`application/json`: UsageDaily.

- `from` (string, required)
- `to` (string, required)
- `days` (array of UsageDay, required)
  - `day` (string, required)
  - `tokens` (number, required)
  - `tokens_in` (number, required)
  - `tokens_out` (number, required)
  - `cache_read` (number, required)
  - `cache_write` (number, required)
  - `turns` (integer, required)
  - `cost_usd` (number, required)
  - `charged_usd` (number, required)
- `totals` (object, required)
  - `tokens` (number, required)
  - `tokens_in` (number, required)
  - `tokens_out` (number, required)
  - `turns` (integer, required)
  - `cost_usd` (number, required)
  - `charged_usd` (number, required)

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage/daily" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage/daily`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage/daily",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Get usage bucketed and grouped

`GET /v1/usage/breakdown`

Usage bucketed by hour or day, grouped by key, lane, role, session or model, narrowed by any filter.

- Operation id: `getUsageBreakdown`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string (date) | optional | YYYY-MM-DD; default 30 days before `to`. |
| `to` | string (date) | optional | YYYY-MM-DD; default today (UTC). |
| `tz` | string | optional | IANA zone the days and buckets are read in; default UTC. |
| `bucket` | string | optional | Bucket width; default day. One of `day`, `hour`. |
| `group` | string | optional | Split dimension; default none. One of `none`, `key`, `lane`, `role`, `session`, `model`. |
| `key` | string | optional | Only rows from this key id. |
| `lane` | string | optional | Only rows on this lane. |
| `role` | string | optional | Only rows with this agent role. |
| `session` | string | optional | Only rows in this session. |

### Response 200

Buckets, groups and totals.

`application/json`: UsageBreakdown.

- `from` (string, required)
- `to` (string, required)
- `tz` (string, required)
- `bucket` (string, required): One of `day`, `hour`.
- `group` (string, required)
- `totals` (UsageMetrics, required)
  - `requests` (integer, required)
  - `tokens_in` (number, required)
  - `tokens_out` (number, required)
  - `cache_read` (number, required)
  - `cache_write` (number, required)
  - `tokens` (number, required): Billed credits.
  - `usd` (number, required)
  - `list_usd` (number, required)
- `groups` (array of UsageMetrics & object, required)
  - `requests` (integer, required)
  - `tokens_in` (number, required)
  - `tokens_out` (number, required)
  - `cache_read` (number, required)
  - `cache_write` (number, required)
  - `tokens` (number, required): Billed credits.
  - `usd` (number, required)
  - `list_usd` (number, required)
  - `id` (string, required)
  - `label` (string, required)
- `buckets` (array of UsageMetrics & object, required)
  - `requests` (integer, required)
  - `tokens_in` (number, required)
  - `tokens_out` (number, required)
  - `cache_read` (number, required)
  - `cache_write` (number, required)
  - `tokens` (number, required): Billed credits.
  - `usd` (number, required)
  - `list_usd` (number, required)
  - `key` (string, required)
  - `start` (string, required)
  - `by` (object, required)

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage/breakdown" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage/breakdown`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage/breakdown",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Export usage rows

`GET /v1/usage/export`

The usage rows as a CSV (default), JSON or newline-delimited JSON attachment.

- Operation id: `exportUsage`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string (date) | optional | YYYY-MM-DD; default 30 days before `to`. |
| `to` | string (date) | optional | YYYY-MM-DD; default today (UTC). |
| `format` | string | optional | Attachment format; default csv. One of `csv`, `json`, `ndjson`. |
| `tz` | string | optional | IANA zone the days and buckets are read in; default UTC. |
| `key` | string | optional | Only rows from this key id. |
| `lane` | string | optional | Only rows on this lane. |
| `role` | string | optional | Only rows with this agent role. |
| `session` | string | optional | Only rows in this session. |

### Response 200

The rows, as an attachment.

`text/csv`: string.

`application/json`: array of object.

`application/x-ndjson`: string.

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage/export" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage/export`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage/export",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Get the credit balance

`GET /v1/credits`

The wallet balance, the period meter and the plan.

- Operation id: `getCredits`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `billing:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `billing:read`

### Response 200

The balance.

`application/json`: Credits.

- `credits` (object, required): The pot view: beta, plan and permanent credits with a total.
- `balance_credits` (number, required)
- `balance_tokens` (number, required)
- `total_usage_tokens` (number, required)
- `period_usage_tokens` (number, required)
- `capacity_tokens` (number, required)
- `keys_count` (integer, required)
- `paid_usd_week` (number, required)
- `list_usd_week` (number, required)
- `saved_usd_week` (number, required)
- `plan` (string, required)
- `renews_at` (string)

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/credits" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/credits`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/credits",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Get AI spend across apps

`GET /v1/spend`

AI spend across every app on the account over a window, by provider and day.

- Operation id: `getSpend`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `range` | string | optional | Window; default 30d. One of `30d`, `90d`, `month`, `custom`. |
| `from` | string (date) | optional | YYYY-MM-DD, with range=custom. |
| `to` | string (date) | optional | YYYY-MM-DD, with range=custom. |

### Response 200

The spend report.

`application/json`: Spend.

- `from` (string, required)
- `to` (string, required)
- `currency` (string, required): One of `USD`.
- `total_usd` (number, required)
- `tied_usd` (number, required)
- `estimated_usd` (number, required)
- `unpriced_models` (array of string, required)
- `providers` (array of object, required)
  - `provider` (string, required)
  - `label` (string, required)
  - `total_usd` (number, required)
  - `usage_usd` (number, required)
  - `purchase_usd` (number, required)
  - `measured_usd` (number, required)
  - `estimated_usd` (number, required)
  - `plan_usd` (number, required)
  - `residual_usd` (number | null, required)
  - `status` (string, required): One of `caught_up`, `residual`, `estimate_only`.
  - `services` (array of object, required)
    - `service` (string, required)
    - `total_usd` (number, required)
  - `sources` (array of object, required)
    - `source` (string, required)
    - `fresh_at` (string | null, required)
    - `status` (string, required): One of `ok`, `stale`, `missing`.
- `series` (array of object, required)
  - `day` (string, required)
  - `providers` (object, required)

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/spend" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/spend`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/spend",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```

## Get a usage report

`GET /v1/usage/report`

The account’s usage across every key in hourly or daily UTC buckets, grouped by any mix of key, model, lane, role, session and team, and narrowed by any filter.

- Operation id: `getUsageReport`
- Group: [Usage & spend](https://superbot.gg/developers/usage.md)
- Auth: A caller key holding `usage:read` (`Authorization: Bearer sbc_…` or `x-api-key: sbc_…`), or a signed-in session.
- Scopes: `usage:read`

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `starting_at` | string (date-time) | optional | RFC 3339 start, floored to the bucket width. Default: 7 days before `ending_at`. |
| `ending_at` | string (date-time) | optional | RFC 3339 end (exclusive), ceiled to the bucket width. Default: the end of the current bucket. At most 92 days after `starting_at`. |
| `bucket_width` | string | optional | Bucket width; default 1d. One of `1h`, `1d`. |
| `group_by` | string \| array of string | optional | Split each bucket by these dimensions: api_key_id, model, lane, role, session_id, team_id. Repeat the parameter or pass a comma list. |
| `api_key_ids` | string \| array of string | optional | Only usage from these caller key ids. Repeat the parameter or pass a comma list. |
| `models` | string \| array of string | optional | Only usage on these model ids. Repeat the parameter or pass a comma list. |
| `lanes` | string \| array of string | optional | Only usage on these lanes: credits, caller_key, byo. Repeat the parameter or pass a comma list. |
| `roles` | string \| array of string | optional | Only usage with these agent roles (chat for a plain turn). Repeat the parameter or pass a comma list. |
| `session_ids` | string \| array of string | optional | Only usage inside these agent runs. Repeat the parameter or pass a comma list. |
| `team_ids` | string \| array of string | optional | Only usage from keys scoped to these teams. Repeat the parameter or pass a comma list. |
| `limit` | integer | optional | Buckets per page. 1h: default 24, max 168. 1d: default 7, max 31. |
| `page` | string | optional | The previous response’s `next_page`. Repeat group_by and the filters with it. |

### Response 200

One page of buckets.

`application/json`: UsageReport.

- `object` (string, required): One of `list`.
- `data` (array of UsageBucket, required)
  - `object` (string, required): One of `bucket`.
  - `starting_at` (string (date-time), required)
  - `ending_at` (string (date-time), required)
  - `results` (array of UsageResult, required)
    - `requests` (integer, required)
    - `tokens_in` (number, required)
    - `tokens_out` (number, required)
    - `cache_read` (number, required)
    - `cache_write` (number, required)
    - `tokens` (number, required): Billed credits.
    - `usd` (number, required)
    - `list_usd` (number, required)
    - `api_key_id` (string | null)
    - `model` (string | null)
    - `lane` (string | null)
    - `role` (string | null)
    - `session_id` (string | null)
    - `team_id` (string | null)
- `has_more` (boolean, required)
- `next_page` (string | null, required): Pass as `page` for the next buckets; null on the last page.

### Errors

Every refusal carries `error`, `message`, `doc_url` and `request_id`; the gateway routes answer in the dialect you dialed.

| Status | Codes | When |
| --- | --- | --- |
| 400 | [`invalid_request`](https://superbot.gg/developers#errors-invalid_request) | The request is malformed or a parameter is invalid; `param` names the field. |
| 401 | [`unauthorized`](https://superbot.gg/developers#errors-unauthorized) | The bearer is missing, malformed or unknown. |
| 403 | [`insufficient_scope`](https://superbot.gg/developers#errors-insufficient_scope) | The key lacks a scope (insufficient_scope), is revoked, or may not call this route. |

### Examples

```sh
curl -sS -X GET "https://superbot.gg/v1/usage/report" \
  -H "Authorization: Bearer $SUPERBOT_API_KEY"
```

```js
const res = await fetch(`https://superbot.gg/v1/usage/report`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

```python
import os
import requests

res = requests.request(
    "GET",
    "https://superbot.gg/v1/usage/report",
    headers={
        "Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
    },
)
print(res.status_code, res.json())
```
