Skip to main content
A task is what you want done on the customer’s computer, in plain language: “Turn on Dark Mode”, “Connect to the office Wi-Fi called Acme-Guest”, “Export last month’s invoices from Acme Billing to the Desktop”. Describe the outcome, not the clicks. The agent looks at the screen, acts, looks again, and repeats until it is done or needs a person. Start one with POST /v1/sessions/{session_id}/tasks. The prompt can be up to 8,000 characters.

Status lifecycle

done is true for completed, failed and stopped, and nothing changes after that.

Events

Everything a task does is an event with an increasing cursor. Follow them with GET /v1/tasks/{task_id}/events?after={cursor}&wait_ms=25000, or fetch them all with GET /v1/tasks/{task_id}?include=events.
wait_ms holds the request open (up to 55,000 ms) until there is at least one new event, the task ends, or the time runs out. An empty data array just means nothing happened yet; call again with the same after.

Questions and approvals

The agent pauses and asks when it needs a person. While it waits, task.pending is set, the status is waiting_for_user or waiting_for_approval, and the matching webhook (task.waiting_for_user, task.waiting_for_approval) fires. The task waits until it gets an answer or is stopped. Questions are for things only a person knows: which account, which file, which of two printers.
options are suggestions, and may be empty. The answer is free text, up to 4,000 characters (longer answers are cut there). Questions can be answered on the customer’s screen. Unless the agent turns it off (its customer_answers setting), the question also appears in the GuidingHand app with its options, and the customer can answer it there. customer_can_answer is true when they can. Your team can answer too, with /respond or in the console: the first answer is used, and the task’s answer event and the task.question_answered webhook say who gave it (answered_by). So you can relay the question in your chat, or simply wait for the customer to answer it on screen.
If the customer answered first, this returns 409 conflict with code: "already_answered":
Treat that as done, not as a failure: the task already has its answer and carries on. Approvals come before anything consequential or irreversible: purchases, sending messages, deleting data, submitting forms, changing settings, entering personal data. action says exactly what the agent is about to do.
Approvals can be decided on the customer’s screen too. Unless the agent turns it off (its customer_approvals setting), the request also appears in the GuidingHand app, and the customer can allow it or not there. customer_can_approve is true when they can. As with questions, the first decision is used, a later one gets 409 with code: "already_answered", and the approved or denied event and the task.approval_decided webhook say who decided (answered_by). risk is low, medium or high. decision is approve or deny, and the optional note (up to 1,000 characters) is passed to the agent. When you deny an approval the agent asked for, it is told not to do that and carries on another way. The model can also raise its own safety checks, which arrive as approvals with risk: "high"; denying one of those stops the task. Respond only to what is pending now. An id that isn’t pending returns 409 conflict, with error.code saying why: already_answered (with answered_by) when that question or approval has just been answered or decided by someone else, not_pending otherwise (an older id, or a task that has ended).

Idempotency with request_id

Send a request_id of your own (up to 200 characters) when starting a task. If the same request_id was already used on that session, you get the existing task back instead of a new one, whatever its status. Use it so a retried request, after a timeout or a crash, doesn’t run the job twice. Use a new request_id when you do want to run it again.

One task at a time per computer

A computer runs one task at a time. Starting a task while another runs returns 409 conflict, with the running task’s id in error.active_task_id. Wait for it to finish, or stop it with POST /v1/tasks/{task_id}/stop. Your plan also limits how many tasks the whole org runs at once. Past that limit, starting a task returns 429 rate_limit. See Errors.

Stopping

POST /v1/tasks/{task_id}/stop stops the task right away and returns it, with interrupted: false if it had already finished. The customer can stop it too, from the banner or with the keyboard shortcut. See what the customer sees. A task also fails if it runs 150 steps without finishing. Break long jobs into several tasks.

Billing

Tasks use agent minutes, which count only the time a task spends running. Time spent waiting for an answer or an approval is not counted, so a slow reply from a person doesn’t cost you anything.
  • active_seconds is the running time so far.
  • billed_minutes is the running time rounded up to whole minutes, set when the task ends.
  • A task where the model never acted on the computer is free.
The free plan’s minutes are used once per account. When they run out, a running task is stopped and new ones return 402 payment_required. Plans and prices are on guidinghand.ai/pricing.

Listing

GET /v1/tasks lists tasks newest first, filtered by session_id, agent_id or status. Each has recording.frames, the number of recorded screens. See pagination.