Quickstart: HTTPS service
Last updated 3 November 2026In Getting started
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.”
Run a public image as an HTTPS service from your laptop: create a Machine, call it, put it to sleep, wake it and delete it, in a few minutes.
Each step shows the tonbo CLI and the same request to the Management API over HTTPS. You need curl and jq, and Node.js 22 or later for the CLI. The quickstart uses a few cents of your account’s monthly free usage.
Sign in
Sign in at tonbo.dev with GitHub or Google. A new account asks you to choose a username: it names your personal account, which holds your databases, streams and keys, and appears in the console’s addresses. You can change it once every 90 days.
Install the CLI or create a key
npm i -g @tonbo/cli@^0.9
tonbo logintonbo login signs you in through a browser on the same machine. Over SSH, or on a machine without a browser, it prints a short code instead: open https://tonbo.dev/cli/device in a browser on any computer where you are signed in, enter the code, check the computer name and approve (tonbo login --device asks for the code anywhere). For non-interactive use, such as CI, set TONBO_API_KEY to a key that acts as you and is not narrowed, created in the console under API keys, and the CLI uses it instead.
Create a key in the console under API keys, without narrowing it, and keep it in your shell; every request sends it as Authorization: Bearer $TONBO_API_KEY (see API keys and tokens):
export TONBO_API_KEY=tbo_...Create a Machine
tonbo machine create hello --image public.ecr.aws/docker/library/nginx:1.28-bookworm --shape s-1 --port 80:public --region us-east-1 --wait--wait waits until the Machine is active, then prints it: Power is asleep, since a new Machine waits asleep for its first request, and HTTPS is its address. If the creation fails, it says why.
curl -sS -i https://api.tonbo.dev/v1/machines \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"hello","image":"public.ecr.aws/docker/library/nginx:1.28-bookworm","shape":"s-1","region":"us-east-1","ports":[{"port":80,"access":"public","default":true}]}'
until curl -sS https://api.tonbo.dev/v1/machines/hello -H "Authorization: Bearer $TONBO_API_KEY" \
| jq -e '.data.state == "active" or .data.state == "failed"' >/dev/null; do sleep 2; done
curl -sS https://api.tonbo.dev/v1/machines/hello -H "Authorization: Bearer $TONBO_API_KEY" \
| jq '.data | {state, failure, power: .status.power, https: .hostnames.https}'The create answers 202 with Location and Retry-After: 2. The loop does what the CLI’s --wait does: it reads the Machine every 2 seconds until its state is active, or failed with a failure that says why. Then status.power is asleep, since a new Machine waits asleep for its first request, and hostnames.https is its address. The Idempotency-Key makes a create you send again return the same Machine.
Tonbo pulls the image before the Machine is active, usually in under a minute.
- The image is nginx, built for
linux/arm64. --shape s-1(shape) is the smallest shape, 1 vCPU and 2 GiB of memory. The API requires a shape; without--shapethe CLI takes m-8, at up to $0.6888 an awake hour against $0.0861.tonbo machine shapeslists them all (GET /v1/machine-shapes).--port 80:public(aportsentry withaccesspublic) serves nginx’s port 80 to anyone at the Machine’s name. Making a port public needs an owner or admin of the account, and in your personal account that is you.--region us-east-1(region) names a region where Machines run.
A member of an organization without owner or admin rights creates it with a private port instead, and Call it sends a key:
tonbo machine create hello --image public.ecr.aws/docker/library/nginx:1.28-bookworm --shape s-1 --port 80 --region us-east-1 --waitcurl -sS -i https://api.tonbo.dev/v1/machines \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"hello","image":"public.ecr.aws/docker/library/nginx:1.28-bookworm","shape":"s-1","region":"us-east-1","ports":[{"port":80,"access":"private","default":true}]}'Call it
URL=$(tonbo machine show hello --json | jq -r .hostnames.https)
curl -i --retry 5 "$URL/"URL=$(curl -sS https://api.tonbo.dev/v1/machines/hello -H "Authorization: Bearer $TONBO_API_KEY" | jq -r .data.hostnames.https)
curl -i --retry 5 "$URL/"The first request wakes the Machine, which starts nginx in seconds, and the answer is nginx’s welcome page. If it takes longer, the request is answered 503 with Retry-After, and --retry sends it again (see the Machine is still starting).
On a private port, send a key of your account:
Create a key, keep it in a shell variable and send it. A variable named TONBO_API_KEY would override your tonbo login for the CLI too:
tonbo api-key create hello-quickstart --expires-in 15_days
KEY=tbo_...
curl -i --retry 5 -H "Authorization: Bearer $KEY" "$URL/"The key the requests above send reaches a private port as it is:
curl -i --retry 5 -H "Authorization: Bearer $TONBO_API_KEY" "$URL/"You are charged for what nginx uses while the Machine is awake. Asleep, it pays only for what its database stores, and nginx stores nothing there (see Pricing).
Put it to sleep and wake it
tonbo machine sleep hello --wait--wait waits until Power is asleep.
curl -sS -X POST https://api.tonbo.dev/v1/machines/hello/sleep -H "Authorization: Bearer $TONBO_API_KEY"
until curl -sS https://api.tonbo.dev/v1/machines/hello -H "Authorization: Bearer $TONBO_API_KEY" \
| jq -e '.data.status.power == "asleep"' >/dev/null; do sleep 5; doneThe sleep answers 202 with Retry-After: 5 while the Machine goes to sleep, or 200 when it is already asleep; the loop reads it until status.power is asleep.
Call it again, and the request wakes it: neither the CLI nor the API has a wake operation. The wake starts nginx fresh (see What a wake starts with):
curl -i --retry 5 "$URL/"Left alone, it goes to sleep by itself, at most 10 minutes after its last request, and Tonbo may put it to sleep after about 2 minutes, since an idle nginx uses almost no CPU or network (see Sleep, wake and stop).
Delete it
tonbo machine delete helloType hello to confirm.
curl -sS -X DELETE https://api.tonbo.dev/v1/machines/hello -H "Authorization: Bearer $TONBO_API_KEY"It answers 202 and asks for no confirmation; then the Machine is gone.
Its disks and database go with it. If you created a key for a private port with the CLI, revoke it with the id tonbo api-key create printed:
tonbo api-key revoke <key-id> --yesEvery other operation, with the CLI and the API side by side, is on Manage Machines.
Next steps
- Run your own imageBuild your own image, and run it with your command and env.
- Keep data in its database and VolumeKeep what must last in the Machine’s own database.
- Serve requestsPrivate and public ports, keys, and what reaches your program.
- Rules for MachinesWhat to do and what not to, before you rely on a Machine.