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). The examples below keep a key in TONBO_API_KEY.
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 eventsCreate 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:
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 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). An account whose credit is exhausted answers 402 (see When the balance runs out).
content_type, or--content-type, is what every append sends:application/octet-streamwhen omitted,application/jsonfor JSON messages, or any lowercasetype/subtypewithout parameters (see 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-ator--expires-in(90sor more, such as30m,24hor7d), 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:
| Region | Location | Streams origin | Default |
|---|---|---|---|
us-east-1 | US East (N. Virginia) | https://streams.tonbo.dev | Yes |
ap-southeast-1 | Asia Pacific (Singapore) | https://streams.ap-southeast-1.tonbo.dev |
So events, created in us-east-1, is at:
https://streams.tonbo.dev/<account-id>/s.eventsThe 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), 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 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:
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). 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.