Sandboxes
How sandbox lifecycle, TTL, templates, metadata, and injected environment context work in CrowNest.
A sandbox is an isolated live execution environment. You create one from a template, run commands and manage files inside it, and it's destroyed when you kill it or its TTL expires. Sandboxes are the unit of isolation, billing, and lifecycle in CrowNest.
Lifecycle and statuses
Every sandbox moves through a fixed set of statuses. The status field on
the sandbox object always reflects the current state.
| Status | Meaning |
|---|---|
creating | CrowNest is provisioning the sandbox. |
starting | The environment is booting. |
ready | The sandbox is available for work. |
running | Ready, with a command actively executing. |
idle | Ready, with no active work. |
expiring | Cleanup has begun; new operations are rejected. |
destroyed | The sandbox is gone. The record remains queryable. |
failed | The sandbox could not start or stopped abnormally. |
running and idle are derived from ready: a sandbox is running while
it has an active command and idle otherwise.
Destroyed sandboxes carry a destroyedReason:
destroyedReason | Meaning |
|---|---|
user_killed | You deleted the sandbox via the API, SDK, or CLI. |
ttl_expired | The sandbox reached its expiresAt time. |
idle_expired | The sandbox was reclaimed after sitting idle. |
platform_cleanup | CrowNest removed the sandbox during maintenance. |
List endpoints return live sandboxes by default. Pass include=historical
to also get destroyed and failed records.
TTL
Every sandbox has a time-to-live. You request it as ttlMs (milliseconds)
when creating the sandbox, and responses surface the resolved deadline as
expiresAt (ISO 8601). The API default is 3600000 ms (1 hour). Maximum TTL
varies by plan tier: 1 hour for Free, 24 hours for Builder, 72 hours for Scale,
and 168 hours for Enterprise. Requesting more returns sandbox_ttl_exceeded.
Read quotas from GET /v1/usage for current limits.
You can reset a live sandbox's remaining TTL with
POST /v1/sandboxes/{sandboxId}/extend, client.sandboxes.extend(...),
sandbox.extend(...), or crownest sandboxes extend <sandbox-id> --ttl-ms <ms>.
Each extend accepts up to 86400000 ms (24 hours), and the total session is
capped at 24 hours from creation.
When a sandbox expires:
- Running commands move to status
killedwithkilledReasonsandbox_destroyed. - The filesystem is gone unless you exported files as artifacts first.
- The sandbox record remains with status
destroyed. - Billing stops at
expiresAt.
Important
Export anything you need to keep as an artifact before the sandbox expires. The workspace is not preserved.
Templates
A template is the user-facing slug that selects the sandbox environment. Two curated templates are available:
| Template | Contents |
|---|---|
python-node | Python, Node.js, package managers, shell tools, and repo-runner basics. |
node | Node.js 22 with npm for JavaScript and TypeScript repositories. |
python-node is also the default when you omit template. It includes
bash, git, tar, gzip, curl, jq, rg, node, npm, corepack,
pnpm, python3, python3 -m pip, and uv. uv is the recommended Python
package path, but pip-shaped repositories still work.
Additional curated templates and custom Dockerfile templates are planned.
Requesting a slug outside the discovered catalogue returns invalid_request.
Each template resolves to a TemplateVersion, an immutable resolved environment.
The sandbox stores the templateVersionId that was resolved at creation, so
the environment never changes underneath a running sandbox. You can also pass a
templateVersionId directly when creating a sandbox to pin a specific
version.
Metadata
Metadata is a flat string map you set at creation to label sandboxes for correlation, filtering, and display. It's never used for authorization, and you must not store secrets in it.
Limits:
- Maximum 16 keys.
- Keys up to 64 characters; values up to 512 characters.
- Total size up to 4 KB.
- Allowed characters:
a-z A-Z 0-9 _ - . :.
Injected environment context
CrowNest injects a small set of non-secret environment variables into every sandbox so processes can discover their own context:
| Variable | Value |
|---|---|
CROWNEST | 1 |
CROWNEST_SANDBOX_ID | The sandbox ID. |
CROWNEST_PROJECT_ID | The project ID. |
CROWNEST_ORG_ID | The organization ID. |
CROWNEST_TEMPLATE_ID | The template ID. |
CROWNEST_TEMPLATE_VERSION_ID | The resolved TemplateVersion ID. |
CROWNEST_WORKSPACE | /workspace |
The CROWNEST prefix is reserved: setting any CROWNEST* key in command
env is rejected with reserved_env_key. Environment values you pass to
commands are ephemeral and never persisted.
Next steps
- Commands — run processes inside a sandbox.
- Files and the workspace — read and write files
under
/workspace. - Artifacts — export files before the sandbox expires.
- SDK quickstart — create your first sandbox.
- Sandboxes API reference