> Fetch the index of every Tonbo docs page as Markdown at https://tonbo.dev/llms.txt

# Reference

Last updated 2 November 2026

Every interface Tonbo serves, one module at a time: the HTTP APIs, the SDKs that call them and the CLIs. This page says where each module answers, which credential it takes and the conventions they share. Each module’s own pages list its operations, every parameter and every error.

## Modules

| Module | Where it answers | Credential | What it does |
| --- | --- | --- | --- |
| [Management API](https://tonbo.dev/docs/reference/management.md) | `https://api.tonbo.dev/v1` | A personal key, or a token for `https://api.tonbo.dev` | Creates, lists, changes and deletes the account’s databases, streams and keys, and reads the account and its usage. |
| [Token exchange](https://tonbo.dev/docs/reference/token-exchange.md) | `POST https://tonbo.dev/api/iam/token` | Any key, or a Streams token to narrow | Exchanges a key for a token that expires within 10 minutes, and [narrows a token](https://tonbo.dev/docs/platform/api-keys.md#down-scope) for one client such as a web page. |
| [Streams HTTP](https://tonbo.dev/docs/reference/streams.md) | A stream’s or a database’s `url`, on its region’s Streams origin | A personal key, or a token for `https://streams.tonbo.dev` | Appends to a stream and reads it: catch-up reads, long-polls, Server-Sent Events and snapshots. |
| [Node.js SDK](https://tonbo.dev/docs/reference/nodejs.md) | `@tonbo/sdk` 1.0.0 with `@tonbo/sqlite-ursula` 0.11.4, in your process | The `apiKey` option, else `TONBO_API_KEY`, else the login `tonbo login` saved | Opens a database by name as a `node:sqlite` connection, and Pi Durable’s storage on one. |
| [Python SDK](https://pypi.org/project/sqlite-ursula/0.11.3.dev0/) | `sqlite-ursula` 0.11.3.dev0, in your process | The `api_key` option, else `TONBO_API_KEY`, else the login `tonbo login` saved | Opens a database by name as a `sqlite3` connection, with asyncio and LangGraph. |
| [`tonbo` CLI](https://tonbo.dev/docs/reference/cli.md) | Your terminal; it calls the Management API | `tonbo login`, or a key in `TONBO_API_KEY`, which overrides it | One command for each operation of the Management API, with --json for scripts. |
| [`yield` CLI](https://yield.tonbo.io/docs/reference) | Your terminal | `yield login` | Captures your coding agents’ sessions and answers why a file is the way it is. |

## Origins

Two origins are fixed: the Management API’s, `https://api.tonbo.dev/v1`, and the token exchange’s, `https://tonbo.dev`. A stream or a database lives on its region’s Streams origin, and the Management API returns its full URL as `url`; take the URL from there rather than building it (see [Regions and URLs](https://tonbo.dev/docs/streams/manage.md#regions)).

The SDKs read `TONBO_API_ORIGIN` for another Management API origin and `TONBO_AUTH_ORIGIN` for another token exchange origin. Each must be `https`, or `http` only to `localhost`, since requests to it carry the key.

## Credentials

| Credential | What it is | Accepted by |
| --- | --- | --- |
| A personal key, `tbo_…` | Acts as you, with your current role in the account and the key’s narrowing, read again on every request. | The Management API, a stream’s URL and the token exchange, directly. |
| An Agent’s key | Acts as an Agent of the account. | The token exchange only. Sent anywhere else, it answers `401` `exchange_required`, whose `token_endpoint` names the exchange. |
| An access token | A token exchanged from a key, for one audience: `https://api.tonbo.dev` or `https://streams.tonbo.dev`. It reaches what its key reaches and expires within 10 minutes. | The API its audience names. |
| A token for a web page | A Streams token narrowed to the streams and databases it names, read-only unless it asks otherwise, and shorter-lived. | The URLs of the streams and databases it names. |

Every credential is sent as `Authorization: Bearer`. [API keys and tokens](https://tonbo.dev/docs/platform/api-keys.md) explains how to create a key, narrow it and exchange it.

## Errors

- The Management API refuses with `application/problem+json`: a Problem with `type`, `title`, `status`, `code` and `request_id`, and a `detail` when one exists. Match the status and the `code`, never the title or the detail, and quote the `request_id` when you ask for help (see [Errors](https://tonbo.dev/docs/reference/management.md#errors)).
- The token exchange refuses with JSON `{"error": …}` and, for some refusals, a `code` beside it. Match the status and the code, never the message.
- A stream’s URL answers as the durable streams protocol does: a status, sometimes with a code such as `PAYMENT_REQUIRED`, and its headers. [Troubleshooting](https://tonbo.dev/docs/streams/troubleshooting.md) lists each refusal, when it happens and whether to send the request again.
- The SDKs throw errors with a `kind` to match (see [Node.js errors](https://tonbo.dev/docs/reference/nodejs/errors.md)). The `tonbo` CLI prints the refusal and exits with status 1.

## Retries and idempotency

The Management API’s creations below require an `Idempotency-Key` header of 1 to 255 characters. Send the same key again and the API answers what the first request created; send it with a different request and it answers `409`. Make one key for each creation you intend, and reuse it on every retry of that creation:

- [`POST /agents`](https://tonbo.dev/docs/reference/management/account.md#create-agent) Create an Agent, an identity with a role in the account
- [`POST /databases`](https://tonbo.dev/docs/reference/management/databases.md#create-database) Create a database
- [`POST /streams`](https://tonbo.dev/docs/reference/management/streams.md#create-stream) Create a stream

Creating an API key takes no such header: its secret is shown only once, so a retry of the same name answers `409` rather than creating a second key. When a `429` or a `503` carries `Retry-After`, wait that many seconds and send the same request again. An append to a stream is made safe to retry by its producer headers, which make a retried append land once (see [Rules: writers](https://tonbo.dev/docs/streams/rules/writers.md#producer-headers)).

## Conditional updates

A read of a resource answers its version as `ETag`. An update may send it back in `If-Match`, of at most 500 characters, to change only that version: a stale one answers `412` `precondition_failed`, and without the header the last write wins. An operation that needs the header says so, and answers `428` `precondition_required` without it.

## Pagination

A list answers `data` and `next_cursor`. It takes `limit`, from 1 to 200 items, by default 50, and `cursor`, the `next_cursor` of the page before. A cursor is opaque and tied to the query it came from, so send it with the same other parameters. `next_cursor` is `null` on the last page. The CLI prints one page and names on stderr the `--cursor` to run it again with.

## Rate limits

- The Management API answers `429` with `Retry-After` past its rate limit.
- The token exchange counts 600 tokens a minute for each key and 3000 requests a minute from each address, and answers `429` `rate_limited` past either (see [the exchange’s limits](https://tonbo.dev/docs/platform/api-keys.md#limits)).
- Streams and databases take at least 50 requests a second and 16 open tails for each account in each region (see [Limits](https://tonbo.dev/docs/streams/limits.md#requests)).

## Versions and compatibility

The Management API’s version is in its path, `/v1`.

Responses may gain fields; clients ignore fields they do not know. Request bodies stay closed: an unknown field is refused. A breaking change to an enforced operation ships as a new version, or with a compatibility window that names its consumer and removal condition.

A stream’s URL serves the [durable streams protocol](https://ursula.tonbo.io/docs/specs/durable-stream) of Ursula 0.11.3. Pin each SDK at the exact release its reference names: a later release can change its options, its cache format and the server releases it works with.
