codai docs
Shared sessions

Sharing and orgs

Grant a role on a session to a person, an organisation or a link; list what is shared with you; manage org membership.

A share grants a role on one session to a user, to every member of an org, or to whoever presents a link token. The session owner manages shares; anyone can create an org and invite people into it.

principal_typeprincipal_idWho gets access
userThe user's UUIDThat account, on every device.
orgThe org's UUIDEvery current member of the org. Only an org member can share a session into it.
link— (must be omitted)Any authenticated principal who presents the token.

role is viewer (default), editor or owner. expires_at is optional and must be in the future; an expired share is ignored everywhere. Sharing with the session's own owner is 400 — The owner already has full access.

Share a session

curl -X POST https://ai.codai.ro/v1/sessions/5b3e…/shares \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "Content-Type: application/json" \
  -d '{ "principal_type": "user", "principal_id": "7d21…-uuid", "role": "editor" }'
{
  "id": "e4a9…", "session_id": "5b3e…", "principal_type": "user", "principal_id": "7d21…",
  "role": "editor", "has_token": false, "expires_at": null,
  "created_by_user_id": "…", "created_at": "2026-09-23T10:00:00.000Z"
}

Unknown user → 404 not_found (User not found.). A non-UUID principal_id → 400 (principal_id must be a user uuid.).

A link token grants the share's role to any authenticated codai user who presents it. Treat it like a password: set expires_at, keep the role at viewer unless you need more, and delete the share when done.

Manage shares

MethodPathMin roleResponse
GET/v1/sessions/:id/sharesowner{ shares: Share[] } — never includes tokens, only has_token.
POST/v1/sessions/:id/sharesowner201 Share (+ token once for link).
DELETE/v1/sessions/:id/shares/:shareIdowner{ deleted: true, id }; unknown → 404 (Share not found.).

Deleting a share revokes access immediately for everyone it covered — including anyone currently connected via a link token, whose next request is 403 not_a_member.

What is shared with me

curl "https://ai.codai.ro/v1/sessions/shared-with-me" -H "Authorization: Bearer $CODAI_API_KEY"
{ "sessions": [ { "id": "5b3e…", "session_key": "…", "owner_user_id": "…", "title": "Fix the flaky test", "created_at": "…", "last_event_at": "…", "last_seq": 42, "executor_device_id": "1c2f…", "lease_expires_at": "…", "e2e": false, "archived": false, "role": "editor", "share_id": "e4a9…" } ] }

Lists sessions shared with you directly or through an org (up to 200; ?archived=1 includes archived ones). Link-share access is exercised per request and does not appear in any list — a viewer who arrived by link has to keep the token. GET /v1/sessions (with x-codai-device or ?v=2) returns your own sessions first, then the shared ones, each with your role.

Your effective role on a session is the highest across every share that matches you — a viewer link plus an editor user share makes you an editor.

Organisations

An org is a named group of users. Sharing a session with an org shares it with everyone in it, now and later.

On the wire the Org object is camelCase — { id, name, ownerUserId, createdAt } — unlike every other object on this surface. This is part of v1 and will not be renamed.

MethodPathWhoRequestResponse
POST/v1/orgsany user{ "name": string 1..200 }201 { id, name, ownerUserId, createdAt, role: "owner" }
GET/v1/orgsany user—{ orgs: [{ id, name, ownerUserId, createdAt, role }] } — orgs you belong to, with your role
GET/v1/orgs/:id/membersorg member—{ org_id, members: [{ user_id, role, created_at, email }] }
POST/v1/orgs/:id/membersorg owner or admin{ "user_id": uuid } or { "email": string } (exactly one), role? default member201 { org_id, user_id, role } — an upsert, so re-posting changes the role
DELETE/v1/orgs/:id/members/:userIdorg owner or admin—{ deleted: true, org_id, user_id }

Membership roles are owner · admin · member. Only the org owner can grant owner (403 — Only the org owner can grant the owner role.) and the owner cannot be removed (403 — The org owner cannot be removed.). Adding someone who has no codai account is 404 (User not found.); a non-member reading the list is 403.

# create an org and add a teammate by email
ORG=$(curl -s -X POST https://ai.codai.ro/v1/orgs \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "Platform team" }' | jq -r .id)

curl -X POST "https://ai.codai.ro/v1/orgs/$ORG/members" \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "role": "admin" }'

Every share and org mutation writes an audit row (share_add, share_remove, org:create, org:member_add, org:member_remove), so the owner can always reconstruct who had access when.

On this page