Conceder e revogar um endereço
O segundo eixo: a que endereços uma pessoa pode chegar, e a que nível.
Executa qualquer uma das 2 chamadas desta página contra o seu espaço de trabalho, com a sua própria chave.
POST /members/{userId}/addresses
O segundo eixo: a que endereços uma pessoa pode chegar, e a que nível.
Uma concessão não é uma função
access é o vocabulário mais antigo por endereço e deliberadamente não se sobrepõe aos nomes das permissões: member lê o endereço e envia como ele, viewer apenas o lê. Nada diz sobre se a pessoa pode sequer enviar, o que é a sua função, e ambos têm de permitir um envio antes de este acontecer.
| A função | A concessão sobre billing@ | Pode enviar como billing@ |
|---|---|---|
| tem `emails:send` | member | Sim. |
| tem `emails:send` | viewer | Não, a concessão recusa-o. |
| sem `emails:send` | member | Não, a função recusa-o. |
| tem `emails:send` | sem qualquer concessão | Não, o endereço nunca entra na lista contra a qual um envio é verificado. |
Dar uma função a alguém não lhe dá endereços nenhuns. Um membro com uma função e sem concessões abre uma caixa de correio VAZIA em vez da de toda a gente, que é a falha certa a ter enquanto ainda está a decidir o que essa pessoa deve ver.
Conceder um endereço
Requer members:write. POST /members/{userId}/addresses com { addressId, access }; access assume member por omissão. Devolve o membro inteiro tal como fica.
curl -X POST "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses" -H "$AUTH" \ -H "Content-Type: application/json" \ -d '{ "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8", "access": "viewer" }'{ "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"], "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" }POST sobre a subcoleção em vez de um PUT sobre o par, porque de qualquer forma é um upsert e o id da linha não é algo que quem chama alguma vez nomeie. Voltar a fazer POST com um access diferente é como um viewer se torna member: há uma linha por (endereço, pessoa), portanto uma segunda chamada altera o nível em vez de acrescentar uma segunda concessão. É também isso que faz deste o raro POST que é seguro repetir.
Protegido por members:write em vez de pela posse do endereço, que é a diferença entre isto e o antigo caminho de concessão no router de domínios. A posse é a proteção certa para quem colocou lá o domínio e a errada para um administrador que não possui nada e gere os acessos do espaço de trabalho em nome do proprietário. Ambos escrevem a mesma linha.
O membro inteiro volta em vez de apenas a concessão, para que a linha no ecrã possa ser redesenhada sem um segundo pedido, e para que a resposta se leia da mesma maneira quer a concessão fosse nova quer fosse uma alteração.
Um endereço que não pertence a este espaço de trabalho é member_not_found, um 422, com param: "addressId". Uma chave só pode distribuir endereços pertencentes ao espaço de trabalho para o qual foi emitida.
Conceder ao PROPRIETÁRIO do espaço de trabalho é member_is_owner, um 422. Já tem todos os endereços nele, portanto não há nada que a chamada pudesse acrescentar.
Revogar um endereço
Requer members:write. DELETE /members/{userId}/addresses/{addressId}. Devolve o membro, menos esse endereço.
curl -X DELETE \ "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses/c40a95f2-1cc6-4d31-82a8-9e075d31c2a8" \ -H "$AUTH"{ "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"], "addresses": [ { "addressId": "2b81de07-9c1f-4a4b-8e05-d3862c1f0a44", "address": "[email protected]", "access": "member" } ], "createdAt": "2026-08-12T14:20:00.000Z" }A revogação estreita, e aquela a que se deve recorrer quando alguém muda de equipa: mantém a função e os outros endereços e deixa de ver este.
Um endereço que não pertence a este espaço de trabalho é recusado em vez de ignorado em silêncio. Caso contrário, um erro de escrita no id comunicaria uma revogação bem-sucedida que nunca aconteceu, que é precisamente a falha que este endpoint existe para evitar.
O membro volta em vez de uma lápide, porque a resposta interessante é aquilo a que ainda pode chegar. Um { deleted: true } aqui deixaria o cliente a descobrir isso por subtração.
Para retirar tudo de uma vez, DELETE /members/{userId} remove a função e todas as concessões em conjunto e comunica quantas foram.