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}/stream

Every 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}/live

The 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}/cancel

Reusing 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:

FieldValuesMeaning
strategyauto, manual, disabledDecides whether compaction starts automatically, only on request, or never.
thresholdxs, sm, md, lg, xlSets a model-relative trigger at 10%, 20%, 40%, 60%, or 80% of the session model's context window.
threshold_tokensInteger from 1 to 10,000,000Sets an exact estimated-token trigger instead of a preset.
summary_modelModel IDChooses 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}/compact

disabled 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}/cancel

Use 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=true

Force cancellation can interrupt a loop-owned turn and leave its run needing operator attention. It does not delete transcript rows.

Next