Memberships join a user to a workspace with a role and lifecycle status. The operator API lists people in the current workspace and lets administrators change role or status, or remove a non-owner membership.
Role and status are authority
Roles are owner, admin, member, and auditor; status determines whether the membership is active. Changing either refreshes that user's connected authority so an open LiveView or socket cannot retain stale permissions.
The owner is protected
This API rejects promotion to owner, changing the existing owner's role, and removing the owner. Use an explicit ownership-transfer workflow rather than trying to bypass these invariants.
Before you begin
A signed-in browser session with a selected workspace backed by an active membership is required; an archived workspace remains readable but rejects mutations. Every /api/v1/operator endpoint rejects API credentials and bearer tokens, regardless of their scopes.
Any role on an active membership can list members. Owner or admin membership is required to update or remove a membership.
The workspace_id path must match the selected workspace. Owner transfer is not supported through these endpoints.
How it works
Identify the membership row
List the selected workspace's memberships and use the membership id—not the user id—for update or delete. Confirm the nested user email and current role before changing authority.
Apply and verify
Change only role or status, then re-read the list. Removed or deactivated users may have their connected sessions refreshed or revoked, so coordinate changes that affect on-call operators.
Examples
These examples are illustrative. Replace the sample values with your own.
Keep credentials in environment variables or a secret manager, never in client-side code.
List current workspace members
Paste the UUID of the workspace currently selected in the application, then request only its membership collection.
javascript
const workspaceId = window.prompt("Current workspace UUID");
if (!workspaceId) throw new Error("A workspace UUID is required");
const response = await fetch(`/api/v1/operator/workspaces/${encodeURIComponent(workspaceId)}/members`, {
credentials: "same-origin",
headers: {"Accept": "application/json"}
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${body.detail}`);
console.log(body);
What to expect
200 OK. The response wrapper is {"memberships": []}; each populated item nests user and workspace and includes role, status, and last_seen_at.
Troubleshooting
A known workspace returns 404
Membership routes accept only the session's current workspace UUID. Select that workspace in the application before using its path.
An owner change is rejected
That protection is intentional. The membership update accepts role and status for non-owner rows but cannot create, modify, or remove workspace ownership.
Endpoint reference
Ready to integrate? Open an endpoint for its required permissions, request fields,
response format, and status codes. The examples above explain the workflow;
these details define each individual request.
GET
/api/v1/operator/workspaces/:workspace_id/members
Web Session
List workspace members
Description
Returns every membership row for the session's current workspace,
including the owner. The envelope is `memberships` (not `members`).
Each item is `role`, `status`, `last_seen_at`, `user{id,email}`, and
`workspace{id,name}` — not a flat `user_id` / `workspace_id` /
`user.name` shape.
`:workspace_id` must equal the session workspace; any other UUID is
404. Browser session; machine Bearer tokens are 401.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
workspace_id
path
string
Yes
Must be the session's current workspace UUID
Responses
200
Membership rows for the current workspace
Returns: MembershipList
Response Body
Field
Type
Required
Description
memberships
array<object>
Yes
Membership records
memberships[].id
string
Yes
Membership UUID
memberships[].status
string (active, invited, disabled)
Yes
Membership status
memberships[].user
object
Yes
Member user (id and email only; name is not rendered)
workspace_id is not the session's current workspace
PATCH
/api/v1/operator/workspaces/:workspace_id/members/:id
Web Session
Update member role or status
Description
Writes `membership.role` and/or `membership.status`. Neither field is
required; an empty `membership` object is a successful no-op. Roles
are `member`, `admin`, and `auditor` — the API never promotes anyone
to `owner`. Statuses are `active`, `invited`, and `disabled`. Setting
status to anything other than `active` revokes every browser session
for that user.
Owner rows cannot be mutated (`400` `cannot_change_owner`), including
sending `"role": "owner"`. Owner/admin only (`403` `admin_required`).
`:workspace_id` must be the session workspace (otherwise 404).
Auth
Web Session
Request Body
Field
Type
Required
Description
membership
object
Yes
Membership attributes to update. All fields optional.
membership.status
string (active, invited, disabled)
No
New membership status. Non-active values revoke the member's sessions.
membership.role
string (member, admin, auditor)
No
New role. owner is refused with 400 cannot_change_owner.
Parameters
Name
In
Type
Required
Description
workspace_id
path
string
Yes
Must be the session's current workspace UUID
id
path
string
Yes
Membership UUID
Responses
200
Updated membership
Returns: Membership
Response Body
Field
Type
Required
Description
id
string
Yes
Membership UUID
status
string (active, invited, disabled)
Yes
Membership status
user
object
Yes
Member user (id and email only; name is not rendered)
Owner protection (`cannot_change_owner`) or other atom error as Problem JSON detail
401
No operator browser session
403
Owner or admin membership required
404
Membership not found, or workspace_id is not the current workspace
422
Invalid role or status
DELETE
/api/v1/operator/workspaces/:workspace_id/members/:id
Web Session
Remove member
Description
Deletes a non-owner membership and revokes that user's browser
sessions. Removing the owner is refused (`400` `cannot_remove_owner`).
Owner/admin only. `:workspace_id` must be the session workspace.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
workspace_id
path
string
Yes
Must be the session's current workspace UUID
id
path
string
Yes
Membership UUID
Responses
204
Member removed
400
Cannot remove the workspace owner (`cannot_remove_owner`)
401
No operator browser session
403
Owner or admin membership required
404
Membership not found, or workspace_id is not the current workspace