Engineering

Stream Live Agent Progress with SSE and Last-Event-ID

Lisa Chen||6 min
Home

Most computer use APIs give you a final status. You POST a task, wait, and GET a result. That works for batch jobs but not for interactive sessions where you want to log, retry, or cancel in real time. The Coasty Computer Use API solves this with Server-Sent Events (SSE) on /v1/runs/{id}/events. You get a continuous stream of steps, states, and errors as the agent drives the desktop. You reconnect with Last-Event-ID to resume exactly where you left off.

How SSE on /v1/runs/{id}/events works

Start a task with POST /v1/runs. The response includes a run_id. Then open an SSE connection to GET /v1/runs/{run_id}/events. The server streams lines prefixed with data: . Each line is a JSON event with fields like type, step_id, state, and message. When the connection drops, send a GET with the Last-Event-ID header. The server resumes from that event ID without re-sending earlier steps. This gives you a live log, retries, and cancellation without polling.

python
import os
import json
import requests

API_KEY = os.getenv('COASTY_API_KEY')
BASE = 'https://coasty.ai/v1'

# 1. Start a run
run_resp = requests.post(
    f'{BASE}/runs',
    headers={'X-API-Key': API_KEY, 'Content-Type': 'application/json'},
    json={
        'machine_id': 'your-machine-id',
        'task': 'Open Chrome and navigate to coasty.ai',
        'cua_version': 'v4',
        'max_steps': 50,
        'deadline_seconds': 300,
        'on_awaiting_human': 'pause'
    }
)
run = run_resp.json()
run_id = run['run_id']

# 2. Stream events with SSE + Last-Event-ID
last_event_id = None
while True:
    params = {'Last-Event-ID': last_event_id} if last_event_id else None
    resp = requests.get(
        f'{BASE}/runs/{run_id}/events',
        headers={'X-API-Key': API_KEY},
        params=params,
        stream=True
    )
    for line in resp.iter_lines():
        if not line:
            continue
        if line.startswith(b'data: '):
            data = json.loads(line[6:])
            print(data)
            last_event_id = data.get('event_id')
        if resp.status_code == 204:
            break
    if resp.status_code == 204:
        break
    if last_event_id is None:
        break

print('Run finished')

Event format and fields

  • Each event is a JSON object in the SSE data line.
  • event_id is an integer used for Last-Event-ID.
  • type can be step, state, error, or cancelled.
  • step_id is the unique ID for that step (useful for retries).
  • state is one of queued, running, awaiting_human, succeeded, failed, cancelled, timed_out.
  • message contains human-readable text from the agent or the server.
  • You can cancel the run from any state with POST /v1/runs/{id}/cancel.
  • You can resume with POST /v1/runs/{id}/resume after a failure.

Use Last-Event-ID to reconnect without missing events.

Where this beats brittle automation

Traditional automation relies on brittle selectors and static API endpoints. If a UI changes, your script breaks. The Coasty Computer Use agent reads the screen, reasons about what it sees, and acts like a human. The SSE stream lets you observe that reasoning in real time. You can log every decision, retry on failure, cancel or pause on human interaction, and resume later. You get observability and control that API-only tools cannot provide.

Start streaming your agent progress with SSE and Last-Event-ID. Build dashboards, live logs, and interactive workflows without polling. Get your API key at https://coasty.ai/developers.

Want to see this in action?

View Case Studies
Try Coasty Free