Przejdź do dokumentacji
API

Wypisz role

Każda rola w przestrzeni roboczej, wbudowane na początku, wraz z liczbą osób i kluczy, które ją mają.

GETapi.openemail.uk/roles

Uruchamia prawdziwe wywołanie na twojej przestrzeni roboczej, twoim własnym kluczem.

GET /roles

Każda rola w przestrzeni roboczej, wbudowane na początku, wraz z liczbą osób i kluczy, które ją mają.

Dwie osie, i nie jest to to samo pytanie

shell
export OE=https://api.openemail.ukexport AUTH="Authorization: Bearer $OPENEMAIL_API_KEY"

ROLA mówi, co ktoś MOŻE ROBIĆ w tej przestrzeni roboczej: czytać pocztę, wysyłać ją, edytować szablony, dodać domenę. NADANIE (grant) mówi, których ADRESÓW to dotyczy, i mieszka obok, pod /members/{userId}/addresses, jako member (czyta adres i wysyła jako on) albo viewer (tylko czyta). Zanim wiadomość wyjdzie, oba muszą się zgodzić: rola z emails:send bez żadnych nadań nie wyśle z niczego, i tak samo nic nie wyśle adres w przestrzeni roboczej objęty nadaniem viewer.

Każda przestrzeń robocza dostaje na start te same sześć ról. Owner, Admin, Member i Viewer tworzą drabinę. Każda obejmuje wszystko, co niższa, więc degradacja kogoś zawęża jego dostęp, zamiast wymieniać go na inny wycinek. Developer i Billing nie są jej szczeblami: Developer buduje integracje (klucze, webhooki, szablony, wysyłka) i nie czyta żadnej poczty przestrzeni roboczej, a Billing widzi plan i faktury, i nic więcej. Oba mieszczą się ściśle wewnątrz Admin. Są zakładane przy pierwszym odczycie, a nie przy tworzeniu przestrzeni roboczej, więc przestrzeń powstała przed tą funkcją dorabia je w chwili, w której cokolwiek o nie zapyta. builtin mówi, z którego ziarna pochodzi dany wiersz, i tylko tyle: ta szóstka to punkt wyjścia, który przestrzeń robocza ma ukształtować po swojemu, a każdą z nich poza Owner można przemianować, przebudować jej uprawnienia i usunąć. Rozgałęziaj kod na editable i deletable, a nie na nazwie: rola, której ktoś zmienił nazwę, wciąż odpowiada poprawnie na te dwa pola, a jej nazwa nie mówi już nic.

Owner jest jedynym wyjątkiem i jest wyjątkiem pod każdym względem: editable: false, deletable: false i odmowa, gdy wskażesz go jako cel w PATCH /members/{userId}. Opisuje konto, na którym oparta jest przestrzeń robocza, i ma każde uprawnienie, łącznie z dodanymi w późniejszym wydaniu, dlatego jego lista jest wyliczana, a nie przechowywana. Uczynienie kogoś innego właścicielem to przeniesienie przestrzeni roboczej; nie ma tu endpointu, który by je wykonywał.

Pozostała piątka przyjmuje wszystko: nową listę uprawnień, nowy opis, nową nazwę, DELETE. To domyślne role założone na start, a nie elementy stałe: przestrzeń robocza, która nigdy nie buduje integracji, powinna móc pozbyć się Developera, a taka, w której „Member” znaczy coś węższego, powinna móc powiedzieć to własnymi słowami. Odmawia tylko właściciel i odmawia wszystkiego pod jednym kodem: role_immutable, 409 z param: "roleId", niezależnie od tego, czy PATCH niósł nazwę, czy listę uprawnień. Żadna zmiana nazwy nie jest już odrzucana osobno, więc nie ma niezmienności z param: "name", którą trzeba by obsłużyć; jedyne 409, jakie wciąż może wywołać nazwa, to role_name_taken, gdy inna rola w przestrzeni roboczej już się tak nazywa.

Poza tą szóstką przestrzeń robocza zapisuje do 24 własnych ról. Limit liczy tylko je, więc usunięcie roli założonej na start nie kupuje pod nim miejsca. Uprawnienia są ROZWIJANE przy zapisie, a nie brane dosłownie (samo templates:write jest zapisywane jako templates:read i templates:write), więc odczytaj listę z odpowiedzi, zamiast zakładać, że jest tą, którą wysłałeś.

Rola jest też pułapem dla klucza API. Klucz wydany pod nią może key.scopes ∩ role.permissions i nic ponadto, rozstrzygane per żądanie na granicy, więc edycja roli zmienia to, co wolno jej kluczom, już przy ich następnym wywołaniu, a klucz bez roli nie ma pułapu w ogóle. Wszystko o tym jest na stronie Zakresy.

Przykład

Wymaga roles:read. Bez kursora. Koperta odpowiedzi niesie hasMore i nextCursor, żeby klient mógł podać ją temu samemu kodowi listy co każdą inną kolekcję, a drugiej strony nigdy nie ma.

curl
curl "$OE/roles" -H "$AUTH"
Odpowiedź
{  "object": "list",  "data": [    {      "object": "role",      "id": "role_1c94e05d3862c1f0a44b7f3a",      "name": "Owner",      "description": "The person the workspace belongs to. Holds everything, including additions.",      "permissions": ["emails:send", "emails:read", "…", "workspace:manage"],      "builtin": "owner",      "editable": false,      "deletable": false,      "members": 0,      "apiKeys": 2,      "createdAt": "2026-08-01T09:00:00.000Z",      "updatedAt": "2026-08-01T09:00:00.000Z"    },    {      "object": "role",      "id": "role_c40a95f21cc65d31c2a89e07",      "name": "Viewer",      "description": "Reads the mail on the addresses they hold, and changes nothing.",      "permissions": [        "emails:read",        "drafts:read",        "threads:read",        "labels:read",        "contacts:read",        "calendar:read",        "templates:read",        "rules:read",        "connections:read",        "settings:read"      ],      "builtin": "viewer",      "editable": true,      "deletable": true,      "members": 3,      "apiKeys": 1,      "createdAt": "2026-08-01T09:00:00.000Z",      "updatedAt": "2026-08-01T09:00:00.000Z"    }  ],  "hasMore": false,  "nextCursor": null}

Sortowane według rangi wbudowanej, a potem nazwy (owner, admin, member, viewer, developer, billing, dalej reszta alfabetycznie), a nie od najnowszych jak reszta API. Macierz uprawnień czyta się jak drabinę, a sortowanie jej po createdAt co tydzień umieszcza najszerszą rolę w innym wierszu.

Odczyt tej listy jest tym, co ZAKŁADA sześć ról w przestrzeni roboczej, która nie miała żadnej. Zakładanie wchodzi w konflikt na unikalnym indeksie i za drugim razem nie robi nic, więc wywołanie jest idempotentne i zapisuje tylko pierwsze — dlatego też POST /members zawsze może wskazać istniejące roleId.

Zakłada je RAZ. Przestrzeń robocza odnotowuje, że zostały założone, więc ten odczyt uzupełnia przestrzeń starszą niż ta funkcja i potem już nigdy nie pisze, co sprawia, że usunięcie założonej roli jest trwałe. Wcześniejsza wersja wstawiała z powrotem każdy brakujący wiersz szablonowy przy każdym odczycie, więc usunięty Billing wracał pod nowym id przy kolejnym wczytaniu strony; teraz już nie.

members i apiKeys to to, co trzeba by przenieść, zanim rola mogłaby zniknąć, i to pozwala klientowi ostrzec przed pokazaniem opcji usunięcia, a nie po 409. Wiersz właściciela zwykle pokazuje members: 0: właściciel nie jest członkiem własnej przestrzeni roboczej, jest kontem, na którym ona się opiera.

Twardy limit 24 własnych ról istnieje właśnie po to, by to mogła być jedna odpowiedź. Przestrzeń robocza z czterdziestoma rolami nie jest w stanie odpowiedzieć „kto może wysyłać jako billing@”, patrząc na listę, a to jedyne pytanie, dla którego ta funkcja istnieje.