Mango

Sessions

Create, observe, update, and stop persistent agent work.

Edit on GitHub

Sessions bind an immutable agent snapshot to an environment and own an append-only event history.

SDK and HTTP example

This excerpt uses the client and resources from Quickstart. Select your language; the wire contract and lifecycle rules follow below.

const session = await client.sessions.create({ agent: agent.id, environment_id: environment.id, title: 'First session' });

Create

POST /v1/sessions

The agent field supports three forms.

Latest version:

{
  "agent": "agent_...",
  "environment_id": "env_...",
  "title": "Investigation"
}

Pinned version:

{
  "agent": {"type": "agent", "id": "agent_...", "version": 2},
  "environment_id": "env_..."
}

Session-local overrides:

{
  "agent": {
    "type": "agent_with_overrides",
    "id": "agent_...",
    "version": 2,
    "system": "Focus on production incidents.",
    "tools": []
  },
  "environment_id": "env_..."
}

Overrides replace model, system, tools, MCP servers, or skills for this session only. They do not mutate or renumber the agent. A model override may change the model ID or speed; effort remains an Agent-level setting and a session override does not replace it. Overrides also apply to self copies in a coordinator roster. Independently referenced Agents are unaffected.

For a coordinator, session.agent.multiagent.agents expands the Agent resource's Version references into full immutable Agent definitions. The definitions are captured with the Session, in roster order, rather than loaded again when a child Thread starts. A self definition reflects the effective Session overrides and every roster member omits its own multiagent field, preserving the one-level topology. Existing Sessions keep those snapshots even if a referenced Agent is later updated or archived.

The effective custom Skill list is revalidated when the Session is created. Every omitted or latest value is replaced by a concrete immutable Version in the returned session.agent.skills snapshot. PostgreSQL pins those Versions in the same transaction as the Session; deleting a pinned Version is rejected until the Session is physically deleted. Up to 500 unique scope-pinned Skills are accepted across the primary and complete roster, subject to one 500 MiB aggregate expanded-size limit and unique runtime names per execution scope. The self-hosted worker verifies pinned archives and exposes them below its skills/ workdir; roster Agents use isolated subdirectories below skills/.agents/. The model first receives every Skill name plus descriptions bounded to one percent of the configured context window. When it invokes the private Skill dispatcher, the runtime returns Launching skill: <name> and injects the complete selected SKILL.md, prefixed with its base directory, into the provider conversation. Referenced supporting files remain on disk for ordinary read or bash access. Self-hosted workers download the same immutable primary and roster pins before tool dispatch, verify each canonical archive's advertised byte length and SHA-256 digest, and add a 500 MiB compressed-byte plus 10,000-file Session guard; the server-side Agent loop reads the main instruction entry directly from Mango's canonical archive rather than reaching into the worker filesystem. Their model-visible skills/... paths are relative to the worker's configured workdir. See Sandboxes for the execution boundary.

Optional initial_events may contain up to 50 user.message or user.define_outcome objects. A non-empty list starts execution immediately. An outcome may use either an inline text rubric or a ready File rubric from the same Workspace. File text is validated and snapshotted before the Session admission transaction, so a missing or invalid File cannot leave a partially created Session and deleting it later cannot change the active outcome. The optional title, metadata, initial_events, resources, and vault_ids fields must use their documented non-null shapes when present; omission supplies the empty/default value. budget: null explicitly selects no spend ceiling. A non-null budget sets a Session-wide ceiling in integer USD cents:

{
  "budget": {
    "type": "limit",
    "max_list_cost": {"amount": "2500", "currency": "USD"}
  }
}

Budgeted Sessions require model IDs present in Mango's built-in price catalog, which currently contains canonical Anthropic model IDs and published list prices, for the coordinator and every resolved roster member. A router may still forward those requests, but an opaque router-defined model alias is not assigned a guessed price. resources accepts up to eight Memory Store inputs:

{
  "type": "memory_store",
  "memory_store_id": "memstore_...",
  "access": "read_write"
}

A Memory Store input uses memory_store_id, optional instructions, and read_write or read_only access. It can only be attached at creation. The self-hosted worker prepares it below /mnt/memory. File and Git inputs are not part of Mango's self-hosted contract; stage them in the operator-owned workspace. vault_ids is an ordered list of active Vault references. The order is frozen with the Session: for an MCP endpoint, the first Vault containing a matching credential wins. Admission requires the Vault keyring to be configured and rejects missing, archived, empty, or duplicate references. Updating vault_ids after creation remains unsupported by the current Mango contract.

Get and update

GET /v1/sessions/{id}
POST /v1/sessions/{id}

The update body accepts agent, metadata, title, and budget:

{
  "title": "New title",
  "metadata": {"owner": "sre", "stale": null},
  "agent": {
    "tools": [
      {"type": "agent_toolset_20260401"},
      {"type": "mcp_toolset", "mcp_server_name": "linear"}
    ],
    "mcp_servers": [
      {"type": "url", "name": "linear", "url": "https://mcp.linear.app/sse"}
    ]
  }
}
  • metadata is a per-key patch: a string upserts the key, null deletes it, and omitting the field preserves the whole bag.
  • title may be omitted or set to a string; null is not a no-op update.
  • agent updates only tools and mcp_servers, as a full replacement: the array you send becomes the new value, [] clears, and omitting preserves. model, system, and skills are fixed for the session's lifetime and are rejected; set them with agent_with_overrides at create time instead.
  • An agent update is session-local. It never renumbers or mutates the agent resource, and it applies from the next turn.
  • An agent update requires an idle session. A request that arrives while a turn is in flight returns 409; send an untargeted user.interrupt first. title and metadata carry no such precondition.
  • vault_ids is rejected on update by the current Mango API.
  • A Session created with a budget may replace it or set budget: null to remove it. A changed maximum must be strictly greater than the exact list cost already consumed. A Session created without a budget cannot add one later, and a removed budget cannot be re-added.

Changed fields and their session.updated event commit together. The event carries only the fields the request actually changed; a request that changes nothing emits no event.

List

GET /v1/sessions

Supported query parameters:

ParameterMeaning
limitPage size, 1–1000; default 100. Values above 1000 return a validation error.
orderasc or desc; default desc
pageOpaque next or previous cursor
agent_idMatch agent ID
agent_versionMatch version; requires agent_id
statuses[]Repeatable public status filter
include_archivedtrue or false
created_at[gt|gte|lt|lte]RFC 3339 timestamp bounds
deployment_idMatch Sessions created by the Deployment
memory_store_idMatch Sessions attached to the Memory Store

The response includes both directions:

{
  "data": [],
  "next_page": null,
  "prev_page": null
}

Archive and delete

POST /v1/sessions/{id}/archive
DELETE /v1/sessions/{id}

A running session cannot be archived or deleted and returns 409. A user.interrupt durably cancels active model or tool Activities across API and worker processes so the Session can return to idle. Omitting session_thread_id interrupts every non-archived Thread; providing it targets only the named Thread.

Archive prevents further input and retains history and Session Files, but does not release the sandbox. Automatic idle or archive-based sandbox reclamation is not implemented. Delete performs sandbox cleanup and removes Session-owned Files; download any outputs you need to retain before deleting a Session.

Delete removes the session and persisted history, sends a final session.deleted event to active subscribers, and closes their streams:

{"id": "session_...", "type": "session_deleted"}

Response notes

The response embeds the resolved agent snapshot and includes nullable budget, resources, vault_ids, outcome_evaluations, stats, usage, and deployment_id. stats and usage are cumulative live projections, and outcome_evaluations reflects each admitted outcome. resources embeds active File and Memory Store Resource objects. Ordered vault_ids are resolved at creation; update-time vault replacement is rejected. usage aggregates provider-reported token, prompt-cache, Web Fetch, and Web Search counters across every Session Thread. usage.list_cost is calculated from Mango's current built-in price catalog, provider-reported execution facts that affect that catalog's rates, the Web Search request rate, and $0.08 per Session active hour, then rounded to the nearest cent for the public monetary projection. Provider routing is not Agent configuration. Thread list cost excludes Session runtime. Accounting remains exact internally, and model-request admission checks the shared ceiling before every request; an already in-flight request may take the Session over its limit. Provider-reported tokens remain visible even when a response-level billing rule makes their list cost zero, such as an unbilled Claude Fable 5 refusal.

When the ceiling is reached, affected Threads become idle with budget_reached. If the whole Session becomes idle, session.usage is emitted immediately before session.status_idle. A pending client action takes precedence as requires_action; its result remains admissible, and the budget is checked before any subsequent model request. Raising or removing the budget resumes a turn that was paused at that check. deployment_id is null for direct Session creation and contains the parent Deployment ID for Deployment-created Sessions.

Worker workspace files remain operator-owned and are not automatically published through the Files API.

See capabilities and limits.

On this page