Список участников
Все в рабочем пространстве, роль каждого и адреса, которые каждому выданы.
Выполняет настоящий запрос в вашем рабочем пространстве, с вашим собственным ключом.
GET /members
Все в рабочем пространстве, роль каждого и адреса, которые каждому выданы.
Участник — это две выдачи, а не одна
export OE=https://api.openemail.ukexport AUTH="Authorization: Bearer $OPENEMAIL_API_KEY"role — это то, что человеку МОЖНО ДЕЛАТЬ: одна строка, одна роль, тот же объект, который описывает /roles. addresses — это то, НАД ЧЕМ он это может делать: по одной записи на адрес, каждая со своим access. Клиент не должен сливать их воедино: роль с emails:send и пустым массивом addresses — это человек, который может отправлять ниоткуда, а полный массив addresses под ролью viewer — это тоже человек, который может отправлять ниоткуда. Путь отправки проверяет обе стороны, и экран, показывающий одну из них, уверенно объяснит не тот отказ.
Строки адресов говорят access там, где в хранимой колонке написано role, и переименование здесь — суть, а не наведение порядка: в этом объекте уже есть поле role, означающее совсем другое, а два role на соседних уровнях вложенности со значениями из двух разных словарей — это ошибка, ждущая первого, кто прочитает их бегло. access — это member, который читает адрес и отправляет от его имени, или viewer, который только читает.
implied: true означает, что ЭТУ РОЛЬ НИКТО НЕ ВЫБИРАЛ. Общий доступ появился задолго до ролей, поэтому у большинства людей с доступом к почтовому ящику есть выданные адреса и вообще нет строки участника; вместо того чтобы лишать их почты до прогона бэкфилла, сервис выводит встроенную роль из самого широкого доступа, который у них есть, и сообщает её с role.id, равным null. Показывайте это как «следует из доступа», а не как роль, которую кто-то выбрал. Пока PATCH не превратит эту догадку в решение, расширение их доступа к адресам молча расширяет и то, что им можно делать.
ВЛАДЕЛЕЦ — это ПЕРВАЯ строка, помеченная isOwner: true, с role.builtin, равным owner. Это аккаунт, к которому привязано рабочее пространство, он по определению обладает всеми разрешениями, и POST, PATCH и DELETE отказывают ему с member_is_owner. Поэтому рабочее пространство без общего доступа сообщает об одном участнике, а не о нуле. Считайте места, исключая isOwner.
Пример
Требует members:read. Владелец идёт первым, затем все остальные по адресу электронной почты, а не по дате вступления, потому что этот список читают, чтобы найти одного человека, а не чтобы увидеть, что изменилось.
curl "$OE/members" -H "$AUTH"{ "object": "list", "data": [ { "object": "member", "userId": "nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t", "email": "[email protected]", "name": "Sam Okonjo", "image": null, "role": { "id": "role_2b81de079c1f0a4b7e05d386", "name": "Support", "builtin": null }, "implied": false, "permissions": [ "emails:send", "emails:read", "threads:read", "threads:write", "labels:read", "labels:write", "contacts:read" ], "addresses": [ { "addressId": "2b81de07-9c1f-4a4b-8e05-d3862c1f0a44", "address": "[email protected]", "access": "member" }, { "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8", "address": "[email protected]", "access": "viewer" } ], "createdAt": "2026-08-12T14:20:00.000Z" }, { "object": "member", "userId": "7fQ2mN8vBz1aRd4tYwKx7fQ2mN8vBz1a", "email": "[email protected]", "name": null, "image": null, "role": { "id": null, "name": "Viewer", "builtin": "viewer" }, "implied": true, "permissions": [ "emails:read", "drafts:read", "threads:read", "labels:read", "contacts:read", "calendar:read", "templates:read", "rules:read", "connections:read", "settings:read" ], "addresses": [ { "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8", "address": "[email protected]", "access": "viewer" } ], "createdAt": null } ], "hasMore": false, "nextCursor": null}Две группы в одном списке, и иначе нельзя: у кого-то есть роль и ни одного адреса, а у кого-то — адрес и ни одной строки роли. Перечисление только пересечения скрыло бы обе группы, а в большинстве рабочих пространств вторая группа крупнее.
createdAt равно null для того, у кого есть выданные адреса, но строка участника никогда не записывалась, — то есть для тех же людей, у кого implied равно true. Это момент, когда человеку дали РОЛЬ, а не когда ему впервые открыли адрес.
permissions — это плоский вычисленный список, а не набор булевых флагов. Клиент, спрашивающий «есть ли здесь templates:write», не может отстать от словаря; клиент, которому вручили { canEditTemplates: true }, отстанет незаметно.
Без курсора, со стандартной обёрткой. Состав рабочего пространства ограничен тем, скольким людям владелец реально открыл доступ, и пагинация здесь была бы церемонией вокруг того, что клиент запрашивает один раз и рисует целиком.