CLOUSD
Open account
LearnBenchmarkSoonHow agents score on Clousd phonesBlogSoonGuides, deep dives and field notesCompareSoonClousd next to the alternatives
BuildIntegrationsSoonMCP, Claude Code, Codex, Cursor, n8nGitHubSDK, MCP server and examples
Read the Docs

Run automation

Tasks

Give a phone the goal in plain words. Clousd's agent does the steps and answers.

A task

Start a run
POST /v1/runs
{
  "task": "Open Settings and tell me the Android version",
  "device": "c3f9a41d2"
}
# → 201 {"run": {"id": "r_8f2c", "status": "queued", …}}

GET /v1/runs/r_8f2c
# → {"run": {"status": "completed", "answer": "Android 15", "steps": 4, "seconds": 21}}

Write the task the way you would for a person: what to open, what to do, what to report back. The agent looks at the screen, taps and types until the goal is reached, and ends with an answer. A phone does one task at a time; another run on the same phone waits in its queue.

Statuses: queued, running, paused (it asks you something), completed, failed, cancelled. Send an Idempotency-Key header to make a retry safe: the same key and body return the same run.

Many phones

Give devices instead of device (up to 32): every phone gets the same task, all at once. The answer is a parent run with one child run per phone; GET /v1/runs?since=… lists them with their own answers.

Follow it live

Server-Sent Events
curl -N -H "Authorization: Bearer cl_live_…" https://api.clousd.com/v1/runs/r_8f2c/events

id: 3
event: step
data: {"n": 3, "tool": "tap", "target": "About phone", "result": "ok"}

id: 6
event: end
data: {"status": "completed"}

Events: status, plan, step, card, answer, message, end. Resume after a dropped connection with ?since=N. Every step is kept: GET /v1/runs/{id}/trajectory lists them and /steps/{n}.jpg is the screen before each one. In the dashboard the same run is a replay you can step through.

Questions and permissions

With "options": {"mode": "ask"} the agent stops before risky steps (sending, paying, deleting) and when it needs something only you know. The run is paused and carries a card: a question with options, or a permission for one action.

Answer
POST /v1/runs/r_8f2c/answer   {"card": "c1", "answer": "the first one"}
POST /v1/runs/r_8f2c/answer   {"card": "c2", "allow": true}
POST /v1/runs/r_8f2c/message  {"text": "use the work email"}
POST /v1/runs/r_8f2c/cancel

Saved logins

Save a login once - in the dashboard (the Sign-in line of a task) or with POST /v1/credentials {"package", "name", "fields": {"username", "password", "totp"}} - and pass it to a run by package and name. The agent types the values on the phone; they never reach the model, the run's steps or the API response, and GET /v1/credentials lists only which fields are set.

A run with a login
{
  "task": "Sign in to the app and tell me how many orders are on the Orders page",
  "device": "c3f9a41d2",
  "credentials": [{"package": "com.example.shop", "name": "work"}]
}

Structured output

Add a JSON Schema in options.output_schema and the answer also comes back as structured_output in that shape, ready for your code.

Options
"options": {
  "output_schema": {"type": "object", "properties": {"orders": {"type": "integer"}}},
  "max_steps": 60,
  "timeout": 600
}
# → "structured_output": {"orders": 3}

On a schedule

A schedule starts the same run by itself: POST /v1/schedules with name, phones, task, at ("HH:MM"), tz (a time zone like Europe/Berlin), days (1 to 7, Monday is 1; empty means every day) and optional credentials. Pause it with /toggle and remove it with /delete. To hear when a run ends, add a webhook.