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

# Manage streams

Last updated 29 October 2026

Create, list, publish, expire and delete streams whenever a program needs a new one or is done with it: on **Streams** in the console, with the Tonbo CLI, or through the Management API at `https://api.tonbo.dev/v1/streams`. All three act on the same streams.

| Task | Console | CLI | API |
| --- | --- | --- | --- |
| Create | **Create stream** | `tonbo stream create` | `POST /v1/streams` |
| List | **Streams** | `tonbo stream list` | `GET /v1/streams` |
| Show | A stream’s name in the list | `tonbo stream show` | `GET /v1/streams/{name}` |
| Public or private | **Make public**, **Make private** | `tonbo stream update` | `PATCH /v1/streams/{name}` |
| Delete | **Delete stream** | `tonbo stream delete` | `DELETE /v1/streams/{name}` |
| Usage this month | **Streams** | `tonbo stream usage` | `GET /v1/usage/streams` |

The CLI is `@tonbo/cli`: install it with `npm i -g @tonbo/cli` and sign in with `tonbo login`. The API takes a personal API key, or a token exchanged from a key, as a bearer token (see [API keys and tokens](https://tonbo.dev/docs/platform/api-keys.md)). The examples below keep a key in `TONBO_API_KEY`.

**CLI**

```shell
tonbo stream create events --content-type application/json
tonbo stream create run-42 --content-type application/json --expires-in 24h
tonbo stream list
tonbo stream show events
tonbo stream update events --public
tonbo stream delete events
```

## Create a stream

Any member creates streams; a narrowed key never does. In the console, open **Streams**, choose **Create stream**, and give it a name, a region, a content type and, if it should delete itself, an expiry. None of them can be changed later. Through the API, with a key that acts as you and is not narrowed:

```shell
curl -sS -X POST "https://api.tonbo.dev/v1/streams" \
  -H "Authorization: Bearer $TONBO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"events","content_type":"application/json"}'
```

It answers `201` with the stream, its `url` included, once it is active, or `202` while it is still being created: read it again until it is active. A retry with the same [`Idempotency-Key`](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/) answers the same stream instead of creating a second one; the CLI sends one too and prints it when a creation is not confirmed. An account holds at most 10000 streams, counted apart from its databases, and past that the answer is `403` (see [Limits](https://tonbo.dev/docs/streams/limits.md)). An account whose credit is exhausted answers `402` (see [When the balance runs out](https://tonbo.dev/docs/databases/pricing.md#zero-balance)).

- `content_type`, or `--content-type`, is what every append sends: `application/octet-stream` when omitted, `application/json` for JSON messages, or any lowercase `type/subtype` without parameters (see [Content types](https://tonbo.dev/docs/streams/append.md#content-types)).
- `region`, or `--region`, is where the stream lives, such as `"region":"ap-southeast-1"`; without one it goes to the default region, `us-east-1`.
- `expires_at`, an RFC 3339 time at least 60 seconds after the creation, or `--expires-at` or `--expires-in` (`90s` or more, such as `30m`, `24h` or `7d`), has Tonbo delete the stream within a minute after it passes, as a deletion would. Without one the stream never expires.

## Regions and URLs

A stream lives in one region, and its URL is on that region’s Streams origin, followed by your account’s id and `s.` with the stream’s name. [Regions](https://tonbo.dev/docs/platform/regions.md) lists the regions and each one’s Streams origin.

So `events`, created in `us-east-1`, is at:

```text
https://streams.tonbo.dev/<account-id>/s.events
```

The console, the CLI and the API all show each stream’s URL; use it as they print it.

## Names

1 to 83 lowercase letters, digits, dots, underscores and hyphens, starting and ending with a letter or digit, without `..`, not starting with `m.`, `vol.`, `s.`, `session.` or `proc.` and not `streams` or `new`. A name is unique among the account’s streams, in every region, while a stream holds it, and is free again once that stream is deleted. A stream and a database may share a name. It cannot be changed, and it appears in the URL as it is.

## States

- `creating`: the stream is being created. It takes no appends or reads yet.
- `active`: the stream takes appends and reads at its URL. Its URL never creates a stream, so create each one first.
- `deleting`: the stream is being deleted.

## List and show

The list shows each stream’s name, region, content type, expiry, creation date, last write, size and visibility. A stream’s page, `tonbo stream show` and `GET /v1/streams/events` add its URL, state and incarnation, which changes when the stream is deleted and created again (see [A stream deleted and created again](https://tonbo.dev/docs/streams/read.md#incarnation)), and its size as log and snapshot. `tonbo stream list --prefix` and `?prefix=` list only the names that start with a prefix. The API returns up to 50 streams a page, or `limit`, at most 200, with a `next_cursor` for the next page. A key narrowed to streams lists only the streams it reaches.

## Public and private

A new stream is private. Owners and admins can publish an active one, so anyone with its URL reads and tails it without a key or token; appends still need one. Choose **Make public** or **Make private** on the stream’s page, run `tonbo stream update events --public` or `--private`, or send `{"public_read":true}` with `PATCH /v1/streams/events`. [Public streams](https://tonbo.dev/docs/streams/access.md#public) says what anonymous readers reach.

## Delete a stream

Any member deletes streams. Everything appended to it is purged from Tonbo, and every later read or append at its URL answers `404`. Deletion cannot be undone. The console asks you to type the stream’s name, and so does `tonbo stream delete` in a terminal; without one it refuses unless `--yes` is given. Through the API:

```shell
curl -sS -X DELETE "https://api.tonbo.dev/v1/streams/events" \
  -H "Authorization: Bearer $TONBO_API_KEY"
```

It answers `200` once the stream is deleted and `202` while it is being deleted, and repeating it answers the stream being deleted. The name is free again once the deletion completes, and the stream’s usage this month stays in `tonbo stream usage`.

## What a stream’s URL does not do

The stream’s URL never creates or deletes a stream: a `PUT` or a `DELETE` there answers `403` with the code `STREAM_LIFECYCLE` (see [Troubleshooting](https://tonbo.dev/docs/streams/troubleshooting/stream.md#lifecycle)). Create and delete streams in the console, with the CLI or through the Management API, as above, and give a stream a lifetime with its expiry at creation rather than `Stream-TTL`.
