Quickstart
Three API calls: create a sandbox, run a command in it, destroy it. This page gets you from a fresh account to a real execution in a few minutes.
1. Sign in and create an API key
- Sign in with Google. New accounts get $5.00 of runtime credit, no card required.
- Open Dashboard → API keys and create a key.
- Copy it. The key is shown once, at creation time, and starts with
aas_sk_.
export AAS_API_KEY="aas_sk_your_key_here"
Verify the key works. This call returns your balance, limits and pricing:
curl -sS https://sandbox-as-a-service.com/v1/account -H "Authorization: Bearer $AAS_API_KEY"
{
"object": "account",
"id": "8f1c...",
"email": "you@example.com",
"balance_usd": 5.00,
"limits": { "concurrent_sandboxes": 20, "max_timeout_minutes": 1440 },
"pricing_usd_per_hour": {"small":0.09,"medium":0.28,"large":0.55}
}
2. Create a sandbox, run a command, destroy it
Each sandbox is a dedicated virtual machine. The create call blocks until the machine is ready, so by the time you get a response you can immediately execute in it.
# Requires: curl, jq
export AAS_API_KEY="aas_sk_your_key_here"
# 1. Create a sandbox. Returns when it is ready (status: running).
SBX=$(curl -sS -X POST https://sandbox-as-a-service.com/v1/sandboxes \
-H "Authorization: Bearer $AAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quickstart-$(date +%s)" \
-d '{"size":"small","timeout_minutes":15}' | jq -r .id)
echo "sandbox: $SBX"
# 2. Run a command inside it.
curl -sS -X POST https://sandbox-as-a-service.com/v1/sandboxes/$SBX/exec \
-H "Authorization: Bearer $AAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"command":"python3 -c \"print(6*7)\"","timeout_ms":30000}' | jq
# 3. Destroy it. Billing stops here.
curl -sS -X DELETE https://sandbox-as-a-service.com/v1/sandboxes/$SBX \
-H "Authorization: Bearer $AAS_API_KEY" | jq# pip install requests
import os
import requests
API = "https://sandbox-as-a-service.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['AAS_API_KEY']}"}
# 1. Create a sandbox. This call blocks until it is ready.
sandbox = requests.post(
f"{API}/sandboxes",
headers=HEADERS,
json={"size": "small", "timeout_minutes": 15},
timeout=600,
).json()
print("sandbox:", sandbox["id"], sandbox["status"])
try:
# 2. Run a command.
result = requests.post(
f"{API}/sandboxes/{sandbox['id']}/exec",
headers=HEADERS,
json={"command": "python3 -c 'print(6 * 7)'", "timeout_ms": 30000},
timeout=120,
).json()
print(result["stdout"].strip()) # -> 42
print(result["exit_code"]) # -> 0
finally:
# 3. Always destroy the sandbox, including on failure.
requests.delete(f"{API}/sandboxes/{sandbox['id']}", headers=HEADERS, timeout=120)// Node.js 18+ (global fetch). No dependencies.
const API = "https://sandbox-as-a-service.com/v1";
const headers = {
Authorization: `Bearer ${process.env.AAS_API_KEY}`,
"Content-Type": "application/json",
};
// 1. Create a sandbox. This call blocks until it is ready.
const sandbox = await fetch(`${API}/sandboxes`, {
method: "POST",
headers,
body: JSON.stringify({ size: "small", timeout_minutes: 15 }),
}).then((r) => r.json());
console.log("sandbox:", sandbox.id, sandbox.status);
try {
// 2. Run a command.
const result = await fetch(`${API}/sandboxes/${sandbox.id}/exec`, {
method: "POST",
headers,
body: JSON.stringify({
command: "node -e 'console.log(6 * 7)'",
timeout_ms: 30000,
}),
}).then((r) => r.json());
console.log(result.stdout.trim()); // -> 42
console.log(result.exit_code); // -> 0
} finally {
// 3. Always destroy the sandbox, including on failure.
await fetch(`${API}/sandboxes/${sandbox.id}`, { method: "DELETE", headers });
}
What you get back
The exec response contains everything the command produced:
{
"object": "execution",
"id": "exec_4b1d2e3f4a5b6c7d",
"sandbox_id": "sbx_9f2c4a1b8d3e6f0a12",
"exit_code": 0,
"stdout": "42\n",
"stderr": "",
"truncated": false,
"duration_ms": 412
}
A failing command is still an HTTP 200. Check exit_code, not the status code,
to find out whether the command succeeded. HTTP status codes describe the API call; exit codes describe
the program you ran.
3. Know what you are paying for
Billing runs from the moment the sandbox is ready until it is destroyed, at
$0.09/hour for a small — so ten minutes costs about
$0.015, and the $5.00 signup credit covers roughly
56 hours of small runtime. Nothing else is metered: API calls, commands and
bytes of output are free.
| Size | vCPU | Memory | Disk | Price |
|---|---|---|---|---|
small | 2 | 4 GB | 40 GB | $0.09/hour |
medium | 4 | 8 GB | 80 GB | $0.28/hour |
large | 8 | 16 GB | 160 GB | $0.55/hour |
What a sandbox is
- A dedicated virtual machine with its own kernel, filesystem and network stack — not a container on a shared host.
- Never reused between accounts. When it is destroyed, the machine and its disk are destroyed.
- Your code runs as the unprivileged
sandboxuser in/workspace. There is no sudo. - Outbound internet works, so
pip,npmandgit clonework. The cloud metadata endpoint and outbound SMTP are blocked.
Next steps
Questions
Do I have to poll until the sandbox is ready?
No. POST /v1/sandboxes is synchronous: it returns once the sandbox is ready to accept commands, with status: "running". Give the request a generous client-side timeout — see limits for how long provisioning can take.
What is installed inside a sandbox?
Python 3 (with pip and venv), Node.js 22, git, curl, wget, jq, unzip and build-essential. You can install anything else at runtime — the sandbox has outbound internet access.
What happens if I never destroy the sandbox?
It is destroyed automatically when it expires. The default lifetime is 15 minutes and the hard ceiling is 1440 minutes after creation. Billing stops at teardown either way, but destroying it as soon as you are done is cheaper.
Can I reuse one sandbox for many requests?
Yes. A sandbox is a normal machine and keeps its filesystem for its whole lifetime, so you can run as many commands in it as you like. Reuse it when the work is related and trusted; create a fresh one per request when you are running code you did not write. See the examples.
Start in the free tier
No credit card required. New accounts get $5 of runtime credit — about 56 hours of sandbox time.