Skip to main content
Quick start

Create an anonymous sandbox first

No account is required for the first run. Create a one-hour sandbox, save the returned box.id and sandboxToken, then use that token for commands or task messages.

curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "agent-sandbox",
    "agent": "clanker-cli",
    "region": "earth"
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/commands" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{ "command": "pwd && ls -la" }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/messages" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "role": "user",
    "content": "Clone the repo, install dependencies, run tests, and summarize anything that blocks the run."
  }'
Clanker CLI

Use sandboxes from CLI or MCP

The open-source Clanker CLI now wraps the hosted sandbox API for terminal users and exposes the same operations as MCP tools for Codex, Claude Code, GitHub Copilot, OpenClaw, Hermes, and other clients.

# Create an anonymous sandbox. Save created.body.box.id and created.body.sandboxToken.
clanker cloud sandboxes create --name agent-sandbox --agent clanker-cli --region earth

# Use CLANKER_SANDBOX_TOKEN or pass --sandbox-token for sandbox-scoped calls.
export CLANKER_SANDBOX_TOKEN="<sandboxToken from create>"

clanker cloud sandboxes inspect "$SANDBOX_ID"
clanker cloud sandboxes command "$SANDBOX_ID" "pwd && ls -la" --timeout-seconds 120
clanker cloud sandboxes message "$SANDBOX_ID" "Clone the repo, install dependencies, run tests, and summarize blockers."
clanker cloud sandboxes delete "$SANDBOX_ID"

# One-shot agent task: create a sandbox and send the first task message.
clanker cloud sandboxes run "Clone the repo, install dependencies, run tests, and summarize blockers." \
  --name repo-check \
  --agent clanker-cli \
  --region earth
clanker mcp --transport stdio

# Hosted sandbox tools exposed by the MCP server:
clanker_cloud_create_sandbox
clanker_cloud_list_sandboxes
clanker_cloud_inspect_sandbox
clanker_cloud_delete_sandbox
clanker_cloud_run_sandbox_command
clanker_cloud_send_sandbox_message
clanker_cloud_run_sandbox_task
Markdown for agents

Fetch the agent-readable API docs

Agents can query a stable Markdown file before calling sandbox routes. Use it as retrieval context for tool runners, LLM orchestration, queue workers, and internal automations.

curl -fsS "https://clankercloud.ai/api-docs-agent.md"
Before using the Clanker Cloud sandbox API, fetch https://clankercloud.ai/api-docs-agent.md. Start with an anonymous sandbox unless the task needs a persistent paid account feature. Save box.id and sandboxToken, keep workflow state with the sandbox, ask before side effects, and delete one-off runtimes when finished.
Agent handoff

Copy docs for your agent

Paste this into Codex, Claude Code, OpenClaw, Hermes, your own runner, or any LLM tool orchestrator that needs the sandbox API contract, account creation paths, token rules, workflow records, approvals, traces, memory, paid outputs, and cleanup behavior.

# Clanker Cloud sandbox API runbook for agents

Base URL: https://clankercloud.ai/api

Use Clanker Cloud sandboxes when a task needs a real hosted shell, files, command execution, workflow state, approval records, traces, memory, or a hosted output.

Agent-readable Markdown docs:

...
Use cases

Useful jobs to run in a sandbox

Repo triage from an issue

Clone a repo, install dependencies, run tests, inspect failures, and leave handoff memory before opening a PR.

CI smoke checks

Run build and test commands in a clean hosted runtime before a deployment, migration, or agent-authored change.

Approval-gated publishing

Generate a report or preview, create an approval record, then publish only after the user accepts the step.

Scheduled reports

Use workflow metadata to track weekly ops, cost, security, or account-review jobs with clear owners and steps.

Human handoffs

Store traces and short non-secret memory so a teammate or follow-up agent can resume without rereading the whole run.

LLM tool orchestration

Expose sandbox creation as a tool, keep sandbox tokens in orchestration state, and let the model call safe task operations.

Base URL

Use https://clankercloud.ai/api for public sandbox API calls.

Authentication

Use X-API-Key or Authorization: Bearer with either an account token or the returned sandbox token.

CLI and MCP

Use clanker cloud sandboxes for terminal workflows, or clanker mcp --transport stdio for agent tools.

Tiers

Anonymous sandboxes last one hour. Free account sandboxes last about eight hours. Paid accounts get larger persistent sandboxes plus hosted sites and /explain.

Agent state

Use workflows, approvals, traces, memory, and tools routes to make runs inspectable and resumable.

Lifecycle

List, inspect, wait, and clean up sandboxes

Agents should treat sandboxes like task runtimes: create one, wait until it is ready, keep the id and token, then delete it when the job is done.

curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY"
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
for attempt in 1 2 3 4 5; do
  STATUS=$(curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
    -H "X-API-Key: $CLANKER_SANDBOX_TOKEN")

  echo "$STATUS"
  echo "$STATUS" | grep -q '"status":"ready"' && break
  sleep $((attempt * 2))
done
curl -sS -X DELETE "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
Routes

Core sandbox routes

RouteMethodUse it for
/api/sandboxesPOSTCreate an anonymous, free account, or paid account sandbox.
/api/sandboxesGETList account-owned sandboxes. Anonymous sandboxes are not listed.
/api/sandboxes/{id}GETInspect status, routes, provider, owner, and expiry.
/api/sandboxes/{id}DELETEDelete the sandbox when the task is done.
/api/sandboxes/{id}/commandsPOSTRun shell commands in the sandbox.
/api/sandboxes/{id}/messagesPOSTSend a chat-style task message to the runtime agent endpoint.
/api/sandboxes/{id}/platformGET or POSTRead capabilities, workflows, approvals, traces, memory, tools, and hosted artifacts.
/api/sandboxes/{id}/sitesGET or POSTPaid account route for static hosted outputs.
/api/sandboxes/{id}/explainGET or POSTPaid account route for sandbox infrastructure summaries.
Accounts

Create accounts for humans and agents

curl -sS "https://clankercloud.ai/api/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "user@example.com",
    "password": "choose-a-password",
    "name": "User"
  }'
curl -sS "https://clankercloud.ai/api/auth/agent/register" \
  -H "Content-Type: application/json" \
  -d '{
    "agentName": "codex",
    "machineHint": "linux/amd64/sandbox",
    "metadata": { "source": "agent-api" }
  }'
curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY" \
  -d '{ "name": "agent-runner", "agent": "codex", "region": "earth" }'
LLM integration

Teach an LLM when and how to use sandboxes

{
  "type": "function",
  "function": {
    "name": "create_clanker_sandbox",
    "description": "Create a hosted Clanker Cloud sandbox for an agent run.",
    "parameters": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "agent": {
          "type": "string",
          "enum": ["clanker-cli", "codex", "claude-code", "openclaw", "hermes", "empty", "clanker-vision"]
        },
        "region": { "type": "string", "default": "earth" }
      },
      "required": ["name", "agent"]
    }
  }
}
async function dispatchSandboxTool(call) {
  if (call.name !== 'create_clanker_sandbox') {
    throw new Error('Unknown tool: ' + call.name)
  }

  const args = call.arguments
  const created = await clanker('/sandboxes', {
    method: 'POST',
    body: {
      name: args.name,
      agent: args.agent || 'empty',
      region: args.region || 'earth',
    },
  })

  // Store these in your orchestration layer, not in the visible model transcript.
  return {
    sandboxId: created.box.id,
    sandboxToken: created.sandboxToken,
    expiresAt: created.box.expiresAt,
  }
}
You can use Clanker Cloud sandboxes when work needs a real shell or hosted workspace.

Rules:
- Create one sandbox per task.
- Store sandbox id and sandboxToken from the create response.
- Prefer Clanker CLI or MCP sandbox tools when they are already available; they call the same hosted sandbox API.
- Use sandboxToken only for that sandbox.
- Run read and test commands freely.
- Create an approval before publishing, deleting, installing system packages, sending messages, or changing accounts.
- Put secrets in the user's normal secret manager or Clanker Cloud settings, not sandbox memory.
- Delete the sandbox when the task is done.
const BASE_URL = 'https://clankercloud.ai/api'

async function clanker(path, { token, method = 'GET', body } = {}) {
  const response = await fetch(BASE_URL + path, {
    method,
    headers: {
      ...(body ? { 'Content-Type': 'application/json' } : {}),
      ...(token ? { 'X-API-Key': token } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  })

  const data = await response.json().catch(() => ({}))
  if (!response.ok) throw new Error(data.error || 'Clanker Cloud request failed')
  return data
}

const created = await clanker('/sandboxes', {
  method: 'POST',
  body: { name: 'agent-run', agent: 'codex', region: 'earth' },
})

const sandboxId = created.box.id
const sandboxToken = created.sandboxToken

await clanker('/sandboxes/' + sandboxId + '/commands', {
  method: 'POST',
  token: sandboxToken,
  body: { command: 'pwd && ls -la' },
})
Agent runners

End-to-end runner examples

These examples are meant for small agent runners, queue workers, test automation, and internal tools that need a hosted runtime but still want an approval trail.

const created = await clanker('/sandboxes', {
  method: 'POST',
  body: { name: 'repo-check', agent: 'codex', region: 'earth' },
})

const sandboxId = created.box.id
const sandboxToken = created.sandboxToken

const workflow = await clanker('/sandboxes/' + sandboxId + '/workflows', {
  method: 'POST',
  token: sandboxToken,
  body: {
    name: 'repo check',
    trigger: 'api',
    approvalMode: 'before_side_effects',
    steps: ['clone', 'install', 'test', 'report'],
  },
})

await clanker('/sandboxes/' + sandboxId + '/commands', {
  method: 'POST',
  token: sandboxToken,
  body: { command: 'git clone "$REPO_URL" repo && cd repo && npm test' },
})

await clanker('/sandboxes/' + sandboxId + '/traces', {
  method: 'POST',
  token: sandboxToken,
  body: { type: 'workflow.step', summary: 'Test command finished', level: 'info' },
})

await clanker('/sandboxes/' + sandboxId + '/memory', {
  method: 'POST',
  token: sandboxToken,
  body: {
    key: 'handoff',
    scope: 'sandbox',
    value: 'Repo check finished. Review traces before publishing or changing anything.',
  },
})

return { sandboxId, workflowId: workflow.id || workflow.workflowId }
import os
import requests

BASE_URL = "https://clankercloud.ai/api"

def clanker(path, token=None, method="GET", body=None):
    headers = {}
    if token:
        headers["X-API-Key"] = token
    if body is not None:
        headers["Content-Type"] = "application/json"

    response = requests.request(
        method,
        BASE_URL + path,
        headers=headers,
        json=body,
        timeout=60,
    )
    response.raise_for_status()
    return response.json() if response.content else {}

created = clanker(
    "/sandboxes",
    method="POST",
    body={"name": "python-agent-run", "agent": "empty", "region": "earth"},
)

sandbox_id = created["box"]["id"]
sandbox_token = created["sandboxToken"]

command = clanker(
    f"/sandboxes/{sandbox_id}/commands",
    token=sandbox_token,
    method="POST",
    body={"command": "python --version && pwd"},
)

print(command)
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/workflows" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "name": "daily account review",
    "trigger": "webhook:account-review",
    "approvalMode": "before_side_effects",
    "metadata": { "source": "internal-queue", "runId": "run_123" },
    "steps": ["collect evidence", "draft report", "ask for approval", "publish"]
  }'
Recipes

Practical sandbox recipes

Use these as starting points for real workflows. They keep work inside one sandbox, record state as the job moves forward, and pause before side effects.

const repoUrl = 'https://github.com/acme/app'

const created = await clanker('/sandboxes', {
  method: 'POST',
  body: { name: 'issue-482-triage', agent: 'codex', region: 'earth' },
})

const sandboxId = created.box.id
const sandboxToken = created.sandboxToken

await clanker('/sandboxes/' + sandboxId + '/workflows', {
  method: 'POST',
  token: sandboxToken,
  body: {
    name: 'issue triage',
    trigger: 'github:issue:482',
    approvalMode: 'before_side_effects',
    steps: ['clone repo', 'run tests', 'inspect failing files', 'write handoff'],
  },
})

await clanker('/sandboxes/' + sandboxId + '/commands', {
  method: 'POST',
  token: sandboxToken,
  body: {
    command: 'git clone "' + repoUrl + '" repo && cd repo && npm ci && npm test',
  },
})

await clanker('/sandboxes/' + sandboxId + '/memory', {
  method: 'POST',
  token: sandboxToken,
  body: {
    key: 'issue-482-handoff',
    scope: 'workflow',
    value: 'Repo test run finished. Summarize failing files and ask before opening a PR.',
  },
})
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/commands" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "command": "git clone $REPO_URL repo && cd repo && npm ci && npm run build && npm test",
    "timeoutSeconds": 900
  }'

curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/traces" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "type": "ci.smoke",
    "summary": "Build and test command finished. Review command output before opening a PR.",
    "level": "info"
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/approvals" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "workflowId": "$WORKFLOW_ID",
    "title": "Publish run report",
    "summary": "Publish the generated report as a static page from this sandbox.",
    "risk": "low",
    "status": "pending"
  }'

# After approval, use a paid account token for the hosted output.
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/sites" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY" \
  -d '{
    "name": "run report",
    "slug": "run-report",
    "sourceDir": "/workspace/report",
    "spa": false
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/workflows" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "name": "weekly ops report",
    "trigger": "schedule:weekly",
    "approvalMode": "before_publish",
    "metadata": {
      "owner": "ops",
      "sources": ["repo", "logs", "tickets", "cost-export"]
    },
    "steps": [
      "collect source files",
      "run checks",
      "write report",
      "ask for approval",
      "publish approved report"
    ]
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/traces" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "type": "handoff.ready",
    "summary": "Sandbox work is ready for a human or follow-up agent.",
    "level": "info"
  }'

curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/memory" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "key": "handoff",
    "scope": "sandbox",
    "value": "What changed: tests passed. What is blocked: publishing needs approval. Next step: review /platform and approve or reject the publish request."
  }'
Workflow state

Make agent runs inspectable

curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/platform" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/workflows" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "name": "deploy fixer",
    "trigger": "webhook",
    "approvalMode": "before_side_effects",
    "steps": ["inspect", "test", "pause before write", "publish report"]
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/approvals" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{
    "workflowId": "$WORKFLOW_ID",
    "title": "Publish deploy report",
    "summary": "Allow the agent to publish a static report from this sandbox.",
    "risk": "low",
    "status": "pending"
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/traces" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{ "type": "shell.command", "summary": "npm test passed", "level": "info" }'

curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/memory" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN" \
  -d '{ "key": "handoff", "scope": "sandbox", "value": "Tests passed; waiting for approval before publishing." }'
Paid outputs

Publish and explain sandbox outputs

curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/sites" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY" \
  -d '{
    "name": "agent status",
    "slug": "agent-status",
    "html": "<!doctype html><h1>Agent run is ready</h1>"
  }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/sites" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY" \
  -d '{ "name": "dist preview", "slug": "dist-preview", "sourceDir": "/workspace/dist", "spa": true }'
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/explain" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY"
Errors

Responses agents should handle

StatusMeaningAgent behavior
401 or 403Missing, expired, or wrong token.Ask for the right account token or use the sandboxToken returned at create time.
402Paid account required.Use a paid account token before calling /sites or /explain.
409Runtime not ready yet.Wait and retry with backoff.
410Sandbox expired.Create a new sandbox and restart from saved external context.
429Rate limited.Back off and avoid parallel command floods.
FAQ

Common questions

Which token should an agent use?

Use the returned sandboxToken for an anonymous sandbox. Use an account API key for account-owned sandboxes, listing sandboxes, paid hosting, and /explain.

Can I put secrets in sandbox memory?

No. Memory is for short non-secret handoff notes. Put secrets in the normal account, customer, or local secret boundary.

Should every LLM call create a sandbox?

No. Create a sandbox when the task needs a shell, files, a hosted workspace, workflow state, or a published output. Simple chat should stay as chat.

Next step

Need the concise reference?

Use the Sandbox API page when you want route tables and lifecycle rules without the longer examples.