SandboxAPI — Code Execution API for AI Agents

12 languages. gVisor isolation. Stateful sessions. Package install. Streaming, async, webhooks, multi-file. MCP-native.

Current API version: 3.4.0 · Base URL via RapidAPI: https://sandboxapi.p.rapidapi.com · Direct: https://api.sandboxapi.dev

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,
  "exit_signal": 0,
  "execution_time_ms": 42,
  "wall_time_ms": 58,
  "memory_used_kb": 8192
}

Stateful session 3.2.0 #

Sessions hold a sandbox open between calls. Variables, files, and installed packages persist for the session's idle TTL (max 30 minutes).

# 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 — sets a variable
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions/sess_abc/execute \
  -H "X-RapidAPI-Key: YOUR_API_KEY" \
  -d '{"code":"x = 42"}'

# 3. Execute again — variable persists
curl -X POST https://sandboxapi.p.rapidapi.com/v1/sessions/sess_abc/execute \
  -H "X-RapidAPI-Key: YOUR_API_KEY" \
  -d '{"code":"print(x * 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 managers: pip, npm, gem, cargo. Top-1k packages per language are cached for sub-3s 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 + webhook 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":"...","callback_url":"https://your.app/hook"}'
# → {"token":"job_xyz","status":"queued"}

# Either poll:
curl https://sandboxapi.p.rapidapi.com/v1/executions/job_xyz \
  -H "X-RapidAPI-Key: YOUR_API_KEY"

# Or wait for the signed PUT to your callback_url.
# Verify the X-SandboxAPI-Signature: sha256=... header.

Multi-file programs 3.0.0 #

# Base64-encode a ZIP of source files, optionally with a compile script and run script.
curl -X POST https://sandboxapi.p.rapidapi.com/v1/execute \
  -H "X-RapidAPI-Key: YOUR_API_KEY" \
  -d '{
    "language":"cpp",
    "additional_files":"<base64 zip>",
    "compile_script":"g++ -O2 *.cpp -o main",
    "run_script":"./main"
  }'

Output verification 3.0.0 #

curl -X POST https://sandboxapi.p.rapidapi.com/v1/execute \
  -H "X-RapidAPI-Key: YOUR_API_KEY" \
  -d '{
    "language":"python3",
    "code":"print(2+2)",
    "expected_output":"5\n"
  }'
# → status: "wrong_answer"

Supported Languages #

LanguageVersionID
Python3.12python3
JavaScriptNode 22javascript
TypeScript5.4typescript
Go1.22go
Java21java
C++GCC 14cpp
CGCC 14c
Bash5.2bash
Rust1.85rust
Ruby3.3ruby
PHP8.4php
C#.NET 9csharp

Request Parameters #

FieldTypeRequiredDefaultDescription
languagestringYesLanguage ID
codestringYes (single-file)Source code (max 1MB)
additional_filesstringYes (multi-file)Base64-encoded ZIP (max 10MB decompressed)
compile_scriptstringNolanguage defaultBash script to compile (max 4KB)
run_scriptstringNolanguage defaultBash script to run (max 4KB)
timeoutintegerNo10CPU seconds (capped by plan)
wall_time_limitfloatNo=timeoutWall-clock seconds
stdinstringNo""Standard input
expected_outputstringNoIf set, compared to stdout for wrong_answer status
compiler_optionsstringNoExtra flags to compile step (max 512 chars, allowlisted)
command_line_argumentsstringNoArgv for the program (max 512 chars)
redirect_stderr_to_stdoutboolNofalseMerge streams
base64_encodedboolNofalseEncode binary stdin/stdout
callback_urlstringNoWebhook URL (async only)

Response Fields #

FieldTypeDescription
idstringExecution ID
statusstringcompleted / wrong_answer / timeout / compilation_error / runtime_error / memory_limit / internal_error
stdoutstringStandard output (max 1MB, may be truncated)
stderrstringStandard error (max 1MB)
compile_outputstringCompiler output (compiled languages only)
exit_codeintegerProcess exit code
exit_signalintegerTermination signal (e.g., 9 for SIGKILL)
execution_time_msintegerCPU time
wall_time_msintegerWall-clock time
memory_used_kbintegerPeak memory

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.

HTTPMeaningWhat to do
200Execution returned a resultInspect status
400Bad request (missing language, oversize body, etc.)Fix the payload
401 / 403Missing/invalid API keyCheck your RapidAPI subscription
408Wall-clock or queue timeoutRaise wall_time_limit or use async
413Payload too largeUse multi-file with ZIP, or trim code
429Rate limit exceededBack off or upgrade tier
500 / 503Internal errorRetry with exponential backoff; report if persistent

Pricing & Rate Limits #

PlanPriceExecutions/moTimeoutBatchSessionsPackagesAsyncStreaming
BasicFree50030s10
Pro$19/mo10,00060s505 concurrenttop-1k cache
Ultra$49/mo50,000300s10020 concurrentfull allowlist
Mega$149/mo200,000600s20050 concurrentfull + custom

All plans include gVisor isolation, 12 languages, stdin, multi-file, output verification, and webhooks where the mode supports it. 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.

MCP Server #

SandboxAPI is available as an MCP server at https://mcp.sandboxapi.dev/mcp with 11 tools: execute_code, execute_batch, list_languages, create_session, session_execute, session_close, session_install_packages, execute_async, get_execution, execute_with_expected, get_capabilities.

Add to Claude Desktop / Cursor / VS Code:

{
  "mcpServers": {
    "sandboxapi": {
      "url": "https://mcp.sandboxapi.dev/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY" }
    }
  }
}

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()
Try it live: open the playground to run any of these snippets in any of the 12 supported languages without writing a client.

Changelog #

VersionHighlights
3.4.0Direct API channel (api.sandboxapi.dev), Stripe self-serve, new Mega tier (200K exec/mo)
3.3.0Package installation in sessions (pip/npm/gem/cargo) with offline cache
3.2.0Stateful sessions — REPL-like execution with persistent variables, files, packages
3.1.0SSE streaming output; async execution with signed webhook callbacks
3.0.04 new languages (Rust, Ruby, PHP, C#); multi-file programs; expected_output + status taxonomy; MCP server expanded to 11 tools
2.0.0Ultra tier (50K exec/mo), gVisor isolation, batch up to 100, 300s timeout, playground
1.2.0Pre-warmed sandbox pools, sub-100ms cold starts, memory reporting
1.1.0Batch execution endpoint (/execute/batch)
1.0.0Stable release — Pro tier, rate limit headers, /health endpoint, full error codes
0.3.0All 8 languages, stdin support, /languages endpoint
0.2.0Added TypeScript, Go, Bash
0.1.0Alpha — Python and JavaScript

Read the full release-by-release changelog →