Engineering

Human in the Loop Automation: Awaiting Human and Resume in the Runs API

Daniel Kim||6 min
Ctrl+H

Automated agents can handle most UI tasks, but some steps need human judgment, approving a purchase, reading a CAPTCHA, or interpreting a security prompt. The Coasty runs API can pause at those moments. When a run hits the awaiting_human state, you can inspect the screen, verify the context, then resume the task. This keeps automation robust without forcing you to hardcode brittle selectors or manual workflows.

How awaiting_human and resume work

When you create a task run with on_awaiting_human, the agent stops and sends a status update. The response includes the current state, the last action, and the last screenshot. You can inspect the screenshot to understand why the agent paused, then call POST /v1/runs/{id}/resume with a clear instruction to continue. The agent reads the new instruction and proceeds until it reaches succeeded, failed, cancelled, or timed_out.

bash
#!/usr/bin/env bash
set -e

COASTY_API_KEY="${COASTY_API_KEY}"
BASE_URL="https://coasty.ai/v1"

# Create a run that pauses on human approval
RUN_RESPONSE=$(curl -s -X POST "${BASE_URL}/runs" \
  -H "Authorization: Bearer ${COASTY_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "machine_id": "machine-abc123",
    "task": "Open Chrome and navigate to example.com, then take a screenshot",
    "cua_version": "v4",
    "on_awaiting_human": "pause",
    "max_steps": 100,
    "deadline_seconds": 600
  }')

RUN_ID=$(echo "$RUN_RESPONSE" | jq -r '.id')
echo "Created run: $RUN_ID"

# Poll until the run reaches awaiting_human
while true; do
  STATUS=$(curl -s -X GET "${BASE_URL}/runs/${RUN_ID}" \
    -H "Authorization: Bearer ${COASTY_API_KEY}" | jq -r '.status')
  echo "Status: $STATUS"
  if [ "$STATUS" = "awaiting_human" ]; then
    break
  fi
  if [ "$STATUS" = "failed" ] || [ "$STATUS" = "cancelled" ] || [ "$STATUS" = "timed_out" ]; then
    echo "Run did not reach awaiting_human: $STATUS"
    exit 1
  fi
  sleep 2
done

# Fetch the run details (last action, screenshot, etc.)
RUN_DETAILS=$(curl -s -X GET "${BASE_URL}/runs/${RUN_ID}" \
  -H "Authorization: Bearer ${COASTY_API_KEY}")
echo "Last action: $(echo "$RUN_DETAILS" | jq -r '.last_action')"
echo "Screenshot available at: $(echo "$RUN_DETAILS" | jq -r '.last_action.screenshot_url')"

# Human verification step (your own code here)
echo "Human verification passed. Resuming run..."

# Resume with a clear instruction
RESUME_RESPONSE=$(curl -s -X POST "${BASE_URL}/runs/${RUN_ID}/resume" \
  -H "Authorization: Bearer ${COASTY_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "Continue with the original task: open Chrome, navigate to example.com, and take a screenshot."
  }')

echo "Resume response: $RESUME_RESPONSE"

# Poll until the run finishes
while true; do
  STATUS=$(curl -s -X GET "${BASE_URL}/runs/${RUN_ID}" \
    -H "Authorization: Bearer ${COASTY_API_KEY}" | jq -r '.status')
  echo "Final status: $STATUS"
  if [ "$STATUS" != "running" ]; then
    break
  fi
  sleep 2
done

echo "Run completed with status: $STATUS"

Key fields and behavior

  • on_awaiting_human: set to pause to stop the run and wait for resume.
  • States: queued, running, awaiting_human, succeeded, failed, cancelled, timed_out.
  • Resume endpoint: POST /v1/runs/{id}/resume takes an instruction to continue.
  • Billed at $0.05 per agent step during task execution.
  • Use events (GET /v1/runs/{id}/events) to stream step logs and reconnect with Last-Event-ID.

When you set on_awaiting_human to pause, the run stays in the awaiting_human state until you call resume with a clear instruction.

Where this beats brittle automation

Traditional automation relies on selectors and fixed element IDs, which break when UI changes. By using the computer use API, the agent sees the screen just like a human. When a human approval is needed, the agent pauses and you can inspect the screenshot, then resume with the next instruction. This keeps workflows reliable and adapts to UI changes without rewriting selectors.

Build workflows that know when to ask a human. Use awaiting_human and resume to pause, verify, and continue task runs. Get a key and start running at https://coasty.ai/developers.

Want to see this in action?

View Case Studies
Try Coasty Free