Retrieve a session
List sessions
Results are paginated. Filter by agent or bydeployment_id (each scheduled fire is a session tagged with its deployment), and sort by creation time. Each response includes has_more and a next_cursor; pass next_cursor back as after to fetch the next page. The cursor is null at the end.
Sending input
You drive a session by sending it input. Every input is recorded on the event stream, and if the session isidle it wakes into running. There are four input types:
fromSeq to resume from the last seq you handled without gaps or duplicates. See Events & streaming.
Interrupt and redirect in one call
Inputs can be batched so they land atomically. The common case is steering a running agent: send an interrupt together with a new message. The agent wraps up the current turn cleanly at the next commit boundary — the interrupted turn ends withstop_reason: "end_turn" — and then picks up the redirect.
Awaiting-approval loop
When the agent calls a tool governed by anask policy, the runtime does not run the tool. Instead the session goes idle with stop_reason: "awaiting_approval" and exposes the waiting call(s) on pending_actions[]. You resolve each one with an allow/deny confirmation; once the last pending action is answered, the session resumes automatically.
ask, and Events & streaming for the tool.confirm event shape.
Awaiting-answer loop
The mirror of the loop above, for the park the agent starts itself. When an agent callsask_operator the turn stops the same way — idle, rows on
pending_actions[], no budget burning — but the row is tagged kind: "question" and carries a
question object: the sentence the agent wrote, and one to three fields to fill in.
- Render from
question, never fromargs. They hold the same content —argsis what the model called with and what replays byte-identically — butquestionis the shape a renderer reads, and it is the one that will keep its meaning if the tool’s arguments ever change. - Every field must be answered, with a non-empty value: an agent that could proceed without one of them would not have asked it. A partial answer is
validation_failed(400) naminganswers.<key>. The escape a person needs is the free-text arm, which is on by default. - A
choiceanswer is the option’s words, never an index. The model reads them back as prose. Sendstring[]for amultiple: truefield and a plainstringfor everything else; the route enforces the arity.
Not every agent can ask.
ask_operator is offered only on a harness that can hold a call open for a person — see Harness capabilities — and an agent whose toolset denies it cannot park this way at all.Approver and timeouts
Each resolved confirmation records who answered it — the approving principal (a user or API key id) is written to the event and audit trail alongside the decision and any deny reason. This is what lets you prove, after the fact, that a payout or destructive action was signed off by a person rather than silently auto-run. Anask tool does not wait forever. The governing policy sets an ask_timeout_seconds and an on_timeout disposition; if no one answers in the window, the runtime applies it:
Interrupting
Arunning session must be interrupted before you can update its agent, archive it, or delete it. An interrupt is delivered as an event and stops the current turn at the next commit boundary — you lose at most one turn, never the run. On its own, an interrupt lands the session at idle with stop_reason: "interrupted".
Archiving
Cancelling stops a session and releases its sandbox while preserving its record and its events.CLI
Next: events & streaming
The resumable event model behind every session.