Execute Python code in secure sandboxes with streaming output, file operations, and pip package support.
LLM-optimized documentation (llms.txt) - Machine-readable quick reference
Sign up with your email to get a trial API key. Email verification required - you must click the link in your email to get your API key.
# 1. Sign up with your email (sends verification email) curl -X POST https://api.cerver.ai/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]"}' # Returns: {"message": "Verification email sent!", ...} # 2. Check your email and click the verification link # You'll receive your API key (sk_trial_xxx) after verification # 3. Create sandbox curl -X POST https://api.cerver.ai/sandbox \ -H "Authorization: Bearer sk_trial_xxx" # Returns: {"sandbox_id": "abc-123", ...} # 4. Run code curl -X POST https://api.cerver.ai/sandbox/abc-123/run \ -H "Authorization: Bearer sk_trial_xxx" \ -H "Content-Type: application/json" \ -d '{"code": "print(2 ** 100)"}' # Returns: {"output": "1267650600228229401496703205376", "exit_code": 0}
Trial keys have limited usage (100 requests/day). Upgrade for higher limits.
Base URL: https://api.cerver.ai
| Endpoint | Description |
|---|---|
POST /auth/signup |
Sign up with email (sends verification link) |
GET /auth/verify-signup?token= |
Verify email and get API key |
POST /auth/login |
Request magic link for dashboard access |
POST /sandbox |
Create sandbox (with envs, timeout, metadata) |
GET /sandbox/:id |
Get sandbox info |
GET /sandboxes |
List all active sandboxes |
DELETE /sandbox/:id |
Terminate sandbox |
POST /sandbox/:id/timeout |
Extend sandbox timeout |
GET /sandbox/:id/host?port=N |
Get external URL for port |
POST /sandbox/:id/run |
Run code (with envs override) |
POST /sandbox/:id/run/stream |
Run code with SSE streaming |
POST /sandbox/:id/install |
Install pip packages |
POST /sandbox/:id/files |
Write file |
GET /sandbox/:id/files |
List files |
GET /sandbox/:id/files?path=x |
Read file |
Create a sandbox with optional configuration:
POST /sandbox
Authorization: Bearer sk_trial_xxx
Content-Type: application/json
{
"engine": "containers",
"envs": {"API_KEY": "secret123", "DEBUG": "true"},
"timeout_ms": 600000,
"metadata": {"project": "my-app", "user_id": "123"}
}
# Response
{
"sandbox_id": "abc-123",
"engine": "containers",
"status": "ready",
"timeout_ms": 600000,
"expires_at": 1706000000,
"envs": ["API_KEY", "DEBUG"],
"metadata": {"project": "my-app", "user_id": "123"}
}
| Parameter | Type | Description |
|---|---|---|
engine |
string | "workers" (default, fast) or "containers" (full pip) |
envs |
object | Environment variables available to code |
timeout_ms |
number | Sandbox lifetime in ms (default: 300000) |
metadata |
object | Custom key-value pairs for tracking |
Set environment variables at sandbox creation, override per execution:
# Set at sandbox creation POST /sandbox {"envs": {"API_KEY": "secret", "DEBUG": "true"}} # Override for specific execution POST /sandbox/abc-123/run { "code": "import os\nprint(os.environ.get('API_KEY'))", "envs": {"API_KEY": "override_value"} } # Output: override_value
Default variables injected automatically:
CERVER_SANDBOX=true - Indicates code is running in CerverCERVER_SANDBOX_ID=abc-123 - The sandbox IDSandboxes have a configurable lifetime. Extend before expiry to keep them alive:
# Create with custom timeout (10 minutes) POST /sandbox {"timeout_ms": 600000} # Check time remaining GET /sandbox/abc-123 # Returns: {"time_remaining_ms": 180000, ...} # Extend timeout POST /sandbox/abc-123/timeout {"timeout_ms": 300000} # Returns: {"expires_at": 1706000300, "time_remaining_ms": 299500}
| Plan | Max Timeout | Default |
|---|---|---|
| Trial | 5 minutes | 5 minutes |
| Free | 1 hour | 5 minutes |
| Pro | 24 hours | 5 minutes |
Run web servers in your sandbox and get external URLs (containers engine only):
# Run a web server in your sandbox POST /sandbox/abc-123/run {"code": "from http.server import HTTPServer, SimpleHTTPRequestHandler\nserver = HTTPServer(('0.0.0.0', 8080), SimpleHTTPRequestHandler)\nserver.serve_forever()"} # Get external URL for the port GET /sandbox/abc-123/host?port=8080 # Response { "sandbox_id": "abc-123", "port": 8080, "url": "https://abc12345-8080.sandbox.cerver.ai", "host": "abc12345-8080.sandbox.cerver.ai" }
POST /sandbox/abc-123/run
Authorization: Bearer sk_trial_xxx
Content-Type: application/json
{
"code": "x = 5\nprint(x * 10)",
"envs": {"DEBUG": "true"},
"timeout": 30
}
# Response
{
"output": "50",
"error": "",
"exit_code": 0,
"duration": 2
}
Get real-time output via Server-Sent Events:
POST /sandbox/abc-123/run/stream
Authorization: Bearer sk_trial_xxx
Content-Type: application/json
{"code": "import time\nfor i in range(3):\n print(i)\n time.sleep(1)"}
# Response (SSE stream)
data: {"type": "stdout", "data": "0\n"}
data: {"type": "stdout", "data": "1\n"}
data: {"type": "stdout", "data": "2\n"}
data: {"type": "exit", "code": 0}
Install pip packages. Auto-upgrades to containers engine if needed:
POST /sandbox/abc-123/install
Authorization: Bearer sk_trial_xxx
Content-Type: application/json
{"packages": "pandas numpy"}
# Response
{"success": true, "upgraded": true}
# Write file POST /sandbox/abc-123/files {"path": "data.txt", "content": "hello world"} # Response: {"success": true, "path": "data.txt", "size": 11} # Read file GET /sandbox/abc-123/files?path=data.txt # Response: {"path": "data.txt", "content": "hello world", "size": 11} # List files GET /sandbox/abc-123/files # Response: {"files": [{"path": "data.txt", "size": 11}]}
Access files from code using __sandbox_dir__:
result = sandbox.run("""
with open(__sandbox_dir__ + '/data.txt') as f:
print(f.read())
""")
| Engine | Startup | Packages | Use Case |
|---|---|---|---|
workers |
~50ms | Python stdlib only | Fast scripts, simple calculations |
containers |
~500ms | Full pip support | pandas, numpy, ML, web servers |
pip install cerver
from cerver import Sandbox with Sandbox(api_key="sk_trial_xxx") as sandbox: result = sandbox.run("print('Hello!')") print(result.output) # Hello!
with Sandbox( api_key="sk_trial_xxx", envs={"API_KEY": "secret"} ) as sandbox: result = sandbox.run(""" import os print(os.environ.get('API_KEY')) """) print(result.output) # secret
with Sandbox(engine="containers") as sandbox: sandbox.install("pandas") result = sandbox.run(""" import pandas as pd df = pd.DataFrame({'a': [1, 2, 3]}) print(df.sum()) """)
{
"name": "execute_python",
"description": "Execute Python code in a secure sandbox",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "Python code to execute"},
"envs": {"type": "object", "description": "Environment variables"}
},
"required": ["code"]
}
}
from cerver import Sandbox from openai import OpenAI client = OpenAI() sandbox = Sandbox() tools = [{ "type": "function", "function": { "name": "execute_code", "description": "Execute Python code in a sandbox", "parameters": { "type": "object", "properties": { "code": {"type": "string"} } } } }] response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "Calculate factorial of 10"}], tools=tools ) if response.choices[0].message.tool_calls: code = response.choices[0].message.tool_calls[0].function.arguments result = sandbox.run(code) print(result.output)
from cerver import Sandbox from anthropic import Anthropic client = Anthropic() sandbox = Sandbox() tools = [{ "name": "execute_code", "description": "Execute Python code in a sandbox", "input_schema": { "type": "object", "properties": { "code": {"type": "string"} } } }] response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "Calculate 2^100"}] ) for block in response.content: if block.type == "tool_use": result = sandbox.run(block.input["code"]) print(result.output)
| Plan | Requests/day | Sandboxes | Port Exposure |
|---|---|---|---|
Trial (sk_trial_) |
100 | 1 | No |
Free (sk_live_) |
1,000 | 5 | Yes |
| Pro | 100,000 | 100 | Yes |
Upgrade your plan for higher limits.
from cerver import Sandbox, CerverError, TimeoutError try: with Sandbox() as sandbox: result = sandbox.run("import nonexistent") if result.exit_code != 0: print(f"Error: {result.error}") except TimeoutError: print("Execution timed out") except CerverError as e: print(f"Cerver error: {e}")
Cerver is built on Cloudflare's infrastructure for security and speed:
Data flow:
User Request
↓
API (validates API key)
↓
D1 Database (stores users, keys, usage)
↓
Sandbox (isolated code execution)
No one can access the database directly. All requests go through the API which validates your API key first. Your code runs in isolated sandboxes that cannot access other users' data.