Skip to the documentation
API

Retrieve a member

One person, their role and their addresses, by account id.

GETapi.openemail.uk/members/{userId}

Runs the real call against your workspace, with your own key.

GET /members/{userId}

One person, their role and their addresses, by account id.

Example

Needs members:read. By USER ID: the userId off the list, not their email address.

curl
curl "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t" -H "$AUTH"
Response
{  "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"    }  ],  "createdAt": "2026-08-12T14:20:00.000Z"}

There is no lookup by email here. POST /members is the one call that takes one, because it is the one call whose caller genuinely does not have a user id yet.

A user id that is not on this workspace is a plain 404. It is the one case in this resource that is unambiguously “no such resource”. The same condition raised by a write that could not be read back maps to 422, which is right there and wrong here.

Read off the full members list rather than by a single-row query, deliberately: a member is the UNION of a role row and a set of address grants, either of which can exist without the other, and that union is computed in exactly one place. A single-row query would be a second implementation of it, and the population it would quietly miss is the legacy grant holders, who are most of the table today.