Saltar para a documentação
API

Conceder e revogar um endereço

O segundo eixo: a que endereços uma pessoa pode chegar, e a que nível.

POSTapi.openemail.uk/members/{userId}/addresses

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çãoA concessão sobre billing@Pode enviar como billing@
tem `emails:send`memberSim.
tem `emails:send`viewerNão, a concessão recusa-o.
sem `emails:send`memberNão, a função recusa-o.
tem `emails:send`sem qualquer concessãoNã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
curl -X POST "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses" -H "$AUTH" \    -H "Content-Type: application/json" \    -d '{ "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8", "access": "viewer" }'
Resposta
{    "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
curl -X DELETE \    "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses/c40a95f2-1cc6-4d31-82a8-9e075d31c2a8" \    -H "$AUTH"
Resposta
{    "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.