Guide
Developer API
Everything the dashboard does to a coding harness, you can do from a script. Create a box, hand an agent a prompt, watch the log stream back, open a shell into it when you want to look, throw it away when you are done. One bearer key, ordinary HTTP.
What This API Controls
Coding harnesses: disposable cloud boxes with a persistent /workspace directory and a coding agent installed. You give one a prompt, it edits files and runs commands, and you read what happened. The dashboard version of this is described in coding harness hosting — this page is the same product with the buttons removed.
Worth being clear about what it is not, because the names sit close together:
- To send a message to your OpenClaw or Hermes bot from code, you want the instance’s own Chat API (the MCP button on its card) — an OpenAI-compatible
/v1/chat/completionsroute. See the chat API guide. - To deploy and manage bots on behalf of other people, that is the reseller programme, which has its own endpoints and its own billing. See Build & Resell.
- This API is for automating your own account, against the workspace slots your plan already includes.
So there is no OpenClaw-versus-Hermes split on this page, and that is not an omission: a hosted Coding Harness is neither. It is a third thing alongside them — a box running a coding CLI rather than a chat agent — so the endpoints, the supported CLI list and the billing are the same whichever framework your bots happen to run. Where the two frameworks do differ is in how you talk to a bot from code, and that is the Endpoint, which behaves the same on both.
Get a Key
Open the dashboard and go to Developer in the sidebar. Create a key and copy it somewhere safe — it is shown once, at creation, and never again.
Every request carries it as a bearer token, and the base URL is the site itself:
export OPENCLAW_API_KEY="…"
BASE=https://openclawlaunch.com/api/v1The Developer page is open to any signed-in account, so you can read the reference and hold a key before you subscribe. What the key can do is what the plan gates: creating, resetting, wiping, opening a terminal and starting a run answer 402 without an active subscription, while listing, inspecting, deleting and polling a run stay open — so you are never locked away from a workspace you still hold a slot for.
Create a Workspace and Start Work in One Call
curl -X POST $BASE/coding-workspaces \
-H "Authorization: Bearer $OPENCLAW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"harness":"opencode","prompt":"Refactor /workspace/api into modules and run the tests"}'
# → {"id":"…","harness":"opencode","run":{"run_id":"…","log_url":"…"}}harness picks the coding agent: opencode (the default), claude, codex, openclaude, zero, aider, pi, or dsh for the DeepSeek harness. Runs are asynchronous — the call returns a run_id immediately and the agent keeps working for however many minutes the job takes.
Follow the Run
Poll it:
curl $BASE/coding-workspaces/$ID/runs/$RUN_ID \
-H "Authorization: Bearer $OPENCLAW_API_KEY"
# → {"state":"succeeded","exit_code":0,"log_tail":"…"}Or stream it, which is usually what you actually want:
curl -N "$BASE/coding-workspaces/$ID/runs/$RUN_ID?stream=true" \
-H "Authorization: Bearer $OPENCLAW_API_KEY"
# event: log
# data: {"from":0,"to":812,"text":"Reading /workspace/api…"}
# event: end
# data: {"state":"succeeded","exit_code":0,"reason":"finished"}The difference matters more than it looks. The plain GET returns a snapshot of the tail of the log, so polling re-reads the same window and anything that scrolled past between two polls is gone for good. With stream=true each log event carries only the bytes written since the last one, and to tells you where to resume if the connection drops. For a long run, stream it.
Reuse the Box
A workspace persists, so the second task does not need a second box — and it starts with the first task’s work already on disk:
curl -X POST $BASE/coding-workspaces/$ID/runs \
-H "Authorization: Bearer $OPENCLAW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"Now add tests for the module you just extracted"}'Three ways to clear one out, and the difference is worth reading before you script any of them:
resetrebuilds the container but keeps both volumes — your/workspacefiles and the home directory, which is where a coding CLI’s login lives. Use it when the box is in a bad state but the work and the logins should survive.wipedrops both volumes. That is the files and the CLI logins, not just the workspace contents — a fresh box in everything but name.DELETEremoves the workspace entirely and frees the plan slot.
Open Your Own Terminal
When you want to look at the box yourself rather than read a log, POST /api/v1/coding-workspaces/{id}/terminal hands back a short-lived, single-use WebSocket address — a wss:// URL, not an SSH host, so you connect with a WebSocket-capable client rather than ssh. It is the same door the dashboard’s Open Terminal button uses, handed to you instead of to a browser tab.
Secrets, Network, and Isolation
Three things are worth setting deliberately at create time, and all three fail closed — if the conditions cannot be met the call returns an error rather than quietly handing you a weaker box.
- env — environment variables for the workspace. These can be replaced later without rebuilding:
PUT /api/v1/coding-workspaces/{id}/envwith{"env":{"API_TOKEN":"…"}}. It is a whole-set replace of the stored set rather than a merge — what you send is what is stored — and{"env":null}clears it. Keys a harness actually reads (OPENROUTER_API_KEY,ANTHROPIC_API_KEY,OPENAI_API_KEY,DEEPSEEK_API_KEY) are verified against the provider when you set them, so an invalid key is rejected up front instead of failing mid-run. Know when the change lands, because it is not instant everywhere: the next agent run gets the new set, but a process already running keeps the environment it started with, and the container’s own baked environment — which every terminal shell inherits, newly opened or not — only catches up on areset. So clearing a leaked credential here is the first step, not the whole job; reset the box to be sure it is gone from the shells too. - network_allowlist — hostnames the box may reach, e.g.
["github.com","*.githubusercontent.com"]. Names only: no scheme, path, port or IP literals, a leading*.wildcard allowed, and HTTPS only — plain port 80 is refused. This is the difference between an agent that can fetch your repo and one that can reach anything on the internet. - gvisor — set
trueto run the workspace under gVisor, with its own userspace kernel between the box and the host.
A Realistic Use
The shape this API is good at is “a job, in a box, that I did not have to keep alive”:
- A nightly task that opens a workspace on a repository, asks an agent to update dependencies and run the suite, and posts the log where your team reads it.
- A queue worker that spawns one workspace per ticket, so two agents working on two bugs cannot see or break each other’s files.
- A CI step that asks an agent to explain a failing test, streaming its reasoning into the build log.
- Your own front-end over the top: the API is the whole product, so a Slack command or an internal dashboard is a small amount of glue.
Practical Notes
- Keys are shown once. Losing one means creating another, not recovering it.
- A workspace occupies a plan slot until it is deleted. Automations that create boxes should delete them too, or they will run into the slot ceiling.
- Give an agent one clear task per run. “Refactor this module and run the tests” goes better than a paragraph of unrelated requests, in exactly the way it does when a person is asked.
- Prefer a narrow
network_allowlist. Agents follow instructions found in the material they read, so limiting where a box can reach is worth the two minutes it takes.
Try It
Open Developer in the dashboard sidebar, create a key, and paste the create call above. The full endpoint reference lives on that page beside the key, and it is the version that moves with the product.
Related: coding harness hosting, the instance chat API, SSH access, coding plans compared.