HTTP API

Everything the dashboard and the CLI do goes through this API. Base URL: https://api.waken.sh. Requests and responses are JSON. Errors look like {"error": "..."} with a meaningful status code (see errors).

Authentication

Send an API key as a bearer token. Create keys in the dashboard under Developers. A key only sees the agents of its own account.

Terminal
curl https://api.waken.sh/agents \
-H "Authorization: Bearer $WAKEN_KEY"
ScopeAllows
provisionCreate agents
deployMessage agents, run commands, read and write files, schedules, checkpoints
secretsSet environment variables, change the model or the harness
computersDesktops: screenshots, actions, live view, the MCP server
manageEverything, including deleting agents and managing keys and webhooks

Give each part of your system the smallest scope it needs. A key for your chat backend only needs deploy.

Keys are managed from the dashboard, or with the API itself: POST /keys ({"name": "prod", "scopes": ["provision", "deploy"]}, the key is returned once), GET /keys to list them without their secret, DELETE /keys/{id} to revoke one. Scopes: provision creates agents, deploy talks to them and handles their files, secrets changes their variables, model or harness, computers drives desktops and the MCP server, manage does everything, deletion and keys included. Listing and reading agents needs no particular scope.

Create an agent

POST /agents
curl -X POST https://api.waken.sh/agents \
-H "Authorization: Bearer $WAKEN_KEY" \
-d '{
"name": "customer-42",
"external_id": "customer-42",
"model": { "provider": "anthropic", "api_key": "sk-ant-..." },
"spend_cap_usd": 10,
"idle_s": 300
}'
# 201
{ "id": "4ec0b05a", "name": "customer-42", "status": "running", "harness": "claude-code", ... }
FieldMeaning
nameA label. Lowercase letters, digits and dashes
external_idYour own id for this agent. Creating twice with the same one returns the same agent: safe to retry
harnessclaude-code (default), codex, openclaw, cursor, hermes
modelprovider, name (optional), api_key. See Models and keys
envExtra environment variables for the agent
spend_cap_usdToken budget, 5 by default
idle_sSeconds without activity before it sleeps. 300 by default, 0 for always on (paid option)
desktoptrue to give it a Linux desktop (paid plans)
mem_mib, disk_gibBigger machine: up to 8192 and 100 (paid option)
imageA public container image instead of a harness. See Container images

Talk to it

POST /agents/{id}/message
curl -X POST https://api.waken.sh/agents/4ec0b05a/message \
-H "Authorization: Bearer $WAKEN_KEY" \
-d '{ "text": "Sort my March receipts" }'
{ "text": "Done, 14 receipts sorted.", "ms": 4936 }

If the agent is asleep, this call wakes it first. You never call wake yourself. The request stays open until the agent answers: allow a few minutes of timeout on your side.

Sleep, checkpoints, rewind

RouteWhat it does
GET /agentsList your agents. ?external_id= to find one
GET /agents/{id}One agent: status, harness, model, size
POST /agents/{id}/sleepSleep now. It wakes on the next call that needs it
POST /agents/{id}/wakeWake it without sending a message, for example before a burst of calls
POST /agents/{id}/restartRestart the harness process. Files and checkpoints untouched
POST /agents/{id}/snapshotTake a checkpoint now
GET /agents/{id}/snapshotsList its checkpoints
POST /agents/{id}/restoreRewind: {"snapshot_id": "..."}, or an empty body for the latest
GET /agents/{id}/usageSpend so far and the cap
PUT /agents/{id}/sizeChange memory and disk: {"mem_mib": 4096, "disk_gib": 20}
DELETE /agents/{id}Delete it, its files and its checkpoints

Files and commands

Paths are relative to the agent's working folder, /root/work. Files up to 100 MB.

RouteWhat it does
GET /agents/{id}/files/list?path=List a folder
GET /agents/{id}/files/download?path=Download a file
PUT /agents/{id}/files/write?path=Write a file: the request body is the content
POST /agents/{id}/filesUpload a whole folder as a gzipped tarball
POST /agents/{id}/files/mkdir, /move{"path": "..."} and {"from": "...", "to": "..."}
DELETE /agents/{id}/files/delete?path=Delete a file or a folder
POST /agents/{id}/exec{"command": "ls -la", "timeout_s": 60}. Returns exit_code and output
GET /agents/{id}/logs?lines=100What the harness printed
GET /agents/{id}/consoleThe machine's boot log, when something looks wrong at a lower level

Model, harness and variables

RouteWhat it does
PUT /agents/{id}/model{"model": {provider, name, api_key}}: same harness, new model
PUT /agents/{id}/harness{"harness": "codex", "model": {...}}: new harness, files kept, conversation handed over
GET /agents/{id}/envThe names of its variables. Values are never returned
PUT /agents/{id}/env{"env": {"FOO": "bar"}, "unset": ["OLD"], "reload": true}. reload restarts the harness so it sees the change

Schedules and incoming webhooks

POST /agents/{id}/triggers
# Every weekday at 09:00 UTC, wake the agent and send it this message
{ "cron": "0 9 * * 1-5", "message": "Check the inbox and file what arrived" }

GET /agents/{id}/triggers lists them, DELETE /agents/{id}/triggers/{tid} removes one, and POST /agents/{id}/triggers/{tid}/run fires one right now, to test it.

GET /agents/{id}/webhook returns a secret URL. Any POST to it becomes a message to the agent, 30 per minute at most: plug it into Stripe, GitHub or a form. POST /agents/{id}/webhook/rotate replaces the URL.

Events sent to you

Register a URL with POST /webhooks ({"url": "https://...", "events": ["agent.capped"]}, or no events for all of them). The response contains a signing secret, shown once. Each delivery carries X-Waken-Event, a unique X-Waken-Delivery id, and X-Waken-Signature: sha256= followed by the HMAC SHA-256 of the raw body with your secret.

  • agent.deployed, agent.sleeping, agent.woken, agent.restored, agent.resized, agent.deleted
  • agent.capped: the spend cap was reached
  • agent.error
  • computer.takeover_requested: an agent on a desktop needs a human
The API is in early access. Every route on this page works today. If one has to change, you hear about it before it does.
Next: desktops and MCP