A sandbox is named by you and addressed by that name in every path. Names are unique within a workspace.
The sandbox object
{
"id": "sbx-01jbx3w2v8k6p3m9q0t7r4n5ce",
"name": "agent-1",
"organization": "wB7xKq2LmN9pR4tY",
"url": "https://agent-1-wb7xkq2l.nanite.page",
"url_settings": { "auth": "sandbox", "start": null },
"status": "running",
"held": false,
"labels": [],
"created_at": "2026-10-31T09:20:00.000Z",
"updated_at": "2026-10-31T09:20:00.412Z",
"last_running_at": "2026-10-31T09:20:00.412Z",
"last_warming_at": null,
"environment_version": "0.11.0",
"version": null
}| Field | Type | About |
|---|---|---|
id |
string | sbx- and 26 lowercase letters and digits. Never reused. |
name |
string | 1 to 63 lowercase letters, digits and dashes, starting with a letter or digit. |
organization |
string | The workspace that owns the sandbox. |
url |
string or null | The preview URL of the sandbox. |
url_settings.auth |
string | Who may open the URL: sandbox or public. |
url_settings.start |
array or null | The command the URL runs to bring a server up. See Preview URLs. |
status |
string | running, warm or cold. See Lifecycle. |
held |
boolean | Whether the sandbox is held, so nothing wakes it. |
labels |
array | Always empty for now. |
created_at |
string | When the sandbox was made, RFC 3339. |
updated_at |
string | When it last changed state. |
last_running_at |
string or null | When it last started running. |
last_warming_at |
string or null | When it last stopped. |
environment_version |
string or null | The version of the sandbox system it was made with. |
version |
null | Reserved. |
Create a sandbox
POST /v1/sandboxes| Field | Type | About |
|---|---|---|
name |
string | Required. 1 to 63 lowercase letters, digits and dashes, starting with a letter or digit. |
url_settings.auth |
string | sandbox (the default) or public. See Preview URLs. |
env |
object | Environment variables, name to value. See Environment and secrets. |
secrets |
object | Secrets, name to { "value", "hosts" }. |
curl -X POST $API -H "$AUTH" -d '{
"name": "agent-1",
"env": { "NODE_ENV": "production" },
"secrets": {
"OPENAI_API_KEY": { "value": "sk-...", "hosts": ["api.openai.com"] }
}
}'Answers 201 with the sandbox once it is up, usually with status running. If it could not be started, nothing is kept and the answer is 503 node_unavailable; try again.
| Status | Code | When |
|---|---|---|
| 400 | invalid_name |
The name breaks the rules above. |
| 400 | invalid_argument |
The body is not JSON, or url_settings, env or secrets is not valid. |
| 402 | insufficient_credits |
The workspace is out of credits. |
| 409 | name_taken |
A sandbox with this name exists. |
| 429 | sandbox_creation_rate_limited |
30 sandboxes were created in the last minute. |
| 429 | sandbox_limit_exceeded |
The workspace keeps as many sandboxes as it may. |
| 429 | concurrent_sandbox_limit_exceeded |
As many sandboxes as the workspace may run are running. |
| 503 | node_unavailable, no_capacity |
There is no room to start it now. Retry after Retry-After seconds. |
List sandboxes
GET /v1/sandboxes| Query | About |
|---|---|
prefix |
Only names that start with this. |
max_results |
1 to 500. Defaults to 50. |
continuation_token |
The next_continuation_token of the previous page. |
{
"sandboxes": [ { "name": "agent-1", "status": "warm", ... } ],
"has_more": false,
"next_continuation_token": null,
"running": 0,
"warm": 1,
"cold": 0,
"running_limit": 10,
"warm_limit": 100
}Sandboxes come sorted by name. running, warm and cold count every sandbox of the workspace in that state, not just this page. running_limit is how many may run at once and warm_limit is how many the workspace may keep in all.
Get a sandbox
GET /v1/sandboxes/{name}Answers the sandbox, or 404 sandbox_not_found. Getting a sandbox does not wake it.
Update a sandbox
PUT /v1/sandboxes/{name}{ "url_settings": { "auth": "public", "start": ["/srv/app/start"] }, "hold": false }Changes who may open the preview URL and the command it runs to start a server, and holds or releases the sandbox. Every field is optional; what you leave out stays as it is. Answers the sandbox.
Rename
{ "name": "web" }Gives the sandbox a new name, in any state. It keeps its id, disk, environment, secrets, checkpoints and schedules. Names are unique per workspace, so a name in use answers 409 name_taken.
The old name stops working at once: routes under it answer 404 sandbox_not_found, and its preview URL moves to the new name. The old address does not redirect, so a sandbox made later with the old name gets it.
Stop a sandbox
POST /v1/sandboxes/{name}/stopStops a running sandbox now instead of waiting for it to go idle, and answers the sandbox with status warm. Stopping ends every process in the sandbox; the disk stays as it is. Stopping a sandbox that is not running changes nothing, and stop never wakes one.
Hold a sandbox
PUT /v1/sandboxes/{name}{ "hold": true }A held sandbox stays stopped. A running one is stopped first. While it is held, exec, filesystem, checkpoint, proxy and port routes answer 409 sandbox_held, its preview URL answers 503, and its schedules record sandbox_held instead of running. Getting, listing, the env and secret routes and delete work as before. {"hold": false} releases it, and the next request wakes it as usual.
Hold a sandbox you do not want woken, such as one with a public URL, without deleting it. A held sandbox is billed for its disk like any stopped one.
Delete a sandbox
DELETE /v1/sandboxes/{name}Answers 204. The disk, the checkpoints, the environment and the secrets of the sandbox are removed for good.
Lifecycle
| Status | Meaning | Billed for |
|---|---|---|
running |
The machine is up and answering. | CPU, memory, disk |
warm |
Stopped, ready to start again quickly. | Disk |
cold |
Stopped for longer. Its disk is kept safe and is fetched back on wake, which takes a little longer. | Disk |
Idle stop
A running sandbox stops on its own after 30 seconds with nothing using it. These count as use:
- a request to one of its routes, while it runs,
- an open WebSocket, such as an exec session, a file watch or a proxy connection,
- an exec session whose process is still running, even with no client attached,
- CPU work: a sandbox using more than 2% of a core, such as a build or an agent started in the background,
- an outbound connection that is still open and that the sandbox sent on in the last 10 minutes, or that brought it data in the last 30 seconds, such as an agent waiting on a slow model reply or a download.
So a long build or an agent keeps the sandbox running while it works or waits on the network, even when nothing outside is attached. A process that only sleeps, or a server you start in the background that no one calls, does not: the sandbox stops and the process goes with it. An idle keep-alive connection can hold a sandbox up to 10 minutes after its last use; close it, or stop the sandbox, when you are done.
Waking
Exec, filesystem, checkpoint, proxy and port routes, the preview URL and schedules wake a warm or cold sandbox before they answer. Getting, listing, stopping and the env and secret routes never do, and nothing wakes a held sandbox.
A wake is refused like a create when the workspace is out of credits (402 insufficient_credits) or already runs as many sandboxes as it may (429 concurrent_sandbox_limit_exceeded).
Processes do not survive a stop. A woken sandbox boots fresh on the disk it had, so start your servers again after a wake.