Management API: Streams

Last updated 2 November 2026

View .md

The account's raw durable streams, each at its url; Control creates and deletes them. The overview covers what every operation shares: authentication, roles, errors, pagination, idempotency and If-Match.

List the account's streams

GET /v1/streams · CLI: tonbo stream list

Needs account.read, which owner, admin and member hold. A narrowed key may call it.

Live raw streams (contracts/streams-databases/v1.json kinds whose api is streams), creating, active or deleting, in every region, by name. A key narrowed to streams sees only the streams it reaches, and a key narrowed to buckets, or by name to databases alone, sees none. last_write_at and stored_bytes come from each region's meter; unavailable_regions names the regions whose sizes could not be read, whose streams then show null sizes (and, with include=daily_writes, those whose daily writes could not be read).

Parameters

NameInTypeRequiredDescription
prefixquerystringnoOnly streams whose name starts with this prefix. 1 to 85 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)[a-z0-9][a-z0-9._-]{0,84}$.
includequeryone of "daily_writes"nodaily_writes adds each stream's daily_write_units, its write units of the last 7 UTC days, from one more read of each region's meter.
cursorquerystringnoOpaque cursor tied to the original query shape. At least 1 characters.
limitqueryintegernoThe most items one page holds, 1 to 200; 50 when omitted. A page may hold fewer; read on with next_cursor until it is null. Default 50. 1 to 200.

Response

StatusAnswer
200Streams
FieldTypeRequiredDescription
dataarray of Streamyes
next_cursorstring or nullyesOpaque cursor of the next page; null on the last page.
unavailable_regionsarray of stringyes
HeaderStatusDescription
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429Seconds before the client should retry.
Example 200 body
{
  "data": [
    {
      "name": "<name>",
      "region": "<region>",
      "url": "https://example.com",
      "content_type": "<content_type>",
      "expires_at": "2026-11-02T09:30:00.000Z",
      "incarnation": "<incarnation>",
      "state": "creating",
      "public_read": false,
      "created_at": "2026-11-02T09:30:00.000Z",
      "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
      "last_write_at": "2026-11-02T09:30:00.000Z",
      "stored_bytes": {
        "log": 0,
        "snapshot": 0
      },
      "measured_at": "2026-11-02T09:30:00.000Z",
      "writes": "accepting",
      "daily_write_units": [
        0
      ]
    }
  ],
  "next_cursor": "<next_cursor>",
  "unavailable_regions": [
    "<unavailable_regions>"
  ]
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
422validation_errorA parameter, header or body field breaks its rule; errors names each field.NoCorrect the fields errors names; the operation’s reference gives each one’s rule. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)

Retries

  • A read: sending it again changes nothing.
  • 429 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS "https://api.tonbo.dev/v1/streams" \
  -H "Authorization: Bearer $TONBO_API_KEY"

Create a stream

POST /v1/streams · CLI: tonbo stream create

Needs streams.write, which owner, admin and member hold. A narrowed key may not.

Any member creates streams; a narrowed key never does. A name is unique among the account's streams across 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. The region is fixed at creation; without one, the stream goes to the region whose default is true for databases, since a stream lives in the same account bucket. The content type is fixed at creation (application/octet-stream when omitted) and every append must send exactly it. An optional expires_at, at least 60 seconds after the creation and fixed for the stream's life, has Tonbo delete the stream within a minute after it passes, as a deletion would; a replay is not held to the 60 seconds. The answer is 201 once the stream is active and 202 while it is still being created; read it again until it is active. A replay with the same Idempotency-Key answers the same stream; the key reused for another name, region, content type or expiry answers 409. An account holds at most limits.streams_per_account live streams (contracts/streams-databases/v1.json), counted apart from its databases; past that the answer is 403 and names whom to contact. An account whose credit is exhausted answers 402.

Parameters

NameInTypeRequiredDescription
Idempotency-KeyheaderstringyesA value you choose for this one creation, 1 to 255 characters, such as a new UUID. Send a new one for each resource you create, and the same one only to retry that request after a timeout or a lost answer: the retry answers what the first request created, in its current state, and never creates a second. A key reused for a different database, stream or Machine answers 409. 1 to 255 characters.

Request body

application/json, required. Unknown fields are refused.

FieldTypeRequiredDescription
namestringyesThe new stream's name, which its URL shows after s.. 409 when a live stream of the account in any region has it; a deleted stream's name is free again. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.
regionstringnoThe stream's region, fixed for its life; the region whose default is true when omitted. A region closed to databases, and so to streams, answers 503. Matches ^[a-z]{2}-[a-z]+-[0-9]$.
content_typestringnoThe stream's content type, fixed for its life; application/octet-stream when omitted. 3 to 127 characters. Matches ^[a-z0-9][a-z0-9!#$&^_.+-]{0,62}/[a-z0-9][a-z0-9!#$&^_.+-]{0,62}$.
expires_atstring (date-time)noWhen the stream expires, an RFC 3339 time, fixed for its life; it never expires when omitted. A new stream's expiry must be at least 60 seconds after its creation by the registry's clock (422 on expires_at otherwise); a replay of the Idempotency-Key must name the same time and is answered however near or past that time is. Once it has passed, Tonbo deletes the stream within a minute, as a deletion would.

Response

StatusAnswer
201The stream, active
202The stream, still being created
FieldTypeRequiredDescription
dataStreamyes
HeaderStatusDescription
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429, 503Seconds before the client should retry.
Example 201 body
{
  "data": {
    "name": "<name>",
    "region": "<region>",
    "url": "https://example.com",
    "content_type": "<content_type>",
    "expires_at": "2026-11-02T09:30:00.000Z",
    "incarnation": "<incarnation>",
    "state": "creating",
    "public_read": false,
    "created_at": "2026-11-02T09:30:00.000Z",
    "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
    "last_write_at": "2026-11-02T09:30:00.000Z",
    "stored_bytes": {
      "log": 0,
      "snapshot": 0
    },
    "measured_at": "2026-11-02T09:30:00.000Z",
    "writes": "accepting",
    "daily_write_units": [
      0
    ]
  }
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
402payment_requiredThe account’s balance is zero, so nothing new is created.NoAdd credit on Usage & billing, then send the request again. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
409idempotency_conflictThe Idempotency-Key was already sent with a different request.NoSend the request with a new Idempotency-Key, or send the request the key was first used for. (more)
409conflictThe name is held by another live resource of the account, the Idempotency-Key already created another resource or one since deleted, or the resource’s current state does not allow the change. detail says which, and errors names the field.NoPick another name or a new Idempotency-Key, or read the resource again and act on its current state. (more)
422validation_errorA parameter, header or body field breaks its rule; errors names each field.NoCorrect the fields errors names; the operation’s reference gives each one’s rule. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)
503region_unavailableThe region could not be reached or read, or it takes no new resource of this kind. Every answer carries Retry-After.After Retry-AfterSend the request again after Retry-After; if detail says the region takes no new resource of this kind, name another region. (more)

Retries

  • Send a new Idempotency-Key with each request and the same one when you send it again: a repeat answers what the first request did, and the key reused for a different request answers 409 (see Idempotency).
  • 429 and 503 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS "https://api.tonbo.dev/v1/streams" \
  -H "Authorization: Bearer $TONBO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"events"}'

Read a stream

GET /v1/streams/{name} · CLI: tonbo stream show

Needs account.read, which owner, admin and member hold. A narrowed key may call it.

A live stream of the account, with its url, content_type, expires_at and state. A key narrowed to streams reads the streams it names and those under its prefixes; a key narrowed to buckets, or by name to databases alone, reads none. Any name a key does not reach answers 404 with the same status and body as a stream that does not exist.

Parameters

NameInTypeRequiredDescription
namepathstringyesThe stream's name, without the s. its URL adds. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.

Response

StatusAnswer
200The stream
FieldTypeRequiredDescription
dataStreamyes
HeaderStatusDescription
ETag200Current resource version for optional conditional updates.
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429Seconds before the client should retry.
Example 200 body
{
  "data": {
    "name": "<name>",
    "region": "<region>",
    "url": "https://example.com",
    "content_type": "<content_type>",
    "expires_at": "2026-11-02T09:30:00.000Z",
    "incarnation": "<incarnation>",
    "state": "creating",
    "public_read": false,
    "created_at": "2026-11-02T09:30:00.000Z",
    "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
    "last_write_at": "2026-11-02T09:30:00.000Z",
    "stored_bytes": {
      "log": 0,
      "snapshot": 0
    },
    "measured_at": "2026-11-02T09:30:00.000Z",
    "writes": "accepting",
    "daily_write_units": [
      0
    ]
  }
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
404not_foundNo live resource of the key’s account has that name or id, or the key is narrowed away from it.NoCheck the name, and that the key belongs to the account that holds it; list the resources to see what exists. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)

Retries

  • A read: sending it again changes nothing.
  • 429 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS "https://api.tonbo.dev/v1/streams/<name>" \
  -H "Authorization: Bearer $TONBO_API_KEY"

Publish a stream for anonymous reads, or take it private

PATCH /v1/streams/{name} · CLI: tonbo stream update

Needs streams.publish, which owner and admin hold. A narrowed key may not.

Owners and admins, on an active stream. Anonymous readers reach only the stream's current incarnation, with GET and HEAD (reads, long-poll and SSE tails); they never append.

Parameters

NameInTypeRequiredDescription
namepathstringyesThe stream's name, without the s. its URL adds. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.
If-MatchheaderstringnoOptional conditional update; omitted requests use last-write-wins. At most 500 characters.

Request body

application/json, required. Unknown fields are refused.

FieldTypeRequiredDescription
public_readbooleanyestrue publishes the stream: anyone with its URL reads and tails it without a key, and appends still need one. false makes it private again.

Response

StatusAnswer
200The stream
FieldTypeRequiredDescription
dataStreamyes
HeaderStatusDescription
ETag200Current resource version for optional conditional updates.
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429Seconds before the client should retry.
Example 200 body
{
  "data": {
    "name": "<name>",
    "region": "<region>",
    "url": "https://example.com",
    "content_type": "<content_type>",
    "expires_at": "2026-11-02T09:30:00.000Z",
    "incarnation": "<incarnation>",
    "state": "creating",
    "public_read": false,
    "created_at": "2026-11-02T09:30:00.000Z",
    "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
    "last_write_at": "2026-11-02T09:30:00.000Z",
    "stored_bytes": {
      "log": 0,
      "snapshot": 0
    },
    "measured_at": "2026-11-02T09:30:00.000Z",
    "writes": "accepting",
    "daily_write_units": [
      0
    ]
  }
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
404not_foundNo live resource of the key’s account has that name or id, or the key is narrowed away from it.NoCheck the name, and that the key belongs to the account that holds it; list the resources to see what exists. (more)
409conflictThe name is held by another live resource of the account, the Idempotency-Key already created another resource or one since deleted, or the resource’s current state does not allow the change. detail says which, and errors names the field.NoPick another name or a new Idempotency-Key, or read the resource again and act on its current state. (more)
412precondition_failedIf-Match does not name the resource’s current ETag: it changed since you read it. Nothing changed.NoRead the resource again, check that the change still applies, and send it with the new ETag. (more)
422validation_errorA parameter, header or body field breaks its rule; errors names each field.NoCorrect the fields errors names; the operation’s reference gives each one’s rule. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)

Retries

  • It takes no Idempotency-Key; its description above says what sending it again does.
  • If-Match is optional: send the ETag you read, and a 412 precondition_failed means the resource changed since; read it again and decide (see If-Match).
  • 429 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS -X PATCH "https://api.tonbo.dev/v1/streams/<name>" \
  -H "Authorization: Bearer $TONBO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"public_read":false}'

Delete a stream and everything in it

DELETE /v1/streams/{name} · CLI: tonbo stream delete

Needs streams.write, which owner, admin and member hold. A narrowed key may not.

Any member deletes streams; a narrowed key never does. The answer is 200 once the stream is deleted (state is deleted) and 202 while it is still being deleted. Its name is free again once it is deleted; its usage this month stays in /usage/streams. Repeating the request answers the stream being deleted.

Parameters

NameInTypeRequiredDescription
namepathstringyesThe stream's name, without the s. its URL adds. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.

Response

StatusAnswer
200The stream, deleted
202The stream, being deleted
FieldTypeRequiredDescription
dataStreamyes
HeaderStatusDescription
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429Seconds before the client should retry.
Example 200 body
{
  "data": {
    "name": "<name>",
    "region": "<region>",
    "url": "https://example.com",
    "content_type": "<content_type>",
    "expires_at": "2026-11-02T09:30:00.000Z",
    "incarnation": "<incarnation>",
    "state": "creating",
    "public_read": false,
    "created_at": "2026-11-02T09:30:00.000Z",
    "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
    "last_write_at": "2026-11-02T09:30:00.000Z",
    "stored_bytes": {
      "log": 0,
      "snapshot": 0
    },
    "measured_at": "2026-11-02T09:30:00.000Z",
    "writes": "accepting",
    "daily_write_units": [
      0
    ]
  }
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
404not_foundNo live resource of the key’s account has that name or id, or the key is narrowed away from it.NoCheck the name, and that the key belongs to the account that holds it; list the resources to see what exists. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)

Retries

  • It takes no Idempotency-Key; its description above says what sending it again does.
  • 429 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS -X DELETE "https://api.tonbo.dev/v1/streams/<name>" \
  -H "Authorization: Bearer $TONBO_API_KEY"

Read a stream's writes and size over time

GET /v1/streams/{name}/usage · CLI: tonbo stream activity

Needs account.read, which owner, admin and member hold. A narrowed key may call it.

A live stream's writes per hour or day (UTC) over a window of at most 31 days, by default the last 24 hours hourly or the last 30 days daily, through the current step, and its size at the end of each step (now, for the current one), from its region's meter, with the meter's checkpoint as as_of and the stream's last write. Only the stream as it is now counts, not an earlier stream of the same name. A write counts in the step that holds its settlement hour, so the current step grows until it ends; a step that starts after now answers null. A key narrowed to streams reads the streams it reaches, and any other name answers 404 with the same status and body as a stream that does not exist. 503 when the stream's region cannot be read.

Parameters

NameInTypeRequiredDescription
namepathstringyesThe stream's name, without the s. its URL adds. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.
granularityqueryone of "hour" or "day"noOne point per UTC hour (the default) or per UTC day. Default "hour".
fromquerystring (date-time)noThe window's start, on a UTC hour (or day, for daily points); by default 24 hours (or 30 days) before to.
toquerystring (date-time)noThe window's end, exclusive, on a UTC hour (or day), at most 31 days after from; by default the end of the current hour (or day).

Response

StatusAnswer
200The stream's activity
FieldTypeRequiredDescription
dataResourceActivityyesA database's or stream's writes and size over a window, from its region's meter.
HeaderStatusDescription
WWW-Authenticate401Authentication scheme required by this API.
Retry-After429, 503Seconds before the client should retry.
Example 200 body
{
  "data": {
    "name": "<name>",
    "region": "<region>",
    "granularity": "hour",
    "from": "2026-11-02T09:30:00.000Z",
    "to": "2026-11-02T09:30:00.000Z",
    "as_of": "2026-11-02T09:30:00.000Z",
    "last_write_at": "2026-11-02T09:30:00.000Z",
    "points": [
      {
        "start": "2026-11-02T09:30:00.000Z",
        "write_units": 0,
        "append_bytes": 0,
        "records": 0,
        "log_bytes": 0,
        "snapshot_bytes": 0
      }
    ]
  }
}

Errors

StatusCodeWhenSend againWhat to do
401exchange_requiredThe key acts as an Agent, and an Agent’s key is never sent itself.NoExchange the key for a token at the endpoint the answer’s token_endpoint names, and send the token as Authorization: Bearer. (more)
401unauthenticatedThe request carries no key or token, or one that is invalid, expired or revoked.NoSend a valid key, or a token that has not expired, as Authorization: Bearer. (more)
403forbiddenThe key’s role does not hold the capability the operation needs, the key is narrowed away from the resource, or the account already holds as many of the resource as it may.NoUse a key whose role holds the capability, or one that is not narrowed; delete what you no longer need, or ask for a higher limit. (more)
404not_foundNo live resource of the key’s account has that name or id, or the key is narrowed away from it.NoCheck the name, and that the key belongs to the account that holds it; list the resources to see what exists. (more)
422validation_errorA parameter, header or body field breaks its rule; errors names each field.NoCorrect the fields errors names; the operation’s reference gives each one’s rule. (more)
429rate_limitedThe key or the account sent more requests than its rate allows.After Retry-AfterWait for the seconds Retry-After names, then send the request again; spread requests out if it recurs. (more)
503region_unavailableThe region could not be reached or read, or it takes no new resource of this kind. Every answer carries Retry-After.After Retry-AfterSend the request again after Retry-After; if detail says the region takes no new resource of this kind, name another region. (more)

Retries

  • A read: sending it again changes nothing.
  • 429 and 503 carry Retry-After: wait that many seconds, then send the same request again.
Request
curl -sS "https://api.tonbo.dev/v1/streams/<name>/usage" \
  -H "Authorization: Bearer $TONBO_API_KEY"

Objects

Stream

FieldTypeRequiredDescription
namestringyesThe stream's name, without the s. its URL adds. 1 to 83 characters. Matches ^(?!m\.)(?!vol\.)(?!s\.)(?!session\.)(?!proc\.)(?!(?:streams|new)$)(?!.*\.\.)[a-z0-9](?:[a-z0-9._-]{0,81}[a-z0-9])?$.
regionstringyesThe region the stream lives in, fixed for its life. Matches ^[a-z]{2}-[a-z]+-[0-9]$.
urlstring (uri)yesThe stream's data-plane address, {region's Streams origin}/{account id}/s.{name} (contracts/streams-databases/v1.json stream_url); append, read, tail and close it with any Durable Streams client.
content_typestringyesThe stream's content type, fixed at creation; every append sends exactly it. 3 to 127 characters. Matches ^[a-z0-9][a-z0-9!#$&^_.+-]{0,62}/[a-z0-9][a-z0-9!#$&^_.+-]{0,62}$.
expires_atstring (date-time) or nullyesWhen the stream expires, fixed at creation; null when it never expires. Once it has passed, Tonbo deletes the stream within a minute, as a deletion would, and its name is free again.
incarnationstring or nullyesUrsula's Stream-Incarnation as a decimal; null while creating. It changes when a stream of the same name is deleted and created again. Matches ^(0|[1-9][0-9]{0,19})$.
stateone of "creating", "active", "deleting" or "deleted"yesdeleted appears only in the answer to the deletion that completed it.
public_readbooleanyesWhether anonymous reads are served.
created_atstring (date-time)yesWhen the stream was created.
created_bystringyesThe member who created it. Matches ^[a-z0-9._-]{1,64}$.
last_write_atstring (date-time) or nullyesThe last write the region's meter saw, up to a minute behind; null before the first append (the create is not one), and when its region is unavailable.
stored_bytesobjectyesWhat the region's meter last saw stored; null when not yet reported or unavailable.
stored_bytes.loginteger or nullyesBytes of the stream's retained messages, as Tonbo stores them; null when not reported. At least 0.
stored_bytes.snapshotinteger or nullyesBytes of its snapshots; null when not reported. At least 0.
measured_atstring (date-time) or nullnoWhen the region's meter last read last_write_at and stored_bytes (every minute while it is healthy); null when the stream is not yet metered or its region is unavailable. Optional; absent from older answers.
writesone of "accepting", "suspended" or nullnoWhether Tonbo accepts writes to the stream now. suspended while the account has no credit left, when writes answer 402 PAYMENT_REQUIRED and reads continue; writes resume shortly after a top-up. It is the account's state, the same for each of its databases and streams. Only in the answer for one stream (show and update), never in a list; null when it could not be read.
daily_write_unitsarray of integer or nullnoThe stream's write units on each of the last 7 UTC days, oldest first, the last being today so far, for a sparkline: only in a list asked for it with include=daily_writes, never in a show; null when its region could not be read. Only the stream as it is now counts, not an earlier stream of the same name. 7 to 7 items.
Example Stream
{
  "name": "<name>",
  "region": "<region>",
  "url": "https://example.com",
  "content_type": "<content_type>",
  "expires_at": "2026-11-02T09:30:00.000Z",
  "incarnation": "<incarnation>",
  "state": "creating",
  "public_read": false,
  "created_at": "2026-11-02T09:30:00.000Z",
  "created_by": "agent.3f1c2a9e-5b7d-4c8e-9f10-2a3b4c5d6e7f",
  "last_write_at": "2026-11-02T09:30:00.000Z",
  "stored_bytes": {
    "log": 0,
    "snapshot": 0
  },
  "measured_at": "2026-11-02T09:30:00.000Z",
  "writes": "accepting",
  "daily_write_units": [
    0
  ]
}