API / stream-and-cancel-a-cloud-agent-run-via-api

API

Stream and cancel a Cloud Agent run with the Cloud Agents API

Follow one run over SSE with GET https://api.cursor.com/v1/agents/{id}/runs/{runId}/stream, and stop it with POST .../cancel. Official reference: Cloud Agents API → Stream A Run / Cancel A Run.

Authenticate with Basic or Bearer. The stream covers only the requested run (no replay of prior runs). Cancellation is terminal — status becomes CANCELLED and cannot resume; continue with a new Create A Run on the same agent.

Stream request

curl --request GET \
  --url https://api.cursor.com/v1/agents/bc-00000000-0000-0000-0000-000000000001/runs/run-00000000-0000-0000-0000-000000000001/stream \
  -u YOUR_API_KEY: \
  --header 'Accept: text/event-stream'

Event types

Event Payload
status { runId, status } — sticky framing; re-sent at the top of every reconnect; has no id line.
assistant { text } delta
thinking { text } delta
tool_call { callId, name, status, args?, result?, truncated? }status is running or completed
interaction_update Full SDK-shape stream; ignore if you only need simplified events
heartbeat {} keepalive
result { runId, status, text?, durationMs?, git? } — terminal; git is the agent's current branches
error { code, message }
done {} stream complete

Most events include an opaque id line (do not parse it). After disconnect, reconnect with Last-Event-ID set to the latest id from this run; a foreign id returns 400 invalid_last_event_id. Expect another status event after a successful resume.

Retention: responses include X-Cursor-Stream-Retention-Seconds. After that window, the endpoint may return 410 stream_expired — read terminal state via Get A Run instead of retrying the stream.

Example stream:

event: status
data: {"runId":"run-00000000-0000-0000-0000-000000000001","status":"RUNNING"}

id: 1713033000000-0
event: assistant
data: {"text":"I'll update the README now."}

id: 1713033005000-0
event: tool_call
data: {"callId":"call-1","name":"read_file","status":"running","args":{"path":"README.md"}}

id: 1713033010000-0
event: result
data: {"runId":"run-00000000-0000-0000-0000-000000000001","status":"FINISHED","text":"Added README.md with installation instructions.","durationMs":12357,"git":{"branches":[{"repoUrl":"github.com/your-org/your-repo","branch":"cursor/add-readme-a1b2"}]}}

id: 1713033010000-0
event: done
data: {}

Cancel A Run

curl --request POST \
  --url https://api.cursor.com/v1/agents/bc-00000000-0000-0000-0000-000000000001/runs/run-00000000-0000-0000-0000-000000000001/cancel \
  -u YOUR_API_KEY:

Response:

{
  "id": "run-00000000-0000-0000-0000-000000000001"
}

Cancelling a run that is already terminal, or was never active, returns 409 run_not_cancellable.

Related how-tos