SandboxAPI — Code Execution API for AI Agents
8 languages. gVisor isolation. Stateful sessions with file and package persistence. Streaming, async polling, and MCP-native tools.
Quick Start #
Synchronous execution #
curl -X POST https://sandboxapi.p.rapidapi.com/v1/execute \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-H "X-RapidAPI-Host: sandboxapi.p.rapidapi.com" \
-d '{"language":"python3","code":"print(\"Hello, World!\")"}'
Response:
{
"id": "exec_abc123",
"status": "completed",
"language": "python3",
"stdout": "Hello, World!\n",
"stderr": "",
"exit_code": 0,
"execution_time_ms": 42,
"memory_used_kb": 8192,
"timeout": 10,
"created_at": "2026-06-25T10:00:00Z"
}
Stateful session 3.2.0 #
Sessions hold a sandbox open between calls. Files and installed packages persist for the session's idle TTL (max 30 minutes). Each call still runs in a fresh interpreter, so keep durable state on disk.
# 1. Create a session
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"language":"python3","idle_ttl":300}'
# → {"id":"sess_abc","language":"python3","expires_at":"..."}
# 2. Execute — writes durable state to the session filesystem
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions/sess_abc/execute \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"code":"from pathlib import Path\nPath(\"state.txt\").write_text(\"42\")"}'
# 3. Execute again — the file is still there
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions/sess_abc/execute \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"code":"from pathlib import Path\nprint(int(Path(\"state.txt\").read_text()) * 2)"}'
# → stdout: "84\n"
Package installation in a session 3.3.0 #
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions/sess_abc/install \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"manager":"pip","packages":["pandas","numpy"]}'
Supported stable managers for current public runtimes: pip for Python and npm for JavaScript/TypeScript. Top-1k packages per ecosystem are cached for fast installs.
Streaming output 3.1.0 #
curl -N -X POST https://sandboxapi.p.rapidapi.com/v1/execute/stream \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"language":"python3","code":"for i in range(5):\n print(i); import time; time.sleep(1)"}'
# → SSE events: stdout, stdout, ..., result
Events use the standard SSE format. The terminal event has event: result with a JSON payload that includes exit_code, execution_time_ms, and memory_used_kb.
Async polling 3.1.0 #
curl -X POST "https://sandboxapi.p.rapidapi.com/v1/execute?async=true" \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{"language":"python3","code":"..."}'
# → {"job_id":"job_xyz","status":"queued","poll_url":"/v1/executions/job_xyz"}
curl https://sandboxapi.p.rapidapi.com/v1/executions/job_xyz \
-H "X-RapidAPI-Key: YOUR_API_KEY"
# Terminal responses include either result or error fields.
Supported Languages #
| Language | Version | ID |
|---|---|---|
| Python | 3.12 | python3 |
| JavaScript | Node 22 | javascript |
| TypeScript | 5.4 | typescript |
| Go | 1.22 | go |
| Java | 21 | java |
| C++ | GCC 14 | cpp |
| C | GCC 14 | c |
| Bash | 5.2 | bash |
Request Parameters #
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
language | string | Yes | — | Language ID |
code | string | Yes | — | Source code (max 1MB) |
timeout | integer | No | 10 | CPU seconds (capped by plan) |
stdin | string | No | "" | Standard input |
Response Fields #
| Field | Type | Description |
|---|---|---|
id | string | Execution ID |
status | string | completed / error / timeout |
language | string | Normalized language ID used for execution |
stdout | string | Standard output (max 1MB, may be truncated) |
stderr | string | Standard error (max 1MB) |
exit_code | integer | Process exit code |
execution_time_ms | integer | CPU time |
memory_used_kb | integer | Peak memory |
timeout | integer | Effective timeout in seconds |
created_at | string | Execution timestamp |
truncated | bool | Present when output was truncated |
Error Handling #
SandboxAPI distinguishes between API errors (HTTP 4xx/5xx) and execution errors (HTTP 200 with a status field). Treat any HTTP 200 response as a successful API call — the status tells you whether the user's code ran cleanly.
| HTTP | Meaning | What to do |
|---|---|---|
200 | Execution returned a result | Inspect status |
400 | Bad request (missing language, oversize body, etc.) | Fix the payload |
401 / 403 | Missing/invalid API key | Check your RapidAPI subscription |
408 | Execution or queue timeout | Raise timeout within your plan limit or use async polling |
413 | Payload too large | Trim code or stdin |
429 | Rate limit exceeded | Back off or upgrade tier |
500 / 503 | Internal error | Retry with exponential backoff; report if persistent |
Pricing & Rate Limits #
| Plan | Price | Executions/mo | Timeout | Batch | Sessions | Packages | Async | Streaming |
|---|---|---|---|---|---|---|---|---|
| Basic | Free | 500 | 30s | 10 | — | — | — | ✓ |
| Pro | $19/mo | 10,000 | 60s | 50 | 5 concurrent | top-1k cache | ✓ | ✓ |
| Ultra | $49/mo | 50,000 | 300s | 100 | 20 concurrent | top-1k cache | ✓ | ✓ |
All plans include gVisor isolation, 8 languages, stdin, batch execution, streaming output, and the playground. Sessions, package install, and async polling are available on paid plans. See pricing for full details.
Security #
Every execution runs inside an OCI container backed by gVisor (runsc) — a user-space kernel that intercepts syscalls before they reach the host. Combined with strict resource limits, no network egress (default), no persistent storage, and per-request cleanup, this gives you a strictly stronger isolation boundary than container-only sandboxes like raw Docker or Kubernetes.
- gVisor (runsc) wraps every container; user-space syscall filter blocks risky calls before the host kernel sees them.
- Resource limits (CPU, memory, PIDs, file descriptors, disk) are enforced by cgroups and seccomp.
- Network egress is disabled for execution containers. Package installs run through a short-lived install container limited to the internal mirror.
- Synchronous executions retain no data. Async results live for 24h. Session state expires at the idle TTL (max 30 min).
MCP Server #
SandboxAPI is available as an MCP server at https://mcp.sandboxapi.dev/mcp with 5 tools: execute_code, execute_batch, list_languages, get_capabilities, and session_install_packages.
Claude Code, Codex, Cursor, VS Code, and Antigravity support remote MCP with Bearer authentication. Use the client setup guide for each client's configuration format. For VS Code, add this to .vscode/mcp.json to use a prompted secret:
{
"inputs": [{
"type": "promptString",
"id": "sandboxapi-key",
"description": "SandboxAPI RapidAPI key",
"password": true
}],
"servers": {
"sandboxapi": {
"type": "http",
"url": "https://mcp.sandboxapi.dev/mcp",
"headers": { "Authorization": "Bearer ${input:sandboxapi-key}" }
}
}
}
Claude Desktop's remote connector UI also supports request headers for organizations with access to Anthropic's limited beta. SandboxAPI OAuth onboarding is planned. Keep keys in environment variables, secret stores, or personal configuration; never place a RapidAPI key in the endpoint URL.
Full integration guide on the MCP page.
Code Examples #
Python (requests)
import requests
resp = requests.post(
"https://sandboxapi.p.rapidapi.com/v1/execute",
headers={
"X-RapidAPI-Key": "YOUR_API_KEY",
"X-RapidAPI-Host": "sandboxapi.p.rapidapi.com",
},
json={"language": "python3", "code": "print(2 + 2)"},
)
data = resp.json()
print(data["stdout"]) # → "4\n"
JavaScript (fetch)
const resp = await fetch("https://sandboxapi.p.rapidapi.com/v1/execute", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Key": "YOUR_API_KEY",
"X-RapidAPI-Host": "sandboxapi.p.rapidapi.com",
},
body: JSON.stringify({ language: "javascript", code: "console.log(2 + 2)" }),
});
const data = await resp.json();
console.log(data.stdout); // → "4\n"
Go
req, _ := http.NewRequest("POST", "https://sandboxapi.p.rapidapi.com/v1/execute",
strings.NewReader(`{"language":"go","code":"package main\nimport \"fmt\"\nfunc main(){fmt.Println(2+2)}"}`))
req.Header.Set("X-RapidAPI-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
Changelog #
| Version | Highlights |
|---|---|
| 3.3.0 | Package installation in sessions with cached package mirrors and supply-chain checks |
| 3.2.0 | Stateful sessions with persistent files and installed packages |
| 3.1.0 | SSE streaming output and async execution with polling |
| 2.0.0 | Ultra tier (50K exec/mo), gVisor isolation, batch up to 100, 300s timeout, playground |
| 1.2.0 | Pre-warmed sandbox pools, sub-100ms cold starts, memory reporting |
| 1.1.0 | Batch execution endpoint (/execute/batch) |
| 1.0.0 | Stable release — Pro tier, rate limit headers, /health endpoint, full error codes |
| 0.3.0 | All 8 languages, stdin support, /languages endpoint |
| 0.2.0 | Added TypeScript, Go, Bash |
| 0.1.0 | Alpha — Python and JavaScript |