Quickstart
Create a sandbox, run a command, and terminate it.
API reference
Endpoints and fields for the
/v2/sandboxes resource.When to use a sandbox
Use a sandbox when you need a clean, disposable environment for a short task:- An AI agent needs to execute the code it writes.
- Your application runs code or commands supplied by end users.
- You want to test a script or package in isolation before running it elsewhere.
Isolation
Every sandbox runs under gVisor, a user-space kernel that intercepts the container’s system calls. Code inside a sandbox can’t reach the host machine or other tenants’ sandboxes, so you can run code you don’t trust.Images and templates
You can start a sandbox in three ways:- Default image: send an empty request body (
{}) and the sandbox runs Runpod’s default sandbox image. - Container image: set
imageto any public image, for examplepython:3.12-slim. For a private image, also setregistryto the ID of one of your saved container registry credentials (from/v2/registries). - Template: set
templateIdto a sandbox template. Runpod provides curated templates, such as Ubuntu and Harbor.
image and templateId can’t be used together.
If you create a sandbox from an image without a start command, the container runs a keepalive process so it stays up for you to run commands in. To run your own main process, set cmd (and optionally entrypoint) in exec form, for example ["python", "-m", "http.server", "8080"].
Lifecycle
A sandbox moves through these states:POST /v2/sandboxes returns 201 with the new sandbox, usually still in the CREATING state. Poll GET /v2/sandboxes/{id} until state is RUNNING before you send commands.
Retry creates safely
Send anIdempotency-Key header with each create request. If the response is lost and you retry with the same key and the same body, the API returns the sandbox the first request created instead of creating (and billing for) a second one.
If the first create failed, for example because no capacity was available, that key is spent: retrying with it returns 409. Retry a failed create with a new key.
Termination is final
A terminated sandbox can’t be restarted. Its record stays readable throughGET /v2/sandboxes/{id}, with terminationReason and terminatedAt set, so you can see why and when it stopped. To run more work, create a new sandbox.
Terminating a sandbox that is already terminated succeeds, so it’s safe to retry DELETE /v2/sandboxes/{id}.
Timeouts
Every sandbox has two clocks. Whichever runs out first terminates the sandbox and stops billing:- Idle timeout (
idleTimeoutSeconds): how long the sandbox can go without activity. Running a command and keeping a log stream open both count as activity. The deadline is reported inidleExpiresAt. - Maximum lifetime (
maxLifetimeSeconds): a hard ceiling on total lifetime, counted from creation. The deadline is reported inexpiresAt.
If you omit a value, the default applies. Values above the maximum are clamped to it, and idle timeouts under 90 seconds are raised to 90. Check
idleTimeoutSeconds and maxLifetimeSeconds in the response to see the values actually applied.
You can change both while a sandbox is running:
- Extend a sandbox’s lifetime with
POST /v2/sandboxes/{id}/extend. - Change its idle timeout with
PATCH /v2/sandboxes/{id}.
Network access
By default, a sandbox has open outbound internet access. Code inside it can reach any host on the internet, for example to install packages or call external APIs. Restricting outbound traffic is opt-in and is not yet available to all accounts. When it is, you’ll be able to setegressMode on create to DENY_ALL (no outbound access) or ALLOW_LIST (only the hostnames in egressAllowlist). Until restriction is enabled for your account, any mode other than ALLOW_ALL returns 400.
Exposed ports
To reach a service running inside a sandbox, list its ports inports when you create the sandbox (up to 15):
httpports are reached through the Runpod proxy at theurlreturned in the sandbox’sportslist. Treat the URL as opaque.tcpandudpports are reached directly at the returnedipandpublicPort.
Storage
Each sandbox has an ephemeral container disk, 10 GB by default (setdisk to change it). It’s deleted when the sandbox terminates.
To keep data, mount an existing volume with mounts:
mounts.network: a network volume, mounted at/workspaceby default. Place the sandbox in the volume’s data center.mounts.global: a global volume, mounted at/workspace-globalby default.
Connect over SSH
SetstartSsh: true on create to inject the SSH public keys registered on your account. Connect using the details in the sandbox’s ssh field. For a direct connection, also expose 22/tcp in ports. Only images that start sshd from the PUBLIC_KEY environment variable support this; all Runpod official images do.
Environment variables and secrets
Pass environment variables inenv. You can reference a Runpod secret with {{ RUNPOD_SECRET_name }}; a create that references a secret you can’t access is rejected.
Compute and pricing
Sandboxes run on CPU compute. Set the CPU flavor and vCPU count incpu, or omit it to use the standard sandbox configuration. Memory and container disk limits scale with the flavor. The cpu and compute fields in the sandbox response show what’s backing it.
Sandboxes are billed per second from creation until termination, at the rate shown in compute.costPerHr (USD per hour). Your account needs enough balance to start a sandbox; otherwise, create returns 402.
Labels
Attachlabels (string key-value pairs) when you create a sandbox to track which job, user, or environment it belongs to. You can filter GET /v2/sandboxes by one or more labels, written as key=value.
Known limitations
These limitations reflect current behavior and will change as the feature matures:- The first command can return
409.RUNNINGmeans compute is allocated, not that the container has finished starting. Until it has, commands and log streams return409with codesandbox_starting. Retry after a short delay. - Commands are capped at about 4 seconds. A command still running at the cap is stopped and returns
exitCode: null. For longer work, run the command withbackground: true, write its output to a file, and read the file with a later command. - A sandbox can show
RUNNINGafter its container exits. If a command returns409with codecontainer_exited, terminate the sandbox and create a new one. /tmpuses memory. Writing large files to/tmpcounts against the sandbox’s memory and can stop it. Write large files elsewhere, such as your home directory or a mounted volume.- Some terminal UIs don’t render. Tool compatibility follows the gVisor version Runpod runs, and some full-screen terminal apps may not display correctly.
Next steps
- Create your first sandbox.
- Browse the Sandboxes API reference.
- Learn how to create an API key.