Перейти к документации
API

Список участников

Все в рабочем пространстве, роль каждого и адреса, которые каждому выданы.

GETapi.openemail.uk/members

Выполняет настоящий запрос в вашем рабочем пространстве, с вашим собственным ключом.

GET /members

Все в рабочем пространстве, роль каждого и адреса, которые каждому выданы.

Участник — это две выдачи, а не одна

shell
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
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 }, отстанет незаметно.

Без курсора, со стандартной обёрткой. Состав рабочего пространства ограничен тем, скольким людям владелец реально открыл доступ, и пагинация здесь была бы церемонией вокруг того, что клиент запрашивает один раз и рисует целиком.