Ir a la documentación
API

Listar roles

Todos los roles del espacio de trabajo, primero los integrados, con cuántas personas y claves tiene cada uno.

GETapi.openemail.uk/roles

Ejecuta la llamada real contra tu espacio de trabajo, con tu propia clave.

GET /roles

Todos los roles del espacio de trabajo, primero los integrados, con cuántas personas y claves tiene cada uno.

Dos ejes, y no son la misma pregunta

shell
export OE=https://api.openemail.ukexport AUTH="Authorization: Bearer $OPENEMAIL_API_KEY"

Un ROL dice qué PUEDE HACER alguien en este espacio de trabajo: leer correo, enviarlo, editar plantillas, añadir un dominio. Una CONCESIÓN dice sobre qué DIRECCIONES puede hacerlo, y vive al lado, en /members/{userId}/addresses, como member (lee la dirección y envía como ella) o viewer (solo la lee). Ambos deben coincidir antes de que salga un mensaje: un rol con emails:send y sin concesiones no puede enviar desde ninguna dirección, y todas las direcciones del espacio de trabajo bajo una concesión de viewer tampoco permiten enviar desde ninguna.

Todos los espacios de trabajo se precargan con los mismos seis roles. Owner, Admin, Member y Viewer forman una escalera. Cada uno tiene todo lo que tiene el siguiente, así que degradar a alguien estrecha su acceso en lugar de cambiarlo por una porción distinta. Developer y Billing no son peldaños de esa escalera: Developer construye integraciones (claves, webhooks, plantillas, envío) y no lee nada del correo del espacio de trabajo, y Billing ve el plan y las facturas y nada más. Ambos quedan estrictamente dentro de Admin. Se precargan en la primera lectura y no al crear el espacio de trabajo, así que un espacio de trabajo creado antes de que existiera esta función los adquiere en cuanto algo los pide. builtin indica de qué plantilla precargada salió una fila, y eso es todo lo que indica: los seis son un punto de partida que un espacio de trabajo debe moldear, y todos salvo Owner se pueden renombrar, repermisionar y eliminar. Ramifica sobre editable y deletable y no sobre el nombre: un rol que alguien renombró sigue respondiendo correctamente a esos dos, y su nombre ya no te dice nada.

Owner es la única excepción, y lo es en todas las direcciones: editable: false, deletable: false, y rechazado como destino en PATCH /members/{userId}. Describe la cuenta sobre la que está indexado el espacio de trabajo y tiene todos los permisos, incluidos los añadidos en versiones posteriores, y por eso su lista se calcula en lugar de almacenarse. Convertir a otra persona en propietaria es una transferencia del espacio de trabajo; aquí no hay ningún endpoint que la realice.

Los otros cinco lo aceptan todo: una nueva lista de permisos, una nueva descripción, un nuevo nombre, un DELETE. Son valores predeterminados precargados y no elementos fijos: un espacio de trabajo que nunca construye una integración debería poder deshacerse de Developer, y uno en el que «Member» signifique algo más estrecho debería poder decirlo con sus propias palabras. Solo el propietario se niega, y se niega a todo bajo un único código: role_immutable, un 409 con param: "roleId", tanto si el PATCH llevaba un nombre como una lista de permisos. Ya no se rechaza ningún cambio de nombre por sí solo, así que no hay ninguna inmutabilidad con param: "name" que gestionar; el único 409 que todavía puede provocar un nombre es role_name_taken, cuando otro rol del espacio de trabajo ya responde a él.

Más allá de los seis, un espacio de trabajo escribe hasta 24 roles propios. El tope cuenta solo esos, así que eliminar un rol precargado no gana espacio bajo él. Los permisos se EXPANDEN al entrar en lugar de tomarse literalmente (templates:write por sí solo se almacena como templates:read y templates:write), así que vuelve a leer la lista de la respuesta en lugar de suponer que es la que enviaste.

Un rol es también el techo de una clave de API. Una clave emitida contra uno puede hacer key.scopes ∩ role.permissions y nada más, resuelto por solicitud en el límite, así que editar un rol cambia lo que sus claves pueden hacer en su siguiente llamada, y una clave sin rol no tiene ningún techo. La página Scopes lo explica por completo.

Ejemplo

Requiere roles:read. Sin cursor. El sobre lleva hasMore y nextCursor para que un cliente pueda pasarlo al mismo código de listado que cualquier otra colección, y nunca hay una segunda página.

curl
curl "$OE/roles" -H "$AUTH"
Respuesta
{  "object": "list",  "data": [    {      "object": "role",      "id": "role_1c94e05d3862c1f0a44b7f3a",      "name": "Owner",      "description": "The person the workspace belongs to. Holds everything, including additions.",      "permissions": ["emails:send", "emails:read", "…", "workspace:manage"],      "builtin": "owner",      "editable": false,      "deletable": false,      "members": 0,      "apiKeys": 2,      "createdAt": "2026-08-01T09:00:00.000Z",      "updatedAt": "2026-08-01T09:00:00.000Z"    },    {      "object": "role",      "id": "role_c40a95f21cc65d31c2a89e07",      "name": "Viewer",      "description": "Reads the mail on the addresses they hold, and changes nothing.",      "permissions": [        "emails:read",        "drafts:read",        "threads:read",        "labels:read",        "contacts:read",        "calendar:read",        "templates:read",        "rules:read",        "connections:read",        "settings:read"      ],      "builtin": "viewer",      "editable": true,      "deletable": true,      "members": 3,      "apiKeys": 1,      "createdAt": "2026-08-01T09:00:00.000Z",      "updatedAt": "2026-08-01T09:00:00.000Z"    }  ],  "hasMore": false,  "nextCursor": null}

Ordenados por rango integrado y luego por nombre (owner, admin, member, viewer, developer, billing, y después el resto alfabéticamente) en lugar de por fecha descendente como el resto de la API. Una matriz de permisos se lee como una escalera, y ordenarla por createdAt pone el rol más amplio en una fila distinta cada semana.

Leer esta lista es lo que PRECARGA los seis en un espacio de trabajo que nunca ha tenido ninguno. La precarga entra en conflicto con un índice único y no hace nada la segunda vez, así que la llamada es idempotente y solo la primera escribe, que es también por lo que POST /members siempre puede nombrar un roleId que existe.

Precarga UNA SOLA VEZ. El espacio de trabajo registra que ya se precargó, así que esta lectura completa un espacio de trabajo más antiguo que la función y después no vuelve a escribir nunca, que es lo que hace que eliminar un rol precargado sea permanente. Una versión anterior reinsertaba en cada lectura la fila de plantilla que faltara, de modo que un Billing eliminado volvía con un id nuevo en la siguiente carga de página; ya no lo hace.

members y apiKeys son lo que habría que trasladar antes de que el rol pueda desaparecer, y es lo que permite a un cliente avisar antes de ofrecer la eliminación en vez de después del 409. La fila del propietario suele mostrar members: 0: el propietario no es miembro de su propio espacio de trabajo, es la cuenta sobre la que está indexado.

Hay un tope estricto de 24 roles personalizados precisamente para que esto pueda ser una única respuesta. Un espacio de trabajo con cuarenta roles no puede responder a «quién puede enviar como billing@» con solo mirar, que es la única pregunta que esta función existe para poder responder.