Run automation
Tasks
Give a phone the goal in plain words. Clousd's agent does the steps and answers.
A task
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
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.
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/cancelSaved 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.
{
"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": {
"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.