Cloud Agent Runs and Events
Use the environment variables from the quickstart. A run is one task on an agent. Its ID stays stable while the agent works, including when you steer an active run with a follow-up.
Submit a task
Section titled “Submit a task”RUN=$(curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ -H "Content-Type: application/json" \ --data '{"prompt":"Inspect the workspace and summarize the project."}' \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs") || exit 1export RUN_ID=$(printf '%s' "$RUN" | jq -er '.id')The response is 202 Accepted, not a completed result. prompt is required
and its trimmed UTF-8 representation is limited to 65,536 bytes. It may be empty
only when images are supplied. Only one run can be active per harness; a
concurrent submission returns a conflict. Wait for completion or use a follow-up.
Creation also accepts optional resume_session_id and parent_run_id for
continuation metadata. Prefer the resume or follow-up endpoints below when
continuing a known run: they obtain the session and parent from that run.
Include images
Section titled “Include images”Read a local image and send raw base64, without a data-URL prefix:
base64 < screenshot.png | tr -d '\n' | jq -Rs '{ prompt: "Describe this screenshot.", images: [{type: "image", data: ., mime_type: "image/png"}] }' | curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ -H "Content-Type: application/json" \ --data-binary @- "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs"Use type: "image" and one of image/png, image/jpeg, image/gif, or
image/webp. There is a maximum of eight images per request. The chosen model
must support image input. Follow-ups accept the same image array.
Request size limits still apply to the base64-encoded JSON; see
Limits.
Read state and history
Section titled “Read state and history”curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs?limit=100" | jq .
curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID" | jq .Listing returns a JSON array, newest first, filtered to this harness. The public
contract permits limit from 1 to 500, defaulting to 100. There is no run-list
pagination cursor.
| Run field | Meaning |
|---|---|
id, agent_id |
Run and agent identifiers. |
status |
queued, running, cancelling, finished, failed, or cancelled. |
prompt |
Original prompt, nullable. Active follow-ups do not replace this stored original. |
result |
Assistant reply when available, nullable. Fetch this after completion for the final answer. |
error |
Failure description, nullable. |
parent_run_id |
Prior run for a continuation, or null. |
dsh_session_id |
Pi session ID, or null before a session is established. |
created_at, updated_at |
Timestamp strings, nullable. |
finished, failed, and cancelled are terminal states. Cancellation and
failure can still leave partial output or changed files. A run’s state is
independent of the runtime state returned by the agent endpoint.
Follow up or resume
Section titled “Follow up or resume”Use a follow-up for conversation-style interaction:
curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ -H "Content-Type: application/json" \ --data '{"prompt":"Focus on the authentication module."}' \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID/follow-ups" | jq .- Active run: interrupts the current Pi turn, then submits the new prompt in the same conversation and returns the same run ID.
- Terminal run: creates a new run using the previous session ID and sets
parent_run_idto the previous run. - Synthetic bootstrap reply without a session: creates a fresh run.
Always take the next run ID from the response, since terminal-state races can change which behavior applies.
To explicitly create a continuation after a prior run:
curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ -H "Content-Type: application/json" \ --data '{"prompt":"Continue with the next step."}' \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID/resume" | jq .Resume returns 202 with a new run. The prior run must have a session.
The server sets resume_session_id and parent_run_id from it, overriding
those fields in the submitted body.
The current supervisor keeps one Pi process and conversation per harness. Resume records continuation metadata and submits to that harness’s current conversation; it does not switch to or rewind an arbitrary historical session. Do not rely on it to restore a specific conversation after a supervisor restart.
Cancel
Section titled “Cancel”curl --fail-with-body --silent --show-error -X DELETE \ -H "Authorization: Bearer $RUNTA_TOKEN" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID" | jq .This returns 200 with run state. Cancelling a terminal run returns its
existing state. Cancellation aborts the active turn; it does not remove history,
delete the runtime, or undo workspace changes. Poll until terminal if the
returned status is still cancelling.
Stream run events
Section titled “Stream run events”curl --fail-with-body --silent --show-error --no-buffer \ -H "Authorization: Bearer $RUNTA_TOKEN" \ -H "Accept: text/event-stream" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID/events?after=-1"The response is a Server-Sent Events stream:
| SSE event | ID | Data |
|---|---|---|
run.status |
status:<state> |
Runtime-side run snapshot when the status changes. |
pi.event |
Decimal sequence number | Dynamic Pi event, including seq, type, and emitted_at_unix_ms. |
error |
None | JSON object with message; indicates a stream failure. |
Keep-alive comments are sent about every 15 seconds. A terminal status drains
the remaining events and closes the stream. Handle both in-band error events
and transport failures. Fetch the run afterward to distinguish success, failure,
and cancellation.
The run.status data is the guest’s stored run object, not the public
CloudAgentRun response. In particular it uses session_id; normal run GET
responses expose that as dsh_session_id.
Render Pi output
Section titled “Render Pi output”Current event types include message_start, message_update, message_end,
tool_execution_start, tool_execution_update, tool_execution_end, and
agent_settled. Preserve unknown event fields and ignore unknown types safely.
The OpenAPI event schema is deliberately open.
Text deltas occur in
assistantMessageEvent.type === "text_delta"; append
assistantMessageEvent.delta. Start a new assistant message for an assistant
message_start. Tool execution and replacement turns can produce multiple
assistant messages in one run, so concatenating every text delta into one
final answer is incorrect. Use the completed run’s result for that answer.
Reconnect without replaying everything
Section titled “Reconnect without replaying everything”Persist the largest successfully processed pi.event sequence number, scoped
to the run ID. Reconnect with ?after=<sequence>; events with seq > after are
returned. The default after=-1 replays from the beginning.
Do not use status:running as a cursor. run.status events can be repeated on
reconnection and have no numeric cursor. The handler reads the after query
parameter, not the browser’s Last-Event-ID header. De-duplicate pi.event
records by run ID and sequence if processing can be retried.
Native browser EventSource cannot set a Bearer authorization header. Use an
authenticated fetch-stream client or your backend’s proxy for SSE, and keep the
Runta API key on your backend.
Replay session events
Section titled “Replay session events”Obtain the session ID from the run and pass it as session_id:
SESSION_ID=$(curl --fail-with-body --silent --show-error \ -H "Authorization: Bearer $RUNTA_TOKEN" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/runs/$RUN_ID" | jq -er '.dsh_session_id') || exit 1
curl --fail-with-body --silent --show-error --get \ -H "Authorization: Bearer $RUNTA_TOKEN" \ --data-urlencode "session_id=$SESSION_ID" \ --data-urlencode "after=-1" \ "$RUNTA_API_URL/v2/agents/$AGENT_ID/events" | jq .The JSON response contains agent_id, session_id, and events. It is a
snapshot, not a live stream. after has the same exclusive sequence semantics
and must be at least -1.
The current helper reads the event log of one matching run for that session; it does not concatenate all runs in a shared conversation. Sequence numbers restart for each run. For complete history, list runs and replay each run’s SSE endpoint with its own cursor.
