At a glance
GET /api/health
POST /api/runs # real repo run in the CloudboxRunner container
POST /api/computers # materialize a ComputerSpec workspace
POST /api/brief
GET /api/c/:id/list
GET /api/c/:id/read?path=...
POST /api/c/:id/write
POST /api/c/:id/ask
POST /api/c/:id/submit
GET /api/c/:id/grade
GET /api/c/:id/receipts
GET /api/c/:id/spec
When CLOUDBOX_API_TOKEN is set, authenticated endpoints require Authorization: Bearer $CLOUDBOX_API_TOKEN (or x-cloudbox-token).
Health
curl http://localhost:8799/api/health
# → { "ok": true, "name": "cloudbox" }
Run a real repo
The runner surface. Cloudbox boots the cloudbox-runner Cloudflare Container, clones a public GitHub repo, executes commands, then verify, collects the requested artifact, and returns the trail.
curl -X POST https://cloudbox.coey.dev/api/runs \
-H "authorization: Bearer $CLOUDBOX_API_TOKEN" \
-H 'content-type: application/json' \
-d '{
"repo": "https://github.com/acoyfellow/cloudbox",
"commands": ["pnpm install --ignore-scripts"],
"verify": ["pnpm run build", "pnpm run test"],
"artifact": "HANDOFF.md"
}'
Response shape:
type ContainerRunResult = {
runId: string;
ok: boolean;
receipts: ContainerRunReceipt[]; // clone, command, verify, diff steps
runnerReceipts: RunnerLifecycleEvent[]; // container boot / request / error
artifact?: { path: string; content: string } | null;
diff?: string;
error?: string;
};
Each ContainerRunReceipt carries cmd, code, signal, stdout, stderr, startedAt, finishedAt. Non-zero verify exit codes set ok: false and return HTTP 422.
runnerReceipts are the computer proof layer. They show whether the CloudboxRunner Durable Object started or reused a Container, how many readiness attempts were needed, how long boot took, and when the runner responded. Typical events are runner.container.start, runner.container.ready_attempt, runner.container.ready, runner.response, and runner.container.not_ready.
Recent runs are available when D1 is bound:
GET /api/runs/recent
GET /api/runs/:runId
Materialize a workspace
curl -X POST http://localhost:8799/api/computers \
-H 'content-type: application/json' \
-d @spec.json
# → { "id": "cb_abc123…", "baseUrl": "/api/c/cb_abc123…" }
The id is a deterministic content hash of the spec. The same spec returns the same id every time — re-materializing is idempotent.
Brief → spec
curl -X POST http://localhost:8799/api/brief \
-H 'content-type: application/json' \
-d '{"brief":"A staff engineer triaging an open PR with failing CI."}'
# → { "spec": { profile, filesystem, collaborators, objectives, rubric } }
The draft spec is a starting point — edit it, then POST it to /api/computers to materialize. v0 is a deterministic stub; the Workers AI-backed structured generator lands in a later phase.
List files
curl http://localhost:8799/api/c/$ID/list
# → { "files": [{ "path": "...", "kind": "...", "state": "..." }, ...] }
Read a file
curl "http://localhost:8799/api/c/$ID/read?path=docs/auth-redesign.md"
# → { "path": "...", "kind": "...", "content": "..." }
Records a read receipt.
Write a file
curl -X POST http://localhost:8799/api/c/$ID/write \
-H 'content-type: application/json' \
-d '{"path":"notes/triage.md","content":"# Notes\n…"}'
# → { "path": "...", "written": <bytes> }
Records a write receipt.
Ask a collaborator
curl -X POST http://localhost:8799/api/c/$ID/ask \
-H 'content-type: application/json' \
-d '{"who":"arch","message":"Should this use a queue?"}'
# → { "from": "arch", "role": "reviewer", "style": "architectural", "reply": "..." }
Records an ask receipt. The who value is the collaborator’s id from the spec.
Submit a decision
curl -X POST http://localhost:8799/api/c/$ID/submit \
-H 'content-type: application/json' \
-d '{"objective":"triage","decision":"request-changes","notes":"..."}'
# → { "objective": "...", "accepted": true }
Records a submit receipt. objective is the objective’s id from the spec.
Grade
curl http://localhost:8799/api/c/$ID/grade
# → {
# "score": 4,
# "max": 5,
# "totalWeight": 6,
# "passed": ["design-first", "decided"],
# "failed": ["right-reviewer"],
# "ungraded": ["explain-ci"],
# "detail": [...]
# }
Pure replay of the receipt log against the rubric. Idempotent — call it as many times as you want; the score is a function of the receipts at that moment.
Receipts
curl http://localhost:8799/api/c/$ID/receipts
# → { "receipts": [{ "ts", "kind", "payload" }, ...] }
The full append-only log. Useful for debugging an agent’s behavior.
Spec
curl http://localhost:8799/api/c/$ID/spec
# → the original ComputerSpec