Skip to main content
Learn how to create a sandbox, run commands in it, and clean it up using the Runpod REST API v2.

What you’ll learn

  • How to create a sandbox from a container image.
  • How to wait until the sandbox is ready to accept commands.
  • How to run a command and read its output.
  • How to stream the sandbox’s logs.
  • How to terminate the sandbox so billing stops.

Requirements

  • A Runpod account with a positive balance.
  • A Runpod API key.
  • curl and jq for the command-line examples, or Python 3 with the requests package for the Python examples.
Set your API key as an environment variable so the examples can use it:

Step 1: Create a sandbox

Create a sandbox from the python:3.12-slim image with a five-minute idle timeout. The Idempotency-Key header makes the request safe to retry if the response is lost:
The response is the new sandbox. Note its id, which you use in every later request:
Every field is optional; an empty body ({}) creates a sandbox from the default image. See Create a sandbox for all fields.
By default, the sandbox has open outbound internet access. See Network access.

Step 2: Wait for the sandbox to be ready

Poll the sandbox until its state is RUNNING:
If the state becomes FAILED, check terminationReason in the response.

Step 3: Run a command

Send a command to the sandbox as an argv array. Commands aren’t run through a shell, so wrap them in ["sh", "-c", "..."] when you need shell syntax such as pipes or &&:
The response contains the command’s output and exit status:
exitCode is 0 when the command succeeds. output always contains stdout and stderr combined.
Commands are capped at about 4 seconds; a command still running at the cap is stopped and returns exitCode: null. For longer work, add "background": true to the request and redirect the command’s output to a file, then read that file with a later command.
Review question: What does the 409 response body look like? These examples assume the conflict code is in a field named code. Also, are python-requests and curl user agents allowed through Cloudflare in prod? Remove this box before merging.

Step 4: Stream logs

Stream the sandbox’s logs as Server-Sent Events. The stream includes the main process’s stdout (container) and lifecycle events such as image pulls (system). Output from commands you run with exec doesn’t appear here. An open log stream counts as activity, so it keeps the sandbox from timing out as idle.
Each event carries a JSON payload:
Press Ctrl+C to stop streaming.

Step 5: Terminate the sandbox

When you’re done, terminate the sandbox to stop billing:
A successful request returns 204 with no body. Terminating a sandbox is final: you can still read it with GET, but you can’t restart it.
In your own code, terminate the sandbox in a finally block or equivalent, so it’s cleaned up even when a command fails. If you forget, the sandbox terminates at its idle timeout or maximum lifetime, whichever comes first.

Next steps

Last modified on October 19, 2026