Skip to main content

Error shape

Every /v1 error has the same shape, with an HTTP status to match:
type is stable and meant for your code. message is written for a person and may change; log it or show it, but don’t match on it. Some errors add fields, such as active_task_id above, or code and answered_by when a question was already answered.

Common causes and fixes

400 invalid_request

  • "prompt" (string) is required: send a non-empty prompt when starting a task.
  • Metadata rejected: metadata must be an object with up to 50 keys, keys up to 40 characters, and string values up to 500 characters. Numbers and nested objects aren’t allowed; send "42", not 42.
  • Agent id rejected: agent_id is 2 to 40 lowercase letters, numbers and dashes. effort is low, medium, high or null.
  • Webhook URL refused: it must be https and resolve to a public address. See Webhooks.
  • /respond without an id: send question_id with answer, or approval_id with decision.

401 authentication

Send Authorization: Bearer gh_live_… with an org API key from Settings → API keys. Check that the key wasn’t revoked, and that you aren’t sending a session token (gh_sk_…), which only works with the older session-token API.

402 payment_required

Starting a task on the free plan after its free minutes are used, or in an org that has no free minutes. An owner can pick a plan in the console under Settings → Plan and usage. A running task on the free plan is also stopped when the minutes run out; its stopped event says so.

403 permission

The signed-in person’s role is too low, for example a member deleting a session. API keys act with the admin role, so this comes up mainly with console sign-ins.

404 not_found

The id doesn’t exist in the org the key belongs to. Session ids are codes like K7QM-24XP; task ids start with task_. A session whose code has expired returns 404 when you start a task on it: create a new session.

409 conflict

  • “No computer is connected to this session.” The session’s status isn’t connected. The customer may have quit the app, closed the laptop or lost the network. Wait for session.connected, or ask them to open GuidingHand.
  • “A task is already running on this computer.” One task runs at a time per computer. error.active_task_id is the running task: follow it to the end, or stop it with POST /v1/tasks/{task_id}/stop.
  • “An agent with that address already exists.” Pick another agent_id, or PATCH the existing agent.
  • “That was already answered by the person at the computer.” (code: "already_answered", answered_by: "customer") The customer answered the question, or decided the approval, on their screen before you did, and theirs is the one the task used. Nothing to fix: carry on following the task. With answered_by: "operator", someone on your team (another process, or the console) answered first. See questions the customer can answer and approvals the customer can decide.
  • “That question/approval is not pending.” (code: "not_pending") The id belongs to an earlier question, or the task has ended. Read the task again and respond to the current pending.

429 rate_limit

  • Too many requests (see rate limits). Wait and retry with backoff.
  • Your plan’s limit on tasks running at the same time across the org. Wait for a task to finish, or move to a plan with more.

500 server_error

Retry with backoff. If you start tasks with a request_id, retrying is safe: you get the same task rather than a second one.

Tasks that fail

A failed task is not an HTTP error: the task ran and couldn’t finish. error has the reason, for example:
  • the computer disconnected in the middle of a step,
  • macOS was dropping the app’s clicks and typing (a permission problem the app reports and offers to fix with a restart),
  • the task ran 150 steps without finishing,
  • the server was restarted during the task. Start it again.
Retry by starting a new task with a new request_id. For recurring failures, the task’s replay_url and GET /v1/tasks/{task_id}?include=trace show what happened; the trace is safe to share with GuidingHand support.

Pagination

GET /v1/sessions and GET /v1/tasks return the newest first, one page at a time:
  • limit sets the page size, 1 to 100 (default 20).
  • When has_more is true, pass next_cursor as cursor to get the next, older page. When it is false, next_cursor is null.
  • Keep the same filters (session_id, agent_id, status) on every page.
(gh is the helper from the Quickstart.) GET /v1/agents returns all agents in one page.

Rate limits

Past a limit, requests return 429 rate_limit. Long polls count as one request each, so following a task with wait_ms=25000 uses about 144 requests an hour.