Listar membros
Toda a gente no espaço de trabalho, a função que cada um tem, e os endereços que a cada um foram dados.
Executa a chamada real contra o seu espaço de trabalho, com a sua própria chave.
GET /members
Toda a gente no espaço de trabalho, a função que cada um tem, e os endereços que a cada um foram dados.
Um membro são duas concessões, não uma
export OE=https://api.openemail.ukexport AUTH="Authorization: Bearer $OPENEMAIL_API_KEY"role é o que PODEM FAZER: uma linha, uma função, o mesmo objeto que /roles descreve. addresses é AQUILO A QUE o podem fazer: uma entrada por endereço, cada uma com o seu próprio access. Um cliente não os deve juntar: uma função com emails:send e um array addresses vazio é alguém que pode enviar a partir de nada, e um array addresses cheio sob uma função de viewer é também alguém que pode enviar a partir de nada. O caminho de envio verifica ambos, e um ecrã que mostre apenas um deles vai explicar com toda a confiança a recusa errada.
As linhas de endereço dizem access onde a coluna guardada diz role, e a mudança de nome é o ponto e não uma arrumação: este objeto já tem um campo role que significa outra coisa completamente diferente, e dois role a um nível de aninhamento de distância com valores de dois vocabulários diferentes é um bug à espera da primeira pessoa que o leia depressa. access é member, que lê o endereço e envia como ele, ou viewer, que apenas o lê.
implied: true significa que NINGUÉM ESCOLHEU ESTA FUNÇÃO. A partilha existia muito antes das funções, por isso a maioria das pessoas com acesso a uma caixa de correio tem concessões de endereço e nenhuma linha de membro; em vez de lhes negar o correio até uma migração ter corrido, o serviço infere uma função integrada a partir da concessão mais ampla que detêm e comunica-a com role.id a null. Mostre isso como "implícito pelo acesso" e não como uma função que alguém escolheu. Até um PATCH transformar a inferência numa decisão, alargar o acesso aos endereços alarga em silêncio o que podem fazer.
O PROPRIETÁRIO é a PRIMEIRA linha, marcada com isOwner: true, com role.builtin igual a owner. É a conta em que o espaço de trabalho está ancorado, tem todas as permissões por definição, e POST, PATCH e DELETE recusam-no a todos com member_is_owner. Por isso um espaço de trabalho não partilhado comunica um membro em vez de nenhum. Conte os lugares excluindo isOwner.
Exemplo
Requer members:read. O proprietário vem primeiro, depois toda a gente por email e não pela data de entrada, porque esta lista é lida para encontrar uma pessoa e não para ver o que mudou.
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}Duas populações numa só lista, e tem de ser assim: alguém pode ter uma função e nenhum endereço, e alguém pode ter um endereço e nenhuma linha de função. Listar apenas a interseção esconderia ambas, e na maioria dos espaços de trabalho o segundo grupo é o maior.
createdAt é null para quem tem concessões mas nunca teve uma linha de membro escrita, as mesmas pessoas para quem implied é true. É quando lhes foi dada uma FUNÇÃO, não quando lhes foi partilhado o primeiro endereço.
permissions é a lista plana já resolvida em vez de um conjunto de booleans. Um cliente que pergunta "isto inclui templates:write" não pode ficar atrasado em relação ao vocabulário; um cliente a quem se entrega { canEditTemplates: true } fica, e em silêncio.
Sem cursor, com o envelope habitual. Os membros de um espaço de trabalho estão limitados pelo número de pessoas com quem o proprietário efetivamente o partilhou, e paginar isso seria cerimónia à frente de algo que um cliente vai buscar uma vez e apresenta inteiro.