Org in a Box
API Reference

Sessions API

Create, manage, and stream agent sessions.

GET /v1/sessions

List the caller's sessions. In local demo mode without auth, the API scopes this list to the configured operator user. Browser clients also carry a local browser-session identifier so operator-owned sessions created before sign-in remain visible after the browser switches into authenticated mode on the same device.

Response:

{
  "sessions": [
    { "sessionId": "uuid", "title": "Q2 Analysis", "updatedAt": "2026-04-18T..." }
  ]
}

POST /v1/sessions

Create a new session. If you pass template_slug, the API resolves that template once and snapshots its system prompt + model override onto the session so later template edits do not change the session's behavior.

Request:

{
  "title": "My Session",
  "template_slug": "research-analyst"
}

Response:

{ "sessionId": "uuid" }

GET /v1/sessions/:id/messages

Get the session's message history from the upstream opencode runtime.

The caller must own the indexed session. Unknown or other users' session IDs return 404. Browser clients can also satisfy ownership for operator-owned demo sessions with the same local browser-session identifier that originally created the session.

Response:

{
  "messages": [
    {
      "info": {
        "id": "msg-1",
        "role": "assistant",
        "time": { "created": 1711000001000, "completed": 1711000002000 }
      },
      "parts": [
        {
          "id": "part-1",
          "messageID": "msg-1",
          "sessionID": "uuid",
          "type": "text",
          "text": "history restored"
        }
      ]
    }
  ]
}

POST /v1/sessions/:id/prompt

Send a message to the agent. Enqueues an agent-turn job.

If the session was created from a template, the prompt uses the stored session snapshot first. Older sessions created before snapshotting was added will be backfilled on first prompt while the source template is still available. The caller must own the indexed session; the route does not create ownership on first prompt anymore. Operator-owned browser sessions remain usable after sign-in on the same device because the browser-session identifier is preserved alongside the indexed owner until the session is claimed by the authenticated user.

Request:

{
  "text": "Summarise the attached PDF",
  "agent": "build"
}

You can also send multipart form data with text, agent, agentProfileId, and repeatable files fields. files[] is also accepted for compatibility. You can also send an opencode-style parts array with text and file entries.

Response:

{ "jobId": "uuid", "sessionId": "uuid" }

If no applied runtime with a default model is available yet, the API rejects the turn with:

{
  "error": "runtime_not_ready",
  "detail": "apply a runtime with an active provider and default model before starting a turn"
}

GET /v1/sessions/:id/events

Server-Sent Events stream for a session. The route proxies the upstream opencode /event?sessionID=... stream and forwards the JSON event objects as SSE message bodies.

Common event payloads:

EventPayload
message.part.updated{ "sessionID": "uuid", "time": 1711000000000, "part": { ... } }
message.part.delta{ "sessionID": "uuid", "messageID": "uuid", "partID": "uuid", "field": "text", "delta": "..." }
permission.asked{ "id": "uuid", "sessionID": "uuid", "permission": "bash", "patterns": ["..."] }
session.status{ "sessionID": "uuid", "status": { "type": "idle" | "running" } }
session.idle{ ... }
session.deleted{ ... }
session.error{ "error": { "message": "..." } }

Clients should treat either session.idle or session.status.status.type === "idle" as the end of the turn.


POST /v1/sessions/:id/permissions/:permissionID

Approve or deny a pending tool permission request.

The caller must own the indexed session.

Request:

{ "response": "once" }

Valid responses are once, always, and reject.


DELETE /v1/sessions/:id

Delete the indexed session record for the current owner.

This removes the session from the Orginabox session index used by the web/API surface. It does not force-delete the upstream sandbox transcript immediately; upstream cleanup still follows the sandbox/runtime lifecycle.

On this page