Rules: requests
Last updated 2 November 2026
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).
server.listen(8080, "0.0.0.0"); // the Machine was created with --port 8080server.listen(8080, "127.0.0.1"); // unreachableStart 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).
const db = await open(process.env.TONBO_DATABASE_URL, settings);
server.listen(8080, "0.0.0.0");
warmCaches(db); // in the background, while servingconst 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).
tonbo machine create tools --image registry.example.com/you/tools:1 --shape s-1 --port 8080tonbo machine create tools --image registry.example.com/you/tools:1 --shape s-1 --port 8080:public # an internal tool anyone can wakeCheck 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).
// On a public port: your program checks its own users.
const user = await verifyUser(req.headers.authorization);// On a private port: Tonbo removed the header.
const user = await verifyUser(req.headers.authorization); // always undefinedCall 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).
curl -H "Authorization: Bearer $TONBO_API_KEY" https://tools-<account>.tonbo.sh/curl -H "Authorization: Bearer $AGENT_KEY" https://tools-<account>.tonbo.sh/ # 401 exchange_requiredRetry 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.
curl --retry 5 https://tools-<account>.tonbo.sh/curl https://tools-<account>.tonbo.sh/ || exit 1 # gives up on a Machine that is waking