Change a member's role or scope
The members.update operation: PATCH /api/v1/members/{id} in the REST API and the members_update tool in the MCP server.
/api/v1/members/{id}Changes a membership's role, its scope (the whole organization, one legal entity or one brand) or its live-mode access. Owners, admins and billing admins work at organization scope; finance and tax managers at the organization or one entity; support, developers and viewers also at one brand.
You can't grant more than you have: an admin can't make anyone an owner, can't change an owner's
membership, and can't grant live access without having it. The organization always keeps at least one
owner (last_owner). Needs members:admin (owners and admins); a security-tier change.
At a glance
- REST:
PATCH /api/v1/members/{id} - MCP tool:
members_update - Operation ID:
members.update - Scope: Organization
- Permission:
members:admin - Risk tier:
security - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyoptional - Modes: Test and live
- Authentication: API key with the
members:adminscope - Since: M1
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | mem_… ID |
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
role | one of org_owner, org_admin, billing_admin, finance, tax_manager, support, developer, viewer | No | |
scope | object | No | |
livemodeAccess | boolean | No |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
id | mem_… ID | |
object | "membership" | |
orgId | org_… ID | |
userId | usr_… ID | |
role | one of org_owner, org_admin, billing_admin, finance, tax_manager, support, developer, viewer | |
scope | object | |
livemodeAccess | boolean | |
invitedBy | usr_… ID or null | |
user | object or null | |
createdAt | date-time | |
updatedAt | date-time |
Examples
Give a brand developer live-mode access
PATCH /api/v1/members/mem_01m4tx5nj8emwbyf7y9vcf47x6
Authorization: Bearer or_test_…
Content-Type: application/json
{
"livemodeAccess": true
}
Response (200):
{
"id": "mem_01m4tx5nj8emwbyf7y9vcf47x6",
"object": "membership",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"userId": "usr_01m4tx5nj8emwbyf7y9vcf47xb",
"role": "developer",
"scope": {
"type": "brand",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4"
},
"livemodeAccess": true,
"invitedBy": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
"user": {
"email": "dev@acme.example",
"name": "Dana Developer"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Move a developer to the whole entity
PATCH /api/v1/members/mem_01m4tx5nj8emwbyf7y9vcf47x6
Authorization: Bearer or_test_…
Content-Type: application/json
{
"scope": {
"type": "entity",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2"
}
}
Response (200):
{
"id": "mem_01m4tx5nj8emwbyf7y9vcf47x6",
"object": "membership",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"userId": "usr_01m4tx5nj8emwbyf7y9vcf47xb",
"role": "developer",
"scope": {
"type": "entity",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2"
},
"livemodeAccess": false,
"invitedBy": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
"user": {
"email": "dev@acme.example",
"name": "Dana Developer"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | Nothing to change was sent, a field is malformed, or the role isn't allowed at the scope. | Fix the fields listed in details.issues and send the request again. |
resource_not_found | 404 | No such membership, or the new scope's entity or brand doesn't exist. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
role_not_grantable | 403 | The current or new access goes beyond your own. | Ask an organization owner to grant this role and scope, or pick a role and scope within your own access. |
last_owner | 409 | The change would leave the organization without an owner. | Make another member an owner first, then change or remove this membership. |
membership_exists | 409 | The person already has a membership at the new scope. | Change the role of the existing membership instead of adding another one. |
version_conflict | 409 | The membership changed at the same time; retry. | Fetch the object again and retry the change. |
permission_denied | 403 | You can't manage members of this organization. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.