Partajare și organizații
Acordă un rol pe o sesiune unei persoane, unei organizații sau unui link; listează ce este partajat cu tine; gestionează apartenența la organizații.
Un share acordă un role pe o sesiune unui user, fiecărui membru al unei org sau oricui prezintă un token de link. Owner-ul sesiunii gestionează share-urile; oricine poate crea o organizație și invita oameni în ea.
principal_type | principal_id | Cine primește acces |
|---|---|---|
user | UUID-ul utilizatorului | Acel cont, pe orice dispozitiv. |
org | UUID-ul organizației | Fiecare membru curent al organizației. Doar un membru al organizației poate partaja o sesiune în ea. |
link | — (trebuie omis) | Orice principal autentificat care prezintă token-ul. |
role este viewer (implicit), editor sau owner. expires_at este opțional și trebuie să fie în viitor; un share expirat este ignorat peste tot. Partajarea cu însuși owner-ul sesiunii este 400 — The owner already has full access.
Partajează o sesiune
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"
}Utilizator necunoscut → 404 not_found (User not found.). Un principal_id care nu e UUID → 400 (principal_id must be a user uuid.).
Un token de link acordă rolul share-ului oricărui utilizator codai autentificat care îl prezintă. Tratează-l ca pe o parolă: setează expires_at, ține rolul la viewer dacă nu ai nevoie de mai mult și șterge share-ul când ai terminat.
Gestionează share-urile
| Metodă | Cale | Rol minim | Răspuns |
|---|---|---|---|
GET | /v1/sessions/:id/shares | owner | { shares: Share[] } — nu include niciodată token-uri, doar has_token. |
POST | /v1/sessions/:id/shares | owner | 201 Share (+ token o singură dată pentru link). |
DELETE | /v1/sessions/:id/shares/:shareId | owner | { deleted: true, id }; necunoscut → 404 (Share not found.). |
Ștergerea unui share revocă accesul imediat pentru toți cei pe care îi acoperea — inclusiv pentru oricine este conectat acum printr-un token de link, al cărui următor request este 403 not_a_member.
Ce este partajat cu mine
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…" } ] }Listează sesiunile partajate cu tine direct sau printr-o organizație (până la 200; ?archived=1 include și cele arhivate). Accesul prin link share se exercită per request și nu apare în nicio listă — un viewer venit prin link trebuie să păstreze token-ul. GET /v1/sessions (cu x-codai-device sau ?v=2) returnează întâi sesiunile tale, apoi cele partajate, fiecare cu role-ul tău.
Rolul tău efectiv pe o sesiune este cel mai înalt dintre toate share-urile care ți se potrivesc — un link viewer plus un share de utilizator editor te fac editor.
Organizații
O organizație este un grup de utilizatori cu nume. Partajarea unei sesiuni cu o organizație o partajează cu toți membrii ei, de acum și de mai târziu.
Pe fir obiectul Org este camelCase — { id, name, ownerUserId, createdAt } — spre deosebire de orice alt obiect de pe această suprafață. Face parte din v1 și nu va fi redenumit.
| Metodă | Cale | Cine | Request | Răspuns |
|---|---|---|---|---|
POST | /v1/orgs | orice utilizator | { "name": string 1..200 } | 201 { id, name, ownerUserId, createdAt, role: "owner" } |
GET | /v1/orgs | orice utilizator | — | { orgs: [{ id, name, ownerUserId, createdAt, role }] } — organizațiile din care faci parte, cu rolul tău |
GET | /v1/orgs/:id/members | membru al organizației | — | { org_id, members: [{ user_id, role, created_at, email }] } |
POST | /v1/orgs/:id/members | owner sau admin al organizației | { "user_id": uuid } sau { "email": string } (exact unul), role? implicit member | 201 { org_id, user_id, role } — un upsert, deci re-postarea schimbă rolul |
DELETE | /v1/orgs/:id/members/:userId | owner sau admin al organizației | — | { deleted: true, org_id, user_id } |
Rolurile de membru sunt owner · admin · member. Doar owner-ul organizației poate acorda owner (403 — Only the org owner can grant the owner role.) și owner-ul nu poate fi eliminat (403 — The org owner cannot be removed.). Adăugarea cuiva care nu are cont codai este 404 (User not found.); un non-membru care citește lista primește 403.
# creezi o organizație și adaugi un coleg după 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" }'Fiecare mutație de share sau organizație scrie un rând de audit (share_add, share_remove, org:create, org:member_add, org:member_remove), așa că owner-ul poate reconstitui oricând cine a avut acces și când.
Streaming de sesiuni
Urmărește o sesiune live prin SSE sau WebSocket, reia de la orice seq și scrie idempotent, ca un retry să nu dubleze niciodată.
Releul de host-uri
Rulează o comandă shell sau citește un fișier pe desktopul tău de pe telefon, dintr-un browser sau dintr-un script — fără SSH, fără port de intrare, doar în același cont.