Skip to content

codai protocol — shared sessions

The language codai apps speak to each other, so a task you start on your phone can be watched, steered or finished from your laptop.

Spec v1 License: Apache-2.0 Docs: CC BY 4.0

codai is one model name — codai — available on every device you own: phone, desktop, the console, the CLI and any agent you write against the gateway. This repository describes how those clients share a session: the ordered log of what an agent did, who is currently running it, and how anyone with access can send it instructions.

In five lines

  1. A session lives on the gateway. It is an append-only list of events (turn_start, tool_call, assistant, …) with a dense sequence number.
  2. Exactly one device — the executor — holds a short lease on the session and is the only one allowed to append events. Everyone else is a viewer or editor.
  3. Viewers follow the session live over SSE or WebSocket and can resume from any seq after a disconnect.
  4. Editors send controls (send, answer, approve, cancel, steer, …). The gateway stores them and echoes them into the log so the executor can apply them — even if it was offline when they were sent.
  5. Dispatch starts a task on a named device: the control is queued for that device and a push notification wakes it up to claim the lease.
sequenceDiagram
    participant Phone as Phone (executor)
    participant GW as Gateway ai.codai.ro
    participant Laptop as Laptop (viewer/editor)

    Phone->>GW: POST /v1/sessions {session_key}
    Phone->>GW: POST /v1/sessions/:id/lease
    GW-->>Phone: 200 lease {device_id, expires_at}
    loop every ≤200 ms / 20 events
        Phone->>GW: POST /v1/sessions/:id/events {events[]}
        GW-->>Phone: {last_seq, events[{client_event_id, seq}]}
    end
    Laptop->>GW: GET /v1/sessions/:id/stream?after=0
    GW-->>Laptop: event: event (replay) … event: lease … event: presence
    Laptop->>GW: POST /v1/sessions/:id/control {id, kind:"steer", text}
    GW-->>Laptop: 202 {accepted, seq}
    GW-->>Phone: frame control (WS) / event kind:"control" (SSE)
    Phone->>GW: POST /v1/sessions/:id/control/:cid/applied
    loop every 10 s
        Phone->>GW: PUT /v1/sessions/:id/lease (heartbeat, TTL 30 s)
    end
Loading

Who is this for

  • App builders — you want your own viewer, executor or dashboard to interoperate with the codai phone and desktop apps. Read the spec and validate your payloads against schemas/.
  • Agent builders — you have an agent (a script, a CI job, an MCP tool) and want to hand tasks to a user's device or follow what it does. Start with examples/probe.mjs and the Dispatch section of the spec.
  • Curious users — you want to know exactly what leaves your phone when "session sync" is on. The answer is the Event object and nothing else; see the privacy notes.

Try it in 2 minutes

You need a codai API key (codai_…, from the console) and a device id. The device id is any UUID you pick — the gateway registers it under your account the first time it sees it.

The three calls below create a session, claim the executor lease, append one event, then read it back.

PowerShell

$CODAI_KEY = "codai_…"                       # your key
$DEVICE    = [guid]::NewGuid().ToString()    # any UUID, reuse it for this device
$H = @{ Authorization = "Bearer $CODAI_KEY"; 'x-codai-device' = $DEVICE
        'x-codai-device-platform' = 'cli'; 'x-codai-device-name' = 'try-it' }
$GW = 'https://ai.codai.ro'

$s = Invoke-RestMethod -Method Post -Uri "$GW/v1/sessions" -Headers $H -ContentType 'application/json' `
       -Body '{"title":"hello from curl"}'
Invoke-RestMethod -Method Post -Uri "$GW/v1/sessions/$($s.id)/lease" -Headers $H -ContentType 'application/json' -Body '{}'
Invoke-RestMethod -Method Post -Uri "$GW/v1/sessions/$($s.id)/events" -Headers $H -ContentType 'application/json' `
       -Body '{"events":[{"kind":"assistant","client_event_id":"e1","payload":{"text":"hi"}}]}'
Invoke-RestMethod -Uri "$GW/v1/sessions/$($s.id)/events?after=0" -Headers $H | ConvertTo-Json -Depth 5

bash

export CODAI_KEY="codai_…"                          # your key
export DEVICE="$(uuidgen | tr 'A-Z' 'a-z')"          # any UUID, reuse it for this device
GW=https://ai.codai.ro
H=(-H "Authorization: Bearer $CODAI_KEY" -H "x-codai-device: $DEVICE"
   -H "x-codai-device-platform: cli" -H "x-codai-device-name: try-it" -H "content-type: application/json")

SID=$(curl -s "${H[@]}" -X POST $GW/v1/sessions -d '{"title":"hello from curl"}' | jq -r .id)
curl -s "${H[@]}" -X POST $GW/v1/sessions/$SID/lease -d '{}'
curl -s "${H[@]}" -X POST $GW/v1/sessions/$SID/events \
     -d '{"events":[{"kind":"assistant","client_event_id":"e1","payload":{"text":"hi"}}]}'
curl -s "${H[@]}" "$GW/v1/sessions/$SID/events?after=0" | jq

Expected: 201 for the session, 200 with {device_id, expires_at} for the lease, {last_seq: 1, accepted: 1, …} for the append, and one event with seq: 1 on the read. Clean up with DELETE /v1/sessions/$SID and DELETE /v1/devices/$DEVICE. More recipes in examples/curl.md.

Concepts

Term In one sentence
Session A server-side conversation with an ordered event log, owned by one user, addressed by its server id (UUID) or your own session_key.
Event One append-only line in the log — {seq, kind, ts, sender_device_id, turn_id?, payload} — written only by the executor; kind is free-form text.
Control A request to the executor (send, answer, approve, deny, cancel, steer, inject) with a client-chosen idempotency id, stored and echoed as an event.
Lease The 30-second, heartbeat-renewed right to execute a session; exactly one device holds it, and only the owner's devices can claim it.
Device A UUID you choose, registered lazily from the x-codai-device header, with a platform (android, ios, web, desktop, cli, agent) and a name.
Role What a caller may do on a session — viewer (read/follow), editor (also send controls), owner (everything, including leases and shares).
Share A grant of a role on one session to a user, an org, or anyone holding a link token (shown once, stored only as a SHA-256 hash).
Dispatch Queue a send control for one specific device of the owner and wake it with a data-only push, so a task can be started remotely.
Presence Who is connected right now (device_id, role, executor, driving), streamed as frames and never persisted.

In this repository

  • spec/shared-sessions.md — the normative specification: objects, routes, headers, SSE/WS frames, lease and idempotency rules, dispatch, errors, limits, conformance checklist.
  • schemas/ — JSON Schema (draft 2020-12) for every wire object; enums are copied verbatim from the reference implementation.
  • examples/probe.mjs (end-to-end round trip in plain Node), viewer.html (a single-file live transcript viewer, no build step), curl.md.
  • CHANGELOG.md — every change to the protocol, with deprecations announced ahead of time.

Implementations

Project Role Language
codai-ro/codai-phone reference executor + viewer Kotlin
codai-ro/codai-desktop executor + viewer Tauri / TS
codai-ro/codai-sdk client library (npm i codai-sdk) TypeScript
codai-ro/codai-sdk-python client library (pip install codai-sdk) Python
codai.ro/console viewer / editor / device manager

Versioning and stability

This is protocol v1. Every realtime frame carries "v": 1.

  • Additive only. New optional fields, new event kinds and new routes may appear in any release. Clients must ignore fields and kinds they do not know.
  • Never removed or renamed within v1. A field, route, header or enum value listed in the v1 spec stays valid for the lifetime of v1.
  • Deprecations are announced in CHANGELOG.md at least one minor release before behaviour changes, and the old form keeps working until v2.
  • The spec, schemas and the gateway change in the same commit; if you find a mismatch it is a bug — please report it.

Contributing

Issues and pull requests are welcome — a typo in the spec, a schema that rejects a valid payload, a client you built. See CONTRIBUTING.md (DCO sign-off, conventional commits) and SECURITY.md for anything security-sensitive.

License

"codai" is a trademark of Dragos Catalin Vladulescu. Implementing this protocol does not require permission; calling your product "codai" does.

About

The shared-sessions protocol: how codai apps sync, share and collaborate on AI sessions across devices. Spec, schemas and examples.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors