codai docs
Shared sessions

Shared sessions

One conversation, many devices — the gateway keeps the ordered event log; the device with the tools executes; everyone else follows or steers.

A shared session is a server-side conversation. The gateway's store is the source of truth for its ordered event log; every device keeps a local cache and reconciles by seq. The conversation travels; execution stays where the tools are — your laptop runs the shell, your phone watches and answers the agent's questions, a teammate reads along.

This is the protocol behind "continue on phone", the hub's session view and the desktop's live mirror. It is public, versioned (v1, stable) and published with JSON Schemas at github.com/codai-ro/codai-protocol.

The moving parts

                     ┌──────────────── gateway (ai.codai.ro) ────────────────┐
                     │  session ──▶ events[seq 1..n]   controls   lease     │
                     └──────▲──────────────┬──────────────▲────────┬────────┘
     appends events  POST   │              │ SSE / WS      │ POST   │ push (FCM)
     claims lease           │              ▼               │        ▼
   ┌────────────────┐   ┌───────────┐   ┌───────────┐   ┌────────────┐
   │   EXECUTOR     │   │  VIEWER   │   │  EDITOR   │   │ DISPATCHED │
   │ desktop / CLI  │   │ hub, web  │   │  phone    │   │  device    │
   │ holds the lease│   │ read-only │   │ sends     │   │ woken with │
   │ runs the tools │   │ follows   │   │ controls  │   │ a `send`   │
   └────────────────┘   └───────────┘   └───────────┘   └────────────┘
ObjectWhat it is
SessionThe container. Has an id (server UUID) and your own session_key, an owner, a title, last_seq, and who holds the lease.
EventOne entry in the log, with a dense server-assigned seq, a kind (turn_start, tool_call, ask, assistant, …) and an opaque payload. Only the executor appends.
ControlAn instruction to the executor — send, answer, approve, deny, cancel, steer, inject. Persisted so a late executor can drain them, echoed into the log so every viewer sees them.
LeaseThe right to append. Exactly one device holds it, for 30 seconds at a time, renewed by heartbeat every 10 seconds.
DeviceAny client installation — a UUID you choose, sent as x-codai-device, registered lazily under your account.
ShareA grant of viewer, editor or owner on one session to a user, an org, or a link token.
PresenceWho is connected right now, and whether they are driving. In memory only.
DispatchA send targeted at one of your devices, plus a push notification to wake it.

Roles

RoleMay
viewerRead the session, its events and controls; follow the live stream.
editorEverything a viewer may, plus submit controls and dispatch.
ownerEverything, plus rename, archive, delete, manage shares and claim the lease.

You are owner of sessions you created. On a shared session your role is the highest of the shares that match you — directly, through an org you belong to, or via a link token you present.

A minimal round trip

Every request carries your key and, on writes, your device id:

export DEV=$(uuidgen)   # once per installation; reuse it

# 1. create (or reopen) a session by your own key
curl -X POST https://ai.codai.ro/v1/sessions \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "x-codai-device: $DEV" -H "x-codai-device-platform: cli" \
  -H "Content-Type: application/json" \
  -d '{ "session_key": "laptop-2026-09-23", "title": "Fix the flaky test" }'

# 2. take the lease — you are the executor now
curl -X POST https://ai.codai.ro/v1/sessions/laptop-2026-09-23/lease \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $DEV"

# 3. append what happened
curl -X POST https://ai.codai.ro/v1/sessions/laptop-2026-09-23/events \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $DEV" \
  -H "Content-Type: application/json" \
  -d '{ "events": [
        { "kind": "turn_start", "turn_id": "t1", "client_event_id": "t1-start", "payload": { "text": "Fix the flaky test" } },
        { "kind": "assistant",  "turn_id": "t1", "client_event_id": "t1-a1",    "payload": { "text": "Reading test_retry.py…" } }
      ] }'

# 4. from any other device: follow it
curl -N "https://ai.codai.ro/v1/sessions/laptop-2026-09-23/stream?after=0" \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $(uuidgen)"

The stream replays the two events, then a lease frame naming your laptop as holder, then stays open for whatever comes next.

Where to go from here

Storing and streaming your own sessions is available on every paid tier. The persistent_memory entitlement gates only server-side memory and search, not this protocol. A session created with e2e: true is encrypted client-side (HIDE — experimental, unaudited) and the gateway stores ciphertext.

On this page