Update a role
Every field optional, and `permissions` replaces the whole list.
Runs the real call against your workspace, with your own key.
PATCH /roles/{id}
Every field optional, and permissions replaces the whole list.
Example
Needs roles:write. Omitting a field leaves it alone, which is what PATCH means.
curl -X PATCH "$OE/roles/role_2b81de079c1f0a4b7e05d386" -H "$AUTH" \ -H "Content-Type: application/json" \ -d '{ "permissions": ["emails:read", "threads:read", "labels:read", "contacts:read"] }'{ "object": "role", "id": "role_2b81de079c1f0a4b7e05d386", "name": "Support", "description": "Answers the shared inboxes and nothing else.", "permissions": ["emails:read", "threads:read", "labels:read", "contacts:read"], "builtin": null, "editable": true, "deletable": true, "members": 3, "apiKeys": 1, "createdAt": "2026-08-30T10:41:02.000Z", "updatedAt": "2026-08-30T13:02:19.000Z"}permissions REPLACES the whole list. There is no grant-one call and there will not be one: a list is what gets audited, and an index-addressed patch is a lost update the moment two tabs are open. Read the role, change the entry you meant, send all of them back. Sending one permission does not add a permission. It leaves the role holding exactly that one, plus whatever it implies.
description is nullable as well as optional, and the difference is the whole point of a patch: omitting it keeps the stored sentence, sending null clears it. Without the nullable there would be no way to remove a description except by replacing it with a space.
The owner is the only role a PATCH refuses, and it refuses every field of one: role_immutable, a 409 with param: "roleId". Everything else takes a new name as readily as a new permission list, the seeded roles included. builtin records where a role came from, not what may be done to it. A name another role already holds is role_name_taken instead, a 409 with param: "name".
The edit lands on the NEXT request made by anybody holding the role, API keys included, because the ceiling is resolved per request rather than cached. Narrowing a role is therefore a live revocation that takes effect without the keys under it being rotated. Widening one is live too, which is the half worth remembering.