Management API reference
Last updated 2 November 2026
Every operation of the Management API at https://api.tonbo.dev/v1, the API the tonbo CLI calls, generated from its OpenAPI document.
The document is public, at openapi.json and, as written, openapi.yaml: give it to an OpenAPI client generator or a coding agent. It also holds the operations of Tonbo Yield’s own client and retired ones kept for their callers, which this page leaves out.
Authentication
Every request carries a key as a bearer token, here from TONBO_API_KEY:
curl -sS https://api.tonbo.dev/v1/account \
-H "Authorization: Bearer $TONBO_API_KEY"A personal key (tbo_…) presented directly, or an access token exchanged from any key with the https://api.tonbo.dev audience. The key acts as its member with the member's current role and the key's narrowing, re-read on every request.
API keys and tokens explains how to create a key, the token exchange and what a key can reach.
Compatibility
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.
Errors
A refusal answers application/problem+json, a Problem whose code names the refusal. The answers operations share:
| Answer | Status | When |
|---|---|---|
Conflict | 409 | Resource or idempotency conflict |
Forbidden | 403 | The authenticated principal lacks the exact action |
MachineRefused | 403, 409, 422, 429 | A refusal whose code and status are one of contracts/machines/machine-v2.json errors (such as name_taken, shape_not_offered, machine_failed or create_rate_limited), or a shared one such as region_not_offered (422, Machines are not offered in the region named or defaulted), forbidden, validation_error or rate_limited. A 429 (device_report_throttled, create_rate_limited, rate_limited) carries Retry-After. |
MemberUnauthorized | 401 | Missing or invalid credentials (unauthenticated), or an Agent key presented directly (exchange_required): exchange it at token_endpoint and present the access token. |
NotFound | 404 | Resource not found or outside the principal's Agent |
PaymentRequired | 402 | The account's credit is exhausted (payment_required) |
PreconditionFailed | 412 | The supplied If-Match value is stale (precondition_failed) |
PreconditionRequired | 428 | The operation requires If-Match and the request has none (precondition_required, RFC 6585) |
RateLimited | 429 | Request rate limit exceeded |
RegionUnavailable | 503 | The region could not be reached or read; retry after Retry-After (region_unavailable). A region where the resource is not offered answers 422 region_not_offered instead. |
ValidationError | 422 | Request validation failed |
Account
GET /accountRead the caller's account, membership and limitsGET /regionsList the regions new resources can be created inGET /membersList the account's people and Agents with their rolesPATCH /members/{subject}Change a member's role, or rename an AgentPOST /agentsCreate an Agent, an identity with a role in the account
Read the caller's account, membership and limits
GET /v1/account · CLI: tonbo account show
Responses
| Status | Answer | Body |
|---|---|---|
200 | The account | data: Account |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/account" \
-H "Authorization: Bearer $TONBO_API_KEY"List the regions new resources can be created in
GET /v1/regions · CLI: tonbo region list
Responses
| Status | Answer | Body |
|---|---|---|
200 | Regions | data: array of Region |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/regions" \
-H "Authorization: Bearer $TONBO_API_KEY"List the account's people and Agents with their roles
GET /v1/members · CLI: tonbo member list
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Members | data: array of Member, next_cursor: NextCursor |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/members" \
-H "Authorization: Bearer $TONBO_API_KEY"Change a member's role, or rename an Agent
PATCH /v1/members/{subject} · CLI: tonbo member update
Owners and admins give a person or an Agent another role; only an owner grants owner. name renames an Agent: it follows the Agent name rule and is unique among the account's active Agents (409 otherwise), and the Agent keeps its id, keys, home region and public hostname. A person's name belongs to their own profile, so name on a person is refused with 422 validation_error on the field name. Both fields in one request change together or not at all. People change members; an Agent's credential is refused with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
subject | path | MemberSubject | yes |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
200 | The member | data: Member |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | Conflict | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS -X PATCH "https://api.tonbo.dev/v1/members/<subject>" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'Create an Agent, an identity with a role in the account
POST /v1/agents · CLI: tonbo agent create
Owners and admins create Agents; only an owner grants owner. A replay with the same Idempotency-Key returns the Agent the first request created.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
201 | The Agent | data: AccountAgent |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
409 | Conflict | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/agents" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"<name>"}'API keys
GET /api-keysList your keys, or every key of the account for an owner or adminPOST /api-keysCreate a key; its secret is in this answer onlyGET /api-keys/{key_id}Read one keyDELETE /api-keys/{key_id}Revoke a key and every token minted from it
List your keys, or every key of the account for an owner or admin
GET /v1/api-keys · CLI: tonbo api-key list
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Live keys | data: array of ApiKey, next_cursor: NextCursor |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/api-keys" \
-H "Authorization: Bearer $TONBO_API_KEY"Create a key; its secret is in this answer only
POST /v1/api-keys · CLI: tonbo api-key create
A personal key acts as you; an Agent key (member: agent.<agent id>), which owners and admins create, acts as the Agent, whose role may not exceed yours. read_only, and either buckets or any of databases, database_prefixes, streams and stream_prefixes, narrow the key for its whole life: a different narrowing takes a new key. An access token never creates a key, and neither does a narrowed key.
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
201 | The key and its secret | data: ApiKeyWithSecret |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | Conflict | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/api-keys" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"<name>"}'Read one key
GET /v1/api-keys/{key_id} · CLI: tonbo api-key show
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key_id | path | Uuid | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The key | data: ApiKey |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/api-keys/<key_id>" \
-H "Authorization: Bearer $TONBO_API_KEY"Revoke a key and every token minted from it
DELETE /v1/api-keys/{key_id} · CLI: tonbo api-key revoke
Your own key, or any key of the account for an owner or admin. A narrowed key may revoke itself (tonbo logout).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key_id | path | Uuid | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The revocation | data: object |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
curl -sS -X DELETE "https://api.tonbo.dev/v1/api-keys/<key_id>" \
-H "Authorization: Bearer $TONBO_API_KEY"Databases
GET /databasesList the account's databasesPOST /databasesCreate a databaseGET /databases/{name}Read a databasePATCH /databases/{name}Publish a database for anonymous reads, or take it privateDELETE /databases/{name}Delete a database and everything in it
List the account's databases
GET /v1/databases · CLI: tonbo database list
Live rows of the listed kinds (contracts/streams-databases/v1.json kinds whose api is databases: a member's databases and each Machine's database, with kind and the owning Machine as owner_id), creating, active or deleting, in every region, by name. A key narrowed to databases sees only the databases it reaches, and a key narrowed to buckets, or by name to streams 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 databases then show null sizes.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
prefix | query | DatabasePrefix | no | Only databases whose name starts with this prefix. |
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Databases | data: array of Database, next_cursor: NextCursor, unavailable_regions: array of RegionId |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/databases" \
-H "Authorization: Bearer $TONBO_API_KEY"Create a database
POST /v1/databases · CLI: tonbo database create
Any member creates databases; a narrowed key never does. A name is unique within the account across every region while a database holds it, and is free again once that database is deleted. The region is fixed at creation; without one, the database goes to the region whose default is true. An optional expires_at, at least 60 seconds after the creation and fixed for the database's life, has Tonbo delete the database within a minute after it passes, as a deletion would; a replay is not held to the 60 seconds. Databases and streams expire by the same rule; a Machine's database never expires. The answer is 201 once the database 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 database; the key reused for another name, region or expiry answers 409. An account holds at most limits.databases_per_account live databases (contracts/streams-databases/v1.json); past that the answer is 403 and names whom to contact. An account whose credit is exhausted answers 402.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
201 | The database, active | data: Database |
202 | The database, still being created | data: Database |
401 | MemberUnauthorized | Problem |
402 | PaymentRequired | Problem |
403 | Forbidden | Problem |
409 | Conflict | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS "https://api.tonbo.dev/v1/databases" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"<name>"}'Read a database
GET /v1/databases/{name} · CLI: tonbo database show
A live database of the account, with its url, expires_at and state; clients that open a database by name, such as @tonbo/sqlite-ursula/tonbo, resolve it here. A key narrowed to databases reads the databases it names and those under its prefixes, and any other name answers 404 with the same status and body as a database that does not exist, so the narrowing does not disclose whether the account's other databases exist. A key narrowed to buckets, or by name to streams alone, reads none.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | ListedDatabaseName | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The database | data: Database |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/databases/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY"Publish a database for anonymous reads, or take it private
PATCH /v1/databases/{name} · CLI: tonbo database update
Owners and admins, on an active database. Anonymous readers reach only the database's current incarnation. A Machine's database answers 409 managed_by_machine (contracts/streams-databases/v1.json kinds.managed_refusal).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | ListedDatabaseName | yes | |
If-Match | header | string | no | Optional conditional update; omitted requests use last-write-wins. |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
200 | The database | data: Database |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | Conflict | Problem |
412 | PreconditionFailed | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS -X PATCH "https://api.tonbo.dev/v1/databases/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"public_read":false}'Delete a database and everything in it
DELETE /v1/databases/{name} · CLI: tonbo database delete
Any member deletes databases; a narrowed key never does. The answer is 200 once the database 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/databases. Repeating the request answers the database being deleted. A Machine's database is deleted with its Machine and answers 409 managed_by_machine (contracts/streams-databases/v1.json kinds.managed_refusal).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | ListedDatabaseName | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The database, deleted | data: Database |
202 | The database, being deleted | data: Database |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
curl -sS -X DELETE "https://api.tonbo.dev/v1/databases/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY"Streams
GET /streamsList the account's streamsPOST /streamsCreate a streamGET /streams/{name}Read a streamPATCH /streams/{name}Publish a stream for anonymous reads, or take it privateDELETE /streams/{name}Delete a stream and everything in it
List the account's streams
GET /v1/streams · CLI: tonbo stream list
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.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
prefix | query | StreamPrefix | no | Only streams whose name starts with this prefix. |
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Streams | data: array of Stream, next_cursor: NextCursor, unavailable_regions: array of RegionId |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/streams" \
-H "Authorization: Bearer $TONBO_API_KEY"Create a stream
POST /v1/streams · CLI: tonbo stream create
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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
201 | The stream, active | data: Stream |
202 | The stream, still being created | data: Stream |
401 | MemberUnauthorized | Problem |
402 | PaymentRequired | Problem |
403 | Forbidden | Problem |
409 | Conflict | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
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":"<name>"}'Read a stream
GET /v1/streams/{name} · CLI: tonbo stream show
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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | StreamName | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The stream | data: Stream |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
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
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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | StreamName | yes | |
If-Match | header | string | no | Optional conditional update; omitted requests use last-write-wins. |
Request body
application/json, required.
Responses
| Status | Answer | Body |
|---|---|---|
200 | The stream | data: Stream |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | Conflict | Problem |
412 | PreconditionFailed | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
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
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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | StreamName | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The stream, deleted | data: Stream |
202 | The stream, being deleted | data: Stream |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
curl -sS -X DELETE "https://api.tonbo.dev/v1/streams/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY"Usage
GET /usageRead the account's rated usage of one monthGET /usage/databasesRead each database's usage of one month at list priceGET /usage/streamsRead each stream's usage of one month at list price
Read the account's rated usage of one month
GET /v1/usage · CLI: tonbo usage show
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
period | query | string | no | The calendar month in UTC; the current month when omitted. |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Usage | data: Usage |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/usage" \
-H "Authorization: Bearer $TONBO_API_KEY"Read each database's usage of one month at list price
GET /v1/usage/databases · CLI: tonbo database usage
One row per listed database version (name, stream creation time and counting history) metered in the month, rolled up by contracts/streams-databases/v1.json kinds.values.<kind>.usage: a Machine's logs and inbox streams are added into its database's row, and a Volume's ledger into other; in every region the account reaches, including databases deleted during the month, plus other for metered usage outside the account's databases (its streams, which /usage/streams lists, session processing and anything unattributed), so the rows and other add up to the account's metered total. Values are at list price, before the monthly allowance and credit; Usage & billing (/usage) shows what is charged.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
period | query | string | no | The calendar month in UTC; the current month when omitted. |
sort | query | one of "-list_value" or "name" | no | By list value, highest first (the default), or by name. |
prefix | query | DatabasePrefix | no | Only databases whose name starts with this prefix. |
names | query | string | no | Only these databases, 1 to 100 listed names, comma-separated (a database name or a Machine's database). |
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Per-database usage | DatabaseUsagePage |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/usage/databases" \
-H "Authorization: Bearer $TONBO_API_KEY"Read each stream's usage of one month at list price
GET /v1/usage/streams · CLI: tonbo stream usage
One row per stream version (name, stream creation time and counting history) metered in the month, in every region the account reaches, including streams deleted during the month, plus other for metered usage outside the account's streams (its databases, session processing and anything unattributed), so the rows and other add up to the account's metered total, as /usage/databases does for databases; no stream is a row of both. Values are at list price, before the monthly allowance and credit, which databases and streams share; Usage & billing (/usage) shows what is charged.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
period | query | string | no | The calendar month in UTC; the current month when omitted. |
sort | query | one of "-list_value" or "name" | no | By list value, highest first (the default), or by name. |
prefix | query | StreamPrefix | no | Only streams whose name starts with this prefix. |
names | query | string | no | Only these streams, 1 to 100 stream names, comma-separated. |
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Per-stream usage | StreamUsagePage |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | ValidationError | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/usage/streams" \
-H "Authorization: Bearer $TONBO_API_KEY"Machines Not open yet
Machines are not open yet. These pages describe Machines as they will open; until then, a create answers region_not_offered (422), “Machines are not offered in any region yet.”
GET /machinesList the account's MachinesPOST /machinesCreate a MachineGET /machines/{name}Read a MachinePATCH /machines/{name}Change a Machine's specDELETE /machines/{name}Delete a MachinePOST /machines/{name}/sleepPut a Machine to sleep nowGET /machines/{name}/activationsList a Machine's activationsGET /machine-shapesList the Machine shapes
List the account's Machines
GET /v1/machines · CLI: tonbo machine list
The account's Machines by name, except those being deleted: managed Machines and, in a personal account, its devices (kind byoc, which PUT /machines/self registers) from every region, whatever machines.open says; unavailable_regions names the regions whose Machines on the page could not be read. A device answers id, name, kind, region, byoc (with its key_state, derived from its current login key), created_at and updated_at; its byoc.hostname and byoc.device_id are answered to the device's person only, never to an Agent key. A narrowed key never reaches a Machine. An organization holds managed Machines only (contracts/machines/machine-v2.json kinds_by_account_kind), so its list never answers a byoc Machine or its fields, and its pages and cursors are those of its managed Machines alone.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Machines | data: array of Machine, next_cursor: NextCursor, unavailable_regions: array of RegionId |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
422 | MachineRefused | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/machines" \
-H "Authorization: Bearer $TONBO_API_KEY"Create a Machine
POST /v1/machines · CLI: tonbo machine create
Any member creates Machines (machines.write); a public port also needs machines.public, and a narrowed key never does. The image is the reserved platform reference tonbo.dev/platform (machine-v2.schema.json $defs.platform_image_reference), which resolves nothing, is stored with repository and digest null and reads as state ready, or a public registry reference, which resolves to its canonical repository and linux/arm64 digest, stored with the reference, and reads as state pulling until a node has pulled it (state is computed, never stored; see getMachine); a registry reference is refused before anything is written, with 422 image_platform_unsupported when it has no linux/arm64 manifest and validation_error when it is not a public reference the resolver can fetch under machine-v2.json image.distribution (a malformed reference, an unknown or unavailable image, a redirected manifest or an oversized document). The name, the HTTPS label <name>-<account> and the SSH username are then reserved for the account, and the Machine is recorded in its region, which is fixed for its life; without region it goes to the account's default creation region. A region where Machines are not offered (machines.open in contracts/regions/cells-v1.json) answers the shared 422 region_not_offered, and a shape that is not offered 422 shape_not_offered, before anything is written. The answer is 202 while the Machine is being created and 201 in every other state (machine-v2.json creation.create_status). Both carry Location, the Machine's URL, and the 202 also Retry-After, the seconds to wait before reading the Machine there again (machine-v2.json creation.poll_after_seconds), until its state is active or failed. A replay with the same Idempotency-Key answers the same Machine as it is now, so a replay of a Machine whose creation failed answers 201 with its failure; the key reused for another request answers 409 idempotency_conflict. Refusals carry the codes and statuses of contracts/machines/machine-v2.json errors.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes |
Request body
application/json, required.
machines/machine-v2.schema.json#/$defs/create
Responses
| Status | Answer | Body |
|---|---|---|
201 | The Machine, no longer being created (a replay of a failed create carries its failure) | MachineEnvelope |
202 | The Machine, still being created | MachineEnvelope |
401 | MemberUnauthorized | Problem |
403 | MachineRefused | Problem |
409 | MachineRefused | Problem |
422 | MachineRefused | Problem |
429 | MachineRefused | Problem |
curl -sS "https://api.tonbo.dev/v1/machines" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @request.jsonRead a Machine
GET /v1/machines/{name} · CLI: tonbo machine show
A Machine of the account. A device (kind byoc, in a personal account only) is served whatever machines.open says and answers its byoc facts, hostname and device_id to its person only, with its id as its ETag ("<id>"), which a delete may name in If-Match. A managed Machine's ETag is "<id>.<revision>" (contracts/machines/machine-v2.json etag), opaque to clients: an update names it in If-Match, and a delete or a sleep may, so a tag read from one Machine never matches another that later takes its name. A Machine is read whatever machines.open says, so a closure never hides it; a region this server cannot reach answers 503 region_unavailable. Its image names the canonical repository a registry image is pulled from and a state computed from the pull: pulling until a node has pulled the digest while the Machine is creating or active, ready once one has (always for the platform reference tonbo.dev/platform, which is never pulled), failed with a failure whose code is one of contracts/machines/machine-v2.json image.failures, and not_pulled on a failed or deleting Machine that no node pulled, since nothing will. While the image is not ready, a request that would wake the Machine answers 503 image_pulling, or 409 image_failed once the pull failed. status.conditions says why a Machine is not doing what it should: wake_blocked when its last wake was refused and none has succeeded since, with the reason, since and, for a crash backoff, retry_at; creation_delayed once it has been creating for longer than contracts/machines/machine-v2.json creation.alert_after_seconds; egress_blocked while its outbound access is blocked; and volume_purged when the Volume its spec names was purged (in practice after 30 days of suspension past the owners' notice), so it boots without it until the spec names another Volume or none. activation.revision is the spec revision the live activation was admitted with. Every spec change advances the Machine's revision, but ports and sleep_after_seconds apply at once, so a lower activation.revision means a sleep is needed only when image, command, shape or env changed; GET /machines/{name}/activations says how each earlier activation ended. A managed Machine names its creator in created_by.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | machines/machine-v2.schema.json#/$defs/name | yes |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The Machine, with its ETag | MachineEnvelope |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS "https://api.tonbo.dev/v1/machines/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY"Change a Machine's spec
PATCH /v1/machines/{name} · CLI: tonbo machine update
A managed Machine only: a device answers 409 machine_kind_mismatch, whatever machines.open says. If-Match is required, because env and ports are replaced whole: the change is written only at the revision it names, so a missing one answers 428 precondition_required, a stale one 412 precondition_failed, and a concurrent change is never lost; an If-Match that is not this Machine's ETag, another Machine's that had the name included, also answers 412 precondition_failed, and so does a bare revision ("<n>"), whose detail says to upgrade @tonbo/cli to 0.9.0 or later (machine-v2.json etag.bare_revision). A Machine whose creation failed answers 409 machine_failed and does not change. A region where Machines are not offered answers 422 region_not_offered. A change to image, command, shape or env applies at the next activation; ports and sleep_after_seconds apply at once. A changed image follows the create's rule: the platform reference tonbo.dev/platform resolves nothing, and any other reference resolves to its canonical repository and linux/arm64 digest, or is refused before anything is written as the create refuses it (422 image_platform_unsupported or validation_error). Naming an image, the same one included, resolves it again and returns its state to pulling, so a failed pull is retried. Making a port public also needs machines.public. Refusals carry the codes and statuses of contracts/machines/machine-v2.json errors.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | machines/machine-v2.schema.json#/$defs/name | yes | |
If-Match | header | string | yes | The Machine's ETag as read, "<id>.<revision>" (contracts/machines/machine-v2.json etag); a Machine update is written only to that Machine at that revision. Required, because env and ports are replaced whole; a missing one answers 428 precondition_required. |
Request body
application/json, required.
machines/machine-v2.schema.json#/$defs/update
Responses
| Status | Answer | Body |
|---|---|---|
200 | The Machine | MachineEnvelope |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | MachineRefused | Problem |
412 | PreconditionFailed | Problem |
422 | MachineRefused | Problem |
428 | PreconditionRequired | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS -X PATCH "https://api.tonbo.dev/v1/machines/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "If-Match: <if-match>" \
-H "Content-Type: application/json" \
-d @request.jsonDelete a Machine
DELETE /v1/machines/{name} · CLI: tonbo machine delete
A managed Machine stops and is purged with its database and logs; its name is free at once for the account's next Machine, while its hostnames stay reserved to the account. The answer is 202 with the Machine being deleted, after which it is absent from the API, or 204 with no body when the name's create never reached its region and only the name was released. A region where Machines are not offered answers 422 region_not_offered, and one this server cannot reach 503 region_unavailable. A device (kind byoc) is forgotten instead, whatever machines.open says (contracts/machines/machine-v2.json kinds.byoc.forget): it is hidden and leaves the per-person cap at once, and its name is free once the forget drains; the answer is 202 with the device as it was, or 204 when its region held no row for it; a 204 names the kind in X-Tonbo-Machine-Kind. Forgetting a device that is not the caller's own (an Agent key's) also needs api_keys.others (actions delete byoc_requires_also), 403 otherwise. A device's key is not revoked: a device whose key is still active registers again at its next start. If-Match is optional; when sent it must be the Machine's current ETag (a device's is its id), or the answer is 412 precondition_failed and nothing is deleted, so a delete retried after the name was reused never deletes the new Machine. A name whose create never reached its region has no ETag to match.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | machines/machine-v2.schema.json#/$defs/name | yes | |
If-Match | header | string | no | The Machine's ETag as read (contracts/machines/machine-v2.json etag); when sent, the request acts only on that Machine at that revision, and otherwise answers 412 precondition_failed. |
Responses
| Status | Answer | Body |
|---|---|---|
202 | The Machine, being deleted, or the device, forgotten | MachineEnvelope |
204 | The name was released, no Machine having been recorded under it, or the device was forgotten, its region holding no row for it | none |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
412 | PreconditionFailed | Problem |
422 | MachineRefused | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS -X DELETE "https://api.tonbo.dev/v1/machines/<name>" \
-H "Authorization: Bearer $TONBO_API_KEY"Put a Machine to sleep now
POST /v1/machines/{name}/sleep · CLI: tonbo machine sleep
machine-controller applies the Machine's effective idle action (status.sleep). An asleep Machine wakes on its next connection; there is no wake operation. The answer is 202 while an activation runs, with Retry-After, the seconds to wait before reading the Machine again (machine-v2.json sleep.poll_after_seconds), until its status.power is asleep; and 200 with the Machine unchanged when there is nothing to do: it is asleep, or still being created. A Machine whose creation failed answers 409 machine_failed, and a device 409 machine_kind_mismatch, whatever machines.open says. A region where Machines are not offered answers 422 region_not_offered. If-Match is optional; when sent it must be the Machine's current ETag, or the answer is 412 precondition_failed and nothing changes.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | machines/machine-v2.schema.json#/$defs/name | yes | |
If-Match | header | string | no | The Machine's ETag as read (contracts/machines/machine-v2.json etag); when sent, the request acts only on that Machine at that revision, and otherwise answers 412 precondition_failed. |
Responses
| Status | Answer | Body |
|---|---|---|
200 | The Machine, unchanged, with nothing to do | MachineEnvelope |
202 | The Machine, going to sleep | MachineEnvelope |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | MachineRefused | Problem |
412 | PreconditionFailed | Problem |
422 | MachineRefused | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS -X POST "https://api.tonbo.dev/v1/machines/<name>/sleep" \
-H "Authorization: Bearer $TONBO_API_KEY"List a Machine's activations
GET /v1/machines/{name}/activations · CLI: tonbo machine activations
A managed Machine's activations, newest first: each boot or refused wake, with what woke it, the spec revision and shape it was admitted with, when, and its end (machine-v2.schema.json $defs.activation_end), null while it is live. An end's reason is why it ended: a refusal such as payment_required or crash_backoff, a stop such as idle_early, sleep_after, workload_exited (with the exit_code or signal) or funding_stop, or the node's. Any member reads it (account.read), whatever machines.open says; a narrowed key never does. A device answers 409 machine_kind_mismatch, and a region this server cannot reach 503 region_unavailable. The cursor is tied to the Machine, so it never pages another Machine that later takes the name.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | machines/machine-v2.schema.json#/$defs/name | yes | |
cursor | query | string | no | Opaque cursor tied to the original query shape. |
limit | query | integer | no |
Responses
| Status | Answer | Body |
|---|---|---|
200 | Activations, newest first | data: array of machines/machine-v2.schema.json#/$defs/activation_entry, next_cursor: NextCursor |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
404 | NotFound | Problem |
409 | MachineRefused | Problem |
422 | MachineRefused | Problem |
429 | RateLimited | Problem |
503 | RegionUnavailable | Problem |
curl -sS "https://api.tonbo.dev/v1/machines/<name>/activations" \
-H "Authorization: Bearer $TONBO_API_KEY"List the Machine shapes
GET /v1/machine-shapes · CLI: tonbo machine shapes
Every shape of contracts/machines/shapes-v1.json, with whether a Machine may name it now and its list price for an hour at full use, and the shape a client proposes by default. Served to any member whatever machines.open says; a narrowed key never reaches it.
Responses
| Status | Answer | Body |
|---|---|---|
200 | Shapes | data: array of MachineShape, default: string |
401 | MemberUnauthorized | Problem |
403 | Forbidden | Problem |
429 | RateLimited | Problem |
curl -sS "https://api.tonbo.dev/v1/machine-shapes" \
-H "Authorization: Bearer $TONBO_API_KEY"Schemas
Account
| Field | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
kind | one of "user" or "organization" | yes | |
name | string | yes | |
member | object | yes | The caller's own membership. |
member.kind | one of "user" or "agent" | yes | |
member.subject | MemberSubject | yes | |
member.role | AccountRole | yes | |
limits | object | yes | |
limits.buckets | integer | yes | Live buckets the account may hold. |
AccountAgent
| Field | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
subject | MemberSubject | yes | |
name | string | yes | |
role | AccountRole | yes | |
region | string | yes | |
created_at | Timestamp | yes |
AccountRole
one of "owner", "admin" or "member"
AgentName
The Agent's one name, defined by contracts/agents/agent-name-v1.json. It is unique among active Agents within its account and an owner or admin may change it (updateMember); there is no separate display name or slug.
string
ApiKey
| Field | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
name | string | yes | |
member | MemberSubject | yes | |
member_kind | one of "user" or "agent" | yes | |
last4 | string | yes | |
read_only | boolean | yes | |
buckets | array of string | yes | |
databases | array of DatabaseName | yes | |
database_prefixes | array of DatabasePrefix | yes | |
streams | array of StreamName | yes | |
stream_prefixes | array of StreamPrefix | yes | |
expires_at | Timestamp or null | yes | |
last_used_at | Timestamp or null | yes | Recorded at most once a minute. |
created_at | Timestamp | yes |
ApiKeyExpiration
one of "15_days", "1_month", "6_months", "1_year" or "never"
ApiKeyWithSecret
Every field of ApiKey, and:
| Field | Type | Required | Description |
|---|---|---|---|
key | string | yes | The secret, shown once. tbo_ followed by 50 base-58 characters, the last six a checksum. |
ContentType
A stream's content type (contracts/streams-databases/v1.json content_type): one lowercase media type type/subtype without parameters, at most 127 bytes, never under application/vnd.ursula. (the formats Tonbo manages). It is the form Ursula normalizes a content type to, so every append sends exactly it; application/json streams are in JSON mode.
string
CreateAccountAgentRequest
| Field | Type | Required | Description |
|---|---|---|---|
name | AgentName | yes | |
role | AccountRole | no | |
region | string | no | The Agent's home region; the only open region when omitted. |
CreateApiKeyRequest
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | |
member | MemberSubject | no | Omit for your own personal key; agent.<agent id> for an Agent key. |
read_only | boolean | no | Narrow the key to read-only actions, for its whole life. |
buckets | array of string | no | Narrow the key to these registered buckets of the account, for its whole life. Never with databases, database_prefixes, streams or stream_prefixes. |
databases | array of DatabaseName | no | Narrow the key to these databases, for its whole life; a name need not exist yet. Never with buckets. |
database_prefixes | array of DatabasePrefix | no | Narrow the key to the databases whose name starts with one of these, for its whole life. Never with buckets. |
streams | array of StreamName | no | Narrow the key to these raw streams, by the name the streams API shows, for its whole life; a name need not exist yet. Never with buckets. A key narrowed to both databases and streams reaches both. |
stream_prefixes | array of StreamPrefix | no | Narrow the key to the raw streams whose name starts with one of these, for its whole life; each at most 83 bytes, the longest stream name. Never with buckets. |
expires_in | ApiKeyExpiration | no |
CreateDatabaseRequest
| Field | Type | Required | Description |
|---|---|---|---|
name | DatabaseName | yes | |
region | RegionId | no | The database's region, fixed for its life; the region whose default is true when omitted. A region closed to databases answers 503. |
expires_at | Timestamp | no | When the database expires, an RFC 3339 time, fixed for its life; it never expires when omitted. A new database'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 database within a minute, as a deletion would. |
CreateStreamRequest
| Field | Type | Required | Description |
|---|---|---|---|
name | StreamName | yes | |
region | RegionId | no | The 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. |
content_type | ContentType | no | The stream's content type, fixed for its life; application/octet-stream when omitted. |
expires_at | Timestamp | no | When 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. |
Database
| Field | Type | Required | Description |
|---|---|---|---|
name | ListedDatabaseName | yes | |
kind | DatabaseKind | yes | |
owner_id | Uuid or null | yes | The Machine that owns a machine row; null for a member's database. |
region | RegionId | yes | |
url | string (uri) | yes | The database's data-plane address, {region's database origin}/{account id}/{name}; open it with the SQLite on Ursula client. |
expires_at | Timestamp or null | yes | When the database expires, fixed at creation; null when it never expires, and always for a Machine's database. Once it has passed, Tonbo deletes the database within a minute, as a deletion would, and its name is free again. |
incarnation | string or null | yes | Ursula's Stream-Incarnation as a decimal; null while creating. A client that cached the URL resolves the database again when it changes. |
state | one of "creating", "active", "deleting" or "deleted" | yes | deleted appears only in the answer to the deletion that completed it. |
public_read | boolean | yes | Whether anonymous reads are served. |
created_at | Timestamp | yes | |
created_by | MemberSubject | yes | |
last_write_at | Timestamp or null | yes | The last write the region's meter saw, up to a minute behind; null until a host first opens it (an open writes; the create does not), and when its region is unavailable. |
stored_bytes | object | yes | What the region's meter last saw stored; null when not yet reported or unavailable. |
stored_bytes.log | integer or null | yes | |
stored_bytes.snapshot | integer or null | yes | |
measured_at | Timestamp or null | no | When the region's meter last read last_write_at and stored_bytes (every minute while it is healthy); null when the database is not yet metered or its region is unavailable. Optional; absent from older answers. |
writes | one of "accepting", "suspended" or null | no | Whether Tonbo accepts writes to the database 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 database (show and update), never in a list; null when it could not be read. |
DatabaseKind
The registry kind of a listed row (contracts/streams-databases/v1.json kinds). A machine row is managed by its Machine; deleting it or changing its visibility answers 409 managed_by_machine.
one of "database" or "machine"
DatabaseName
A database's name (contracts/streams-databases/v1.json name): 1 to 85 lowercase letters, digits, dots, underscores and hyphens, starting and ending with a letter or digit, without ..; m., vol., s., session. and proc. are reserved, and streams and new (the console's create page) are not names. It appears unencoded in the database's URL and in key narrowing.
string
DatabasePrefix
A database name prefix (contracts/streams-databases/v1.json prefix); it selects every name that starts with it.
string
DatabaseUsage
Every field of DatabaseUsageAmounts, and:
| Field | Type | Required | Description |
|---|---|---|---|
name | ListedDatabaseName | yes | |
kind | DatabaseKind | yes | |
owner_id | Uuid or null | yes | The Machine that owns a machine row, whose logs and inbox streams are added into it; null for a member's database. |
region | RegionId | yes | |
stream_created_at | Timestamp | yes | When Ursula created the stream version; with counted_since, the version the row is. |
counted_since | string | yes | The Ursula usage history the version began counting in, 16 hex digits. |
state | one of "active" or "deleted" | yes | |
created_at | Timestamp or null | yes | Null for a metered version the registry does not know. |
deleted_at | Timestamp or null | yes |
DatabaseUsageAmounts
| Field | Type | Required | Description |
|---|---|---|---|
write_units | string | yes | Write units, an integer as text. |
retention_gib_months | string | yes | The retained log in GiB-months (GiB = 1024^3 bytes, month = retention_month_seconds), a decimal as text. |
snapshot_gib_months | string or null | yes | Snapshots in GiB-months, a decimal as text; null when never reported. |
list_value_micros | integer | yes | The value at list price in micro-dollars, before allowance and credit. |
DatabaseUsagePage
| Field | Type | Required | Description |
|---|---|---|---|
period | string | yes | |
as_of | Timestamp or null | yes | The oldest meter checkpoint among the regions read; usage after it is not yet counted. Null before a region's first. |
currency | "usd" | yes | |
basis | "at_list_price_before_allowance_and_credit" | yes | |
pricing | object | yes | The list prices of contracts/billing/streams-prices-v1.json the values use. |
pricing.write_unit_bytes | integer | yes | |
pricing.write_micros_per_million_units | integer | yes | |
pricing.retention_micros_per_gib_month | integer | yes | |
pricing.retention_unit_bytes | integer | yes | |
pricing.retention_month_seconds | integer | yes | |
data | array of DatabaseUsage | yes | |
other | DatabaseUsageAmounts | yes | Metered usage outside the account's databases (its streams, session processing and anything unattributed), in every region read. |
next_cursor | NextCursor | yes | |
unavailable_regions | array of RegionId | yes | Regions whose usage could not be read; their databases and other are missing from this answer. |
ListedDatabaseName
The name of a row the databases API lists (contracts/streams-databases/v1.json kinds whose api is databases): a member's database or a Machine's.
Machine
A Machine as contracts/machines/machine-v2.schema.json defines it.
machines/machine-v2.schema.json
MachineDatabaseName
A Machine's database, m.<machine id> (contracts/streams-databases/v1.json kinds.values.machine.name_pattern). Control creates and deletes it with its Machine.
string
MachineEnvelope
| Field | Type | Required | Description |
|---|---|---|---|
data | Machine | yes |
MachineShape
A shape of contracts/machines/shapes-v1.json shapes, whether a Machine may name it now, and its list price.
| Field | Type | Required | Description |
|---|---|---|---|
shape | machines/machine-v2.schema.json#/$defs/shape | yes | |
vcpus | integer | yes | |
memory_gib | number | yes | |
scratch_gib | number | yes | |
offered | boolean | yes | |
suspendable | boolean | yes | |
ceiling_usd_micros_per_hour | integer | yes | The shape's list price for an hour at full use, in micros of USD: its vCPUs, memory and scratch disk at contracts/billing/machine-prices-v1.json's hourly prices. Billing charges what a Machine uses, never more than this. The same figure an exec or file answer names after a wake. |
Member
| Field | Type | Required | Description |
|---|---|---|---|
kind | one of "user" or "agent" | yes | |
subject | MemberSubject | yes | |
role | AccountRole | yes | |
name | string or null | yes | |
display_name | string or null | yes | |
created_at | Timestamp | yes |
MemberSubject
A person's user id, or agent.<agent id> for an Agent; the sub of its access tokens.
string
NextCursor
Opaque cursor of the next page; null on the last page.
string or null
Problem
| Field | Type | Required | Description |
|---|---|---|---|
type | string (uri) | yes | |
title | string | yes | |
status | integer | yes | |
code | string | yes | |
request_id | string | yes | |
detail | string | no | Explanation specific to this occurrence, when one exists. |
failure_code | TurnFailureCode or null | no | Present only on turn_failed; null for a failure recorded without a code. |
token_endpoint | string (uri) | no | Present only on exchange_required; where to exchange the key. |
errors | array of ValidationIssue | no |
Region
| Field | Type | Required | Description |
|---|---|---|---|
id | RegionId | yes | |
url | string (uri) | yes | The origin of the data plane in this region; a database's URL is this origin, the account id and the database name, and a bucket's is this origin and the bucket name. |
default | boolean | yes | Whether a database goes to this region when its creation names none. |
RegionId
string
Stream
| Field | Type | Required | Description |
|---|---|---|---|
name | StreamName | yes | |
region | RegionId | yes | |
url | string (uri) | yes | The 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_type | ContentType | yes | |
expires_at | Timestamp or null | yes | When 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. |
incarnation | string or null | yes | Ursula's Stream-Incarnation as a decimal; null while creating. It changes when a stream of the same name is deleted and created again. |
state | one of "creating", "active", "deleting" or "deleted" | yes | deleted appears only in the answer to the deletion that completed it. |
public_read | boolean | yes | Whether anonymous reads are served. |
created_at | Timestamp | yes | |
created_by | MemberSubject | yes | |
last_write_at | Timestamp or null | yes | The 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_bytes | object | yes | What the region's meter last saw stored; null when not yet reported or unavailable. |
stored_bytes.log | integer or null | yes | |
stored_bytes.snapshot | integer or null | yes | |
measured_at | Timestamp or null | no | When 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. |
writes | one of "accepting", "suspended" or null | no | Whether 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. |
StreamName
A stream's name (contracts/streams-databases/v1.json kinds.values.stream.name_pattern's capture group): the database name rule with at most 83 bytes, since its stream id is s. and the name. 1 to 83 lowercase letters, digits, dots, underscores and hyphens, starting and ending with a letter or digit, without ..; m., vol., s., session. and proc. are reserved, and streams and new are not names. It appears unencoded in the stream's URL after s..
string
StreamPrefix
A stream name prefix, under the name prefix rule (contracts/streams-databases/v1.json prefix); it selects every stream whose name starts with it.
string
StreamUsage
Every field of DatabaseUsageAmounts, and:
| Field | Type | Required | Description |
|---|---|---|---|
name | StreamName | yes | |
region | RegionId | yes | |
stream_created_at | Timestamp | yes | When Ursula created the stream version; with counted_since, the version the row is. |
counted_since | string | yes | The Ursula usage history the version began counting in, 16 hex digits. |
state | one of "active" or "deleted" | yes | |
created_at | Timestamp or null | yes | Null for a metered version the registry does not know. |
deleted_at | Timestamp or null | yes |
StreamUsagePage
| Field | Type | Required | Description |
|---|---|---|---|
period | string | yes | |
as_of | Timestamp or null | yes | The oldest meter checkpoint among the regions read; usage after it is not yet counted. Null before a region's first. |
currency | "usd" | yes | |
basis | "at_list_price_before_allowance_and_credit" | yes | |
pricing | object | yes | The list prices of contracts/billing/streams-prices-v1.json the values use. |
pricing.write_unit_bytes | integer | yes | |
pricing.write_micros_per_million_units | integer | yes | |
pricing.retention_micros_per_gib_month | integer | yes | |
pricing.retention_unit_bytes | integer | yes | |
pricing.retention_month_seconds | integer | yes | |
data | array of StreamUsage | yes | |
other | DatabaseUsageAmounts | yes | Metered usage outside the account's streams (its databases, session processing and anything unattributed), in every region read. |
next_cursor | NextCursor | yes | |
unavailable_regions | array of RegionId | yes | Regions whose usage could not be read; their streams and other are missing from this answer. |
Timestamp
string (date-time)
TurnFailureCode
Why a Turn failed. deadline_exceeded: it ran for the full execution window. start_timeout: it could not start before its start deadline. aborted: it was aborted. agent_retired: its Agent was deleted or retired. account_deleted: its account entered deletion. key_revoked: the key that submitted it was revoked. funding_exhausted: its account could not fund the runtime or inference. usage_store_unavailable: runtime usage could not be recorded, so the runtime was stopped. runtime_retired: its runtime stopped before the Turn ended. runtime_uncertain: the platform could not establish whether the prompt ran, so it was not replayed. pi_failed: the agent itself failed the Turn. legacy_operation_ended: a Turn created before admission records whose operation ended without it; only during the migration.
one of "deadline_exceeded", "start_timeout", "aborted", "agent_retired", "account_deleted", "key_revoked", "funding_exhausted", "usage_store_unavailable", "runtime_retired", "runtime_uncertain", "pi_failed" or "legacy_operation_ended"
UpdateDatabaseRequest
| Field | Type | Required | Description |
|---|---|---|---|
public_read | boolean | yes |
UpdateMemberRequest
At least one field.
| Field | Type | Required | Description |
|---|---|---|---|
role | AccountRole | no | |
name | AgentName | no | The Agent's new name; refused for a person. |
UpdateStreamRequest
| Field | Type | Required | Description |
|---|---|---|---|
public_read | boolean | yes |
Usage
| Field | Type | Required | Description |
|---|---|---|---|
period | string | yes | |
currency | "usd" | yes | |
total_micros | integer | yes | |
lines | array of object | yes | |
lines[].product | string | yes | |
lines[].region | string | yes | |
lines[].dimension | string | yes | |
lines[].model | string or null | yes | |
lines[].quantity | string | yes | Decimal quantity, as text. |
lines[].amount_micros | integer | yes |
Uuid
string (uuid)
ValidationIssue
| Field | Type | Required | Description |
|---|---|---|---|
field | string | yes | |
code | string | yes |