API
Sessions and turns
The session API is the lower-level interface for durable agent conversations. Use the compound agent invocation endpoint for most product chat surfaces. Use session and turn endpoints when your client must create sessions itself, page the transcript, steer work in progress, or manage compaction directly.
Resource model
A session owns an ordered transcript. A turn is one execution attempt against that transcript. Messages and compaction summaries are durable; typing previews, model deltas, and live tool activity are not.
The core endpoints are:
POST /v1/projects/{project}/sessions
GET /v1/projects/{project}/sessions/{session_id}
GET /v1/projects/{project}/sessions/{session_id}/messages
POST /v1/projects/{project}/sessions/{session_id}/turns
GET /v1/projects/{project}/sessions/{session_id}/streamEvery session is scoped to one project and one agent. A stable name lets
your application resolve the same conversation again without storing a Mobius
session ID as its only lookup key.
Start a turn
Send content to POST .../turns:
{
"input": {
"content": [
{
"type": "text",
"text": "Summarize the open support tickets."
}
],
"idempotency_key": "<message-id>"
}
}By default, the endpoint returns 202 Accepted while the turn continues:
{
"session_id": "<session-id>",
"turn_id": "<turn-id>",
"status": "queued",
"after_sequence": 18
}Open the session stream with after_sequence=18 to follow only activity after
that durable cursor. If the start request sends Accept: text/event-stream,
Mobius returns 200 OK and streams the same turn inline.
Use a provider message ID or another durable application event ID as
idempotency_key. Retrying the same key and content resolves the original
turn instead of starting duplicate work.
Stream and replay
Committed transcript rows arrive as user.message, agent.message, and
compaction.created frames. Their server-sent event id equals the durable
message sequence. Persist that value as the reconnect cursor.
Live frames such as turn.started, generation.delta,
session.message.preview, tool.call, and tool.result help render progress,
but they are not transcript history. Do not persist live_sequence or
delta_sequence as a reconnect cursor.
If a client attaches in the middle of a turn, request the turn's live snapshot:
GET /v1/projects/{project}/sessions/{session_id}/turns/{turn_id}/liveThe snapshot rebuilds the current preview. The final agent.message still
arrives as a durable transcript row even when a client misses live frames.
Tool history also lives in the transcript. A tool_use block appears on the
agent message and the matching tool_result block appears on the following
user message. Pair them by tool_use_id; treat live tool frames as optional
progress only.
Nudge work in progress
A nudge adds direction at the next safe iteration boundary without cancelling the active turn:
POST /v1/projects/{project}/sessions/{session_id}/nudges{
"content": "Do not deploy. Prepare the diff and wait.",
"idempotency_key": "<nudge-id>",
"wake": false
}A delivery of current_turn means the active turn will receive the nudge.
A delivery of new_turn means the previous turn settled first, so Mobius
queued the direction as a new turn instead of dropping it.
Set wake: true only when a turn is waiting on an agent tool and should resume
immediately. One oldest nudge is delivered per safe boundary. A session accepts
up to 32 pending nudges.
Use these endpoints to reconcile or cancel pending direction:
GET /v1/projects/{project}/sessions/{session_id}/nudges?status=pending
POST /v1/projects/{project}/sessions/{session_id}/nudges/{nudge_id}/cancelReusing an idempotency key with different content returns
409 idempotency_conflict. A full queue returns 409 nudge_queue_full.
Compaction
A session compaction policy has four controls. Choose either threshold or
threshold_tokens, not both:
| Field | Values | Meaning |
|---|---|---|
strategy | auto, manual, disabled | Decides whether compaction starts automatically, only on request, or never. |
threshold | xs, sm, md, lg, xl | Sets a model-relative trigger at 10%, 20%, 40%, 60%, or 80% of the session model's context window. |
threshold_tokens | Integer from 1 to 10,000,000 | Sets an exact estimated-token trigger instead of a preset. |
summary_model | Model ID | Chooses the model that writes the summary. |
Update the session to change its policy. Existing sessions do not re-resolve defaults from the agent, loop, or messaging binding.
{
"compaction_policy": {
"strategy": "auto",
"threshold": "md"
}
}For an exact threshold, replace threshold with threshold_tokens:
{
"compaction_policy": {
"strategy": "auto",
"threshold_tokens": 375000
}
}Start compaction under auto or manual with:
POST /v1/projects/{project}/sessions/{session_id}/compactdisabled rejects manual compaction. Change the strategy first.
Cancel or force-unlock a session
Cancel a specific turn when you know its ID:
POST /v1/projects/{project}/sessions/{session_id}/turns/{turn_id}/cancelUse the session cancel endpoint with force=true only when a non-terminal turn
blocks new messages and ordinary cancellation cannot clear it:
POST /v1/projects/{project}/sessions/{session_id}/cancel?force=trueForce cancellation can interrupt a loop-owned turn and leave its run needing operator attention. It does not delete transcript rows.
Next
- Use the higher-level agent invocation flow for most embedded assistants.
- Render live events with the event catalog.
- Understand transcript history and compaction in agent sessions.
- See every schema in the interactive API reference.