Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Leases

Every running sandbox has a lease: a hard deadline after which it is stopped. There is no fixed maximum lifetime. A run that needs days renews its lease for as long as it needs.

The contract

  • The lease is set when you create the sandbox. lease_seconds sets it, between 60 and 604800 (7 days), and the default is 3600. The clock starts when the sandbox starts running.
  • Only an explicit renewal extends it. Running commands, uploading files, open SSH or preview sessions, and polling the sandbox never extend it. Renew the lease itself.
  • The host enforces the lease locally. The deadline is kept on the machine that runs your sandbox, which stops the sandbox when the deadline passes even if runner's API is down. Expiry is reliable whether or not anything else is up.
  • Renewal is deterministic. Every renewal moves the lease to a new generation with a new deadline, and is acknowledged only after the host has stored it. An acknowledged renewal is never undone by an expiry that was already under way. A renewal that arrives after the host has already acted on the deadline is refused with lease_expired (HTTP 410), and the sandbox is gone.
  • Outage grace. If runner's control plane is unreachable from the host when your lease runs out, the host grants one bounded grace period (10 minutes by default) before stopping the sandbox, so our outage does not end your run on the spot. The grace is granted at most once per lease generation, survives a restart of the host's agent, and is not extended because the outage goes on. Renew during the grace, once the API answers again, and the sandbox continues. Do not plan on the grace: it exists for our failures, not as extra lease.
    "Unreachable" is the host's own judgement. The control plane contacts every host every 10 seconds, and a host that has heard nothing from it for 30 seconds treats it as down. So an outage that starts less than about 30 seconds before your deadline may not earn a grace. Neither does a failure that only affects the public API while the control plane still reaches the hosts.
  • A running sandbox always uses its slots, including during a grace period, until it has stopped. It stops counting against your account's slots only once the host confirms it is gone.
  • A sandbox dies with its host. There is no pause, resume or live migration yet, so if the machine running your sandbox fails, the sandbox is lost whatever its lease says. Keep anything you cannot afford to lose outside the sandbox.

Renewing

POST /v1/sandboxes/{id}/lease Authorization: Bearer <key with sandboxes:write> {"seconds": 7200}
{"generation": 3, "expires_at": "2026-10-19T14:02:11Z"}
seconds is counted from now, not from the current deadline, and must be between 60 and 604800. Retrying a renewal is safe. A sandbox that is not running answers invalid_argument. One whose lease has already run out answers lease_expired.
GET /v1/sandboxes/{id} shows the current lease as "lease": {"generation": 3, "expires_at": "..."} while the sandbox is running.

Warnings

About 5 minutes before a lease runs out, runner sends one warning per lease generation. Renewing starts a new generation, which gets its own warning. The warning is delivered in two ways:
  • A lifecycle event, "kind": "lease_warning", in GET /v1/sandboxes/{id}/events. The SDKs surface it.
  • A webhook, if the account has one. Set it with PUT /v1/account/webhook {"url": "https://..."}, using a key with the keys scope. The reply carries the signing secret, shown only that once. An empty url removes the webhook. The URL must be https and must resolve to a public address.
    {"type": "sandbox.lease_warning", "sandbox_id": "sbx_...", "lease": {"generation": 3, "expires_at": "2026-10-19T14:02:11Z"}}
    Each delivery carries Runner-Signature: t=<unix seconds>,v1=<hex>, where v1 is the HMAC-SHA256 of <t>.<raw body> under your secret. Verify it, and refuse old timestamps. A failed delivery is retried a few times, then dropped.
Warnings are best-effort. They come from runner's control plane, so during an outage of it you get none, while the host still enforces the deadline. Do not make a warning the only thing that triggers your renewal. Renew on your own schedule, well before expires_at.

How a lease-stopped sandbox looks

Once the host has stopped a sandbox, GET /v1/sandboxes/{id} shows "state": "terminated" with "error_code": "lease_expired", usually within seconds. The sandbox's event history ends with a terminated event carrying the same code, and it is kept for 30 days.