Box states
When a box freezes, wakes and is stopped for good, what counts as use, what keeps a box awake, and how the app shows whether the conversation using a box is still at it.
claimed → ready → takeover (optional) → stopping → terminated
↕
frozen
Idle rules, as the sandbox_start description states them:
An idle box is frozen after 10 minutes without a call, with /work kept; the next call thaws it. A frozen box is stopped for good 24 hours after its last use. idleTimeoutMin sets your own limit instead of these: the box stops for good after that many minutes without a call, frozen or not. It is capped at 10080 minutes (7 days). An attached phone freezes and thaws with its box (an iPhone restarts its apps); while frozen it holds no device slot and is not billed. A pending sandbox_review keeps neither the box nor its phone awake: they freeze and are stopped by these same rules, and opening the review wakes a frozen box. Commands started with background: true (a dev server, a long build) count as activity for up to 1 hour after your last call; after that a box freezes anyway (they carry on when the next call thaws it). Requests through the box's URLs count as activity for up to 2 hours after the last call; after that the box freezes, and the next page load in a browser wakes it again (a few seconds). Background fetches from an open tab don't wake it. With no room on any host it fails with "no box capacity right now" (HTTP 503 over REST); waitForCapacitySec waits for room instead.
In detail:
- Use: where this page says use (the last use, for one), it means a tool call that acts on the box, or a wake. The calls that act on a box are
sandbox_start,sandbox_exec,sandbox_sync,sandbox_get(sosandbox_pulltoo),sandbox_shot(except capturing several pages withurls),sandbox_scene,sandbox_wire,sandbox_procs, andsandbox_secretsandsandbox_buildfor a box; a person's takeover (connecting to the box's screen, typing and clicking on it) and a link connection from another box count too.sandbox_status,sandbox_list,sandbox_sayandsandbox_feedback, which only read state or leave a message, do not count; nor dosandbox_review,sandbox_device,sandbox_takeoverandsandbox_shotwithurls, though on a frozen box they wake it first (exceptsandbox_devicewithlist), and that wake counts. The last use is when the last of these calls started or ended, or the last wake happened, whichever is later:lastUsedAtinsandbox_statusandsandbox_list. A call that acts on the box counts from the moment it starts, so the box does not freeze under asandbox_syncorsandbox_getthat is still running (a foregroundsandbox_execkeeps it awake for as long as it runs); and a call of any kind that arrives while the box is being frozen waits the few seconds the freeze takes, then wakes the box and runs, instead of failing. - A box is
frozenafter 10 minutes without activity: its memory is snapshotted,/workis kept and it stops billing box time. Activity is use (previous item), or a request through one of the box's URLs (each HTTP request, and a WebSocket once, when it opens) for up to 2 hours after the last use, so a person usingwebUrlkeeps the box awake for that long; the app's live view of the screen and the live thumbnails in its box list do not (both are streamed while someone looks, not stored, unlike the box pictures under Credits). After those 2 hours, requests through the URLs no longer keep it awake: a person still using a page may see the box freeze mid-session, and their next page load wakes it (below). A box does not freeze while a person has taken it over, a foreground command is running, or another awake box has a link connection open to it, nor while it is recording, until a full hour has passed since the last use; after that, once nothing else listed here keeps it awake, the recording is stopped without uploading it (seesandbox_shot). A command started withbackground: true(a dev server, a long build) keeps the box awake only until 1 hour after the last use; after that the box freezes anyway, and the process carries on when the next call thaws it.sandbox_statusgivesfreeze:at, when the box will freeze if nothing changes, andblockedBy[], what keeps it awake right now (background,urlandrecordingwith theuntilthey count to;takeover,foreground,linkandphoneuntil they end, with noat). A box stillreadywell past 10 idle minutes is held by one of these. - A frozen box is woken, in a couple of seconds (about a minute when phones are attached, since they come back first), by any tool call naming it except
sandbox_status,sandbox_say,sandbox_feedback,sandbox_stopandsandbox_devicewithlist, by a link connection from another box, by a person loading one of its pages in a browser (next item), by the Show screen button on the box's page in the app for whoever is signed in to the account (the page has it when something was on the box's screen as it froze:posterUrlin Which conversation is using a box), or byPOST /v1/boxes/{id}/wakewith an OAuth access token or API key. A wake counts as use. Waking needs credits on the account (402 otherwise).sandbox_stopworks on a frozen box too. Nothing is lost. - Loading a page of a frozen box in a browser wakes it: a
GETorHEADwithSec-Fetch-Mode: navigate(a typed URL, a link, a reload), or, from a browser that sends noSec-Fetch-Mode, one whoseAcceptincludestext/html. The edge asks for the box to be thawed and answers with a small page, "Waking this box… This page reloads by itself in a few seconds." (503,Retry-After: 3,Cache-Control: no-store); the page reloads itself until the app shows, about 10 seconds in all. The wake counts as use. Each box gets at most one wake request every 15 seconds; page loads in between get the same page.- Nothing else through the URLs wakes it:
fetchand XHR from an open page, images and scripts, WebSockets andPOSTs get 503{"error":"box is frozen","status":"frozen"}. A tab left open and polling neither wakes the box nor keeps it awake past the 2 hours above. - When the account is out of credits, the page says "This box is paused" (402) and does not reload by itself: add credits in the app, then reload.
- A stopped box does not come back this way: its URLs answer 503
box is terminated, and a new box has new URLs.
- Nothing else through the URLs wakes it:
- The box's URLs stay the same across freeze and thaw; only a new box has new ones.
- The first launch of a large program after a thaw is slower than usual, often several times (an Electron app that opens in 3 seconds can take 12): its files are no longer in the box's memory cache. Launch it once to warm it up before you time a cold start or record one.
- After a thaw, boxd closes the connections to environment addresses and links that were open before the freeze (it notices the thaw within about 15 seconds); connections opened after the thaw stay. Programs have to reconnect: database pools usually do on their own, and long-lived clients should retry.
- A frozen box is stopped for good (
/workis gone) 24 hours after its last use, or after it was frozen if that is later, so a box frozen because credits ran out keeps the full 24 hours. A box handed over withsandbox_reviewand waiting under Ready for you freezes and is stopped the same way: a pending review keeps nothing awake. The person opening the review wakes it while it is frozen; once it has been stopped, the review is over, and the version has to be handed over again on a new box. After it stops, the app lists it under Stopped (last 7 days), with screenshots and recordings available until seven days after capture. A box withidleTimeoutMinis stopped after that many minutes without use instead, frozen or not; a page load that wakes it restarts the count, like any wake. stopsAtinsandbox_statusandsandbox_listis when these rules stop the box for good unless something uses it before then (absent when they never will). From 30 minutes beforestopsAt, every tool result in a conversation that used the box, or that names it, ends with a line such asbox <id>: the idle rules stop it for good at <time> (in 25 minutes) unless something uses it before then, and /work goes with it.; a call that acts on the box pushesstopsAtback,sandbox_statusandsandbox_listdo not. Fetch what you still need before then.- A frozen box these rules stopped keeps its frozen copy for 24 hours more:
restorableUntilinsandbox_status, and insandbox_listwithall: true, says until when, and a call naming the stopped box says how to bring it back.sandbox_start { "restore": "<id>", "goal": "<its goal>" }returns that same box as it froze, with/work, its running programs, its id and its URLs (sandbox_start); attached phones are not kept. A box stopped withsandbox_stopkeeps no copy. - A person trying a box needs nothing from you: their use of its URLs keeps it awake for up to 2 hours after the last use. After that it freezes even while they use it; their next page load wakes it in about 10 seconds, and that wake counts as use, so another 2 hours start (the same after lunch). Set
idleTimeoutMinwhen you want a limit of your own. To look at a page other than the scene yourself,sandbox_shot { "id": "<id>", "target": "url", "url": "http://127.0.0.1:8082/" }opens it in a fresh Chromium in the box and returns a screenshot;curlinsandbox_execgives you the HTML. - An attached phone freezes with its box: it freezes only when the box is about to, so whatever keeps the box awake keeps its phones running too; the box freezes once its phones are frozen; a frozen phone holds no device slot and does not bill; and the call that thaws the box brings it back attached with the same
deviceIdandserial(an Android emulator resumes from a snapshot of its memory; an iPhone simulator boots again with its apps and data kept, apps restarted). If its device host has no free slot at that moment, it stays frozen until one frees up (sandbox_device). Aboxsandbox_reviewof its app does not change this: while it waits for the person, the phone freezes with the box as usual, and comes back with the box when the person opens the review.
A box stopped by these rules has a statusReason that says so, such as frozen and unused for … or unused for …, over idleTimeoutMin ….
While a person has the box's screen (a takeover, or a box review they opened), sandbox_sync and sandbox_exec (unless readOnly) answer 423 with since when the person has it, why (they took it over themselves, or a sandbox_takeover asked them to, or they are trying your review) and the latest time it comes back. sandbox_get, sandbox_procs, sandbox_shot of the screen, a window or a URL, sandbox_status and sandbox_say still work (a box on an older image also answers 423 to sandbox_get and sandbox_shot, and says so). To keep working meanwhile, start another box and sync your code there.
Any state can turn into interrupted: the host machine under it is gone (reclaimed by the cloud, or failed). sandbox_status reports the reason; the next tool call on that box returns the same. Start a new box and rerun. When the cloud reclaims a machine with notice, its boxes are frozen and saved first, and the next call thaws them on another host, so they are not interrupted at all. For a box that could not be saved whole, its /work may still have been, and the error then says Its /work was saved at <time>: sandbox_get or sandbox_pull with path /work on the interrupted box returns that copy as work.tar.gz (without node_modules, caches and files over 64 MiB; changes after that time are lost). Nothing else on an interrupted box survives.
Which conversation is using a box
The stdio adapter (parallelsandbox-mcp 0.3.0 or later) tells ParallelSandbox whether its conversation is still open:
- When it starts, it picks a random id and sends it as the
X-Psbx-Agentheader on every MCP and REST call. - After the first tool call it sends
POST /v1/agents/<id>/heartbeatwith{"client": "<MCP client name>"}every 60 seconds. - When the conversation closes (stdin ends, or SIGTERM, SIGINT or SIGHUP) it sends
POST /v1/agents/<id>/leave. A conversation that ends without one (kill -9, a laptop asleep) counts as gone 3 minutes after its last heartbeat. A heartbeat after a leave counts the same id as back. - Nothing else is sent: no prompt, no transcript.
A box remembers the last agent id that called a tool on it; a call without the header keeps the previous one. An id is letters, digits, - and _, 1 to 64 characters: the two endpoints answer anything else with 400 agent id: letters, digits, - and _ only, at most 64, and a header that breaks the rule is ignored. A client that calls the HTTP endpoint or the REST API directly can do the same: send X-Psbx-Agent itself and call both endpoints with an OAuth access token or API key (each returns {"ok":true}). A client that sends neither leaves a box's AI state to its idle time alone: it is never left.
GET /v1/boxes, sandbox_list and sandbox_status give each live box (starting, ready, taken over, frozen) an agent object, { "state": "working", "idleSec": 42 }; stopping, stopped and interrupted boxes have none. In sandbox_list and sandbox_status it also has thisConversation: true when the box's last agent id is the calling conversation's. idleSec is the seconds since the box was last used (a tool call, a wake, a person operating its screen, a link connection) or started. state is checked in this order:
left: the box's last agent sent leave, or has sent no heartbeat for over 3 minutes.idle: the box has been unused for 1 hour or more, whether or not its conversation is still open.away: the box is frozen, or has been unused for the freeze time (10 minutes), and the conversation is still there.working: otherwise.
The same list says what is on the box's screen:
screenInUse: the virtual display shows something (a browser, an emulator); false on a box that only runs builds or tests.screenActive: true when the box isreadyandscreenInUseis true, whether or not the screen changed recently: a box whose screen sits still while the AI runs tests counts too.posterUrl: a picture of the screen as it was when the box froze (presigned, valid 1 hour), given only when the screen showed something then. A box that only runs builds or tests gets none, instead of a black desktop. Each freeze replaces the earlier poster, keeping only the newest picture (Credits). Once the box is stopped,GET /v1/boxes?all=1still gives the newest one.
The app sorts live boxes with these fields:
- Ready for you: boxes waiting for the person, with a
sandbox_reviewcard or asandbox_takeoverwaiting for them. - AI is testing: only boxes with
screenActivetrue andagent.stateworkingthat are not waiting for the person. - All sandboxes: active boxes and boxes stopped in the last seven days, each labeled AI is using it (
working), AI is busy elsewhere (away), AI stopped · conversation closed (left) or AI stopped · unused for 1 hour (idle). A box whose AI stopped and that is not waiting for the person has the Continue and Shut down buttons (Picking up a box another conversation left).
Frozen is no longer shown to the person as a state: in the list a frozen box is AI is busy elsewhere or AI stopped, its page says The AI isn't using this box, and the next tool call thaws it.
Every tool and topic is listed in the tool reference.