# Clanker Cloud API Docs

Base URL:

```text
https://clankercloud.ai/api
```

Use these docs to create hosted sandboxes, run commands, send task messages, store workflow state, ask for approvals, publish outputs, and teach LLMs when to use a sandbox.

## Create an anonymous sandbox first

No account is required for the first run. Anonymous sandboxes last one hour. Save `box.id` as `SANDBOX_ID` and `sandboxToken` as `CLANKER_SANDBOX_TOKEN`.

Create an anonymous one-hour sandbox:

```bash
curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "agent-sandbox",
    "agent": "clanker-cli",
    "region": "earth"
  }'
```

Run the first command:

```bash
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" }'
```

Send a task message:

```bash
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 blockers."
  }'
```

## Use the Clanker CLI

The open-source Clanker CLI can call the same hosted sandbox API without hand-writing curl.

```bash
# 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"
```

For a one-shot agent task, let the CLI create the sandbox and send the first message:

```bash
clanker cloud sandboxes run "Clone the repo, install dependencies, run tests, and summarize blockers." \
  --name repo-check \
  --agent clanker-cli \
  --region earth
```

Account-owned sandboxes use `CLANKER_CLOUD_API_KEY` or `--api-key`. Custom deployments can set `CLANKER_CLOUD_SANDBOX_API_BASE_URL`, `CLANKER_SANDBOX_API_BASE_URL`, or `--api-base-url`.

When the CLI is launched as an MCP server with `clanker mcp --transport stdio`, it exposes sandbox tools for agents:

```text
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
```

## Agent-readable Markdown

Agents can query a stable Markdown file before calling sandbox routes:

```text
https://clankercloud.ai/api-docs-agent.md
```

Fetch it from an agent runner:

```bash
curl -fsS "https://clankercloud.ai/api-docs-agent.md"
```

Use this instruction when giving an agent access to sandbox API tools:

```text
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.
```

## Copy docs for your agent

Paste this runbook into Codex, Claude Code, OpenClaw, Hermes, your own runner, or any LLM tool orchestrator.

```text
# 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:

https://clankercloud.ai/api-docs-agent.md

Fetch that file when you need the full sandbox API contract without browsing the rendered website.

1. Decide whether the run needs an account.

- Anonymous: POST /api/sandboxes without auth. Best for quick trials. Lifetime is one hour. Save box.id and sandboxToken from the create response.
- Free account: create a user or agent account, then use the returned account API token. Best for longer work sessions. Lifetime is about eight hours.
- Paid account: use a paid account token for larger persistent sandboxes, hosted static sites, and /explain.

2. Create an account when needed.

Human account:

curl -sS "https://clankercloud.ai/api/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "user@example.com",
    "password": "choose-a-password",
    "name": "User"
  }'

Agent account:

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" }
  }'

Send account tokens as X-API-Key: $CLANKER_CLOUD_API_KEY or Authorization: Bearer $CLANKER_CLOUD_API_KEY.

3. Create one sandbox per task.

curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "agent-sandbox",
    "agent": "clanker-cli",
    "region": "earth"
  }'

Store SANDBOX_ID from response.box.id, CLANKER_SANDBOX_TOKEN from response.sandboxToken, and expiresAt from the response.

4. Wait until the sandbox is ready.

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

5. Run commands or send a task message.

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 blockers."
  }'

6. Keep the run inspectable.

Create workflow records, approval records, trace events, and short non-secret memory. Ask for approval before publishing, deleting, installing system packages, sending messages, or changing accounts.

7. Clean up.

curl -sS -X DELETE "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
```

## Useful sandbox jobs

- 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: track weekly ops, cost, security, or account-review jobs with workflow metadata.
- Human handoffs: store traces and short non-secret memory so a teammate or follow-up agent can resume.
- LLM tool orchestration: expose sandbox creation as a tool and keep sandbox tokens in orchestration state.

## Practical recipes

Repo triage from an issue:

```js
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',
  },
})
```

CI smoke check:

```bash
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
  }'
```

Approval-gated publish:

```bash
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
  }'
```

Human or agent handoff:

```bash
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."
  }'
```

## Lifecycle examples

List account-owned sandboxes:

```bash
curl -sS "https://clankercloud.ai/api/sandboxes" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY"
```

Inspect one sandbox:

```bash
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
```

Wait for a sandbox to become ready:

```bash
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
```

Delete the sandbox when the task is finished:

```bash
curl -sS -X DELETE "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
```

## Account auth

Create a user account:

```bash
curl -sS "https://clankercloud.ai/api/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "user@example.com",
    "password": "choose-a-password",
    "name": "User"
  }'
```

Create an agent account:

```bash
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" }
  }'
```

Send account tokens as `X-API-Key: <token>` or `Authorization: Bearer <token>`.

## LLM tool schema

```json
{
  "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"]
    }
  }
}
```

Minimal dispatcher for an LLM tool call:

```js
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',
    },
  })

  return {
    sandboxId: created.box.id,
    sandboxToken: created.sandboxToken,
    expiresAt: created.box.expiresAt,
  }
}
```

## Agent operating rules

- Create one sandbox per task.
- Store the sandbox id and sandbox token from the create response.
- 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.

## Runner examples

JavaScript helper:

```js
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
}
```

Python helper:

```python
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"},
)
```

Webhook-style workflow trigger:

```bash
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"]
  }'
```

## Workflow state

Read platform state:

```bash
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/platform" \
  -H "X-API-Key: $CLANKER_SANDBOX_TOKEN"
```

Create a workflow:

```bash
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"]
  }'
```

Create an approval gate:

```bash
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"
  }'
```

## Paid outputs

Publish inline HTML:

```bash
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>"
  }'
```

Explain sandbox state:

```bash
curl -sS "https://clankercloud.ai/api/sandboxes/$SANDBOX_ID/explain" \
  -H "X-API-Key: $CLANKER_CLOUD_API_KEY"
```

Related:

- [Sandbox API](https://clankercloud.ai/api)
- [Cloud for Agents](https://clankercloud.ai/cloud-for-agents)
- [MCP setup](https://clankercloud.ai/mcp)
