Rules: requests

Last updated 2 November 2026

View .md

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.”

Check these rules before you open your Machine to callers: each keeps its requests answered and its bill small.

The examples use the database a Machine opens as Keep data in its database shows, and a node:http server.

Listen on 0.0.0.0, at a port you declare

Tonbo connects to your program from outside the Machine’s loopback, and serves only declared ports (see Ports and names).

Do
server.listen(8080, "0.0.0.0"); // the Machine was created with --port 8080
Don’t
server.listen(8080, "127.0.0.1"); // unreachable

Start listening within seconds

A request that wakes the Machine waits only so long for your program to listen, then is answered 503 (see The first request).

Do
const db = await open(process.env.TONBO_DATABASE_URL, settings);
server.listen(8080, "0.0.0.0");
warmCaches(db); // in the background, while serving
Don’t
const db = await open(process.env.TONBO_DATABASE_URL, settings);
await rebuildIndexFromScratch(db); // minutes: every waking request times out
server.listen(8080, "0.0.0.0");

Keep a port private unless it must be public

Anyone can call a public port and wake the Machine, Tonbo limits none of those requests, and every second awake is billed (see Public ports and the example).

Do
tonbo machine create tools --image registry.example.com/you/tools:1 --shape s-1 --port 8080
Don’t
tonbo machine create tools --image registry.example.com/you/tools:1 --shape s-1 --port 8080:public # an internal tool anyone can wake

Check your own users’ credentials on a public port only

On a private port Tonbo checks the caller’s key and removes Authorization before your program sees it; on a public port the header passes through (see Private ports).

Do
// On a public port: your program checks its own users.
const user = await verifyUser(req.headers.authorization);
Don’t
// On a private port: Tonbo removed the header.
const user = await verifyUser(req.headers.authorization); // always undefined

Call a private port with a personal key or an exchanged token

A private port takes a member’s personal key, or an access token exchanged from an Agent’s key, and refuses the Agent’s key itself (see The token exchange).

Do
curl -H "Authorization: Bearer $TONBO_API_KEY" https://tools-<account>.tonbo.sh/
Don’t
curl -H "Authorization: Bearer $AGENT_KEY" https://tools-<account>.tonbo.sh/ # 401 exchange_required

Retry a 503 after its Retry-After

A wake still under way, an image still being pulled and a full host answer 503 with Retry-After, and the request did not run (see Troubleshooting); curl --retry waits as told.

Do
curl --retry 5 https://tools-<account>.tonbo.sh/
Don’t
curl https://tools-<account>.tonbo.sh/ || exit 1 # gives up on a Machine that is waking