Members
The people in the organization, their status, and their permissions.
A member's direct access is a predefined role: owner, admin, reviewer or auditor. List the roles to see what each one holds, and change a member's role to replace all of their direct permissions with that role. Their team access doesn't change. Only an owner can grant the owner role. On the hosted edition, a member can instead hold custom permission policies, and team permissions are inherited by every member of the team.
Suspension pauses access while keeping the member's role and permissions.
Removal revokes the member's sessions and personal API keys in the
organization, disables their personal agents' instances, and keeps the
record as deprovisioned for past decisions and audit events.
See Membership management for the member list, status changes and directory-managed members, or Permissions for roles and access.
List members
Returns every member of the organization, with their status and the roles they hold, directly or through their teams.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
limit | query · integer | How many members to return. Defaults to 200. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The members |
401 | ErrorResponse | You are not signed in |
403 | ErrorResponse | You cannot read members |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/members" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"members": [
{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "Ada Lovelace",
"email": "[email protected]",
"status": "active",
"assignments": [
{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"principal_kind": "membership",
"principal_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"scope_kind": "organization",
"scope_id": "string",
"scope_name": "string",
"source": "manual",
"source_key": "string",
"granted_by_actor_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"created_at": "2026-09-08T12:02:11Z",
"permissions": [
"string"
],
"is_owner": true,
"built_in_role": "owner",
"permission_policy_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
}
],
"admission_source": "manual",
"directory_managed": true,
"team_ids": [
"7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
],
"created_at": "2026-09-08T12:02:11Z"
}
]
}List predefined roles
/api/v1/rolesSession or API keyThe predefined roles a person can be invited with or given, owner first, with the permissions each holds. They are the same in every organization.
Request
No parameters or body.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The predefined roles |
401 | ErrorResponse | You are not signed in |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/roles" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"roles": [
{
"key": "owner",
"name": "Reviewer",
"description": "string",
"permissions": [
"string"
],
"dangerous": true
}
]
}Give a member a predefined role
Gives the member one predefined role everywhere in the organization, replacing every permission they hold directly, custom permission policies included. What they inherit from teams and what your directory manages stay.
You cannot change your own role. Only an owner may grant the owner role or change a member who holds it, the organization must keep at least one active owner, and a role holding a sensitive permission needs a fresh sign-in.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The membership's id. |
Request body
A predefined role. owner is full control and only an owner may grant it; admin manages agents, pipelines, paths, members and teams; reviewer decides the requests routed to them; auditor reads everything without changing anything.
One of owner, admin, reviewer, auditor
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The updated membership |
400 | ErrorResponse | The role is unknown |
403 | ErrorResponse | You cannot change permissions, this is your own membership, the role or the member is an owner and you are not, or the role needs a fresher sign-in |
404 | ErrorResponse | No such member |
409 | ErrorResponse | The member is managed by your directory, or is the last active owner |
Response body200
A person's membership of the organization, as stored.
Example
curl -X PUT "$WITHHUMAN_URL/api/v1/members/{id}/role" \
-b "withhuman_session=$WITHHUMAN_SESSION" \
-H "Content-Type: application/json" \
-d '{
"role": "owner"
}'{
"member": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"user_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "active",
"admission_source": "manual",
"directory_managed": true,
"assignments": [
{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"principal_kind": "membership",
"principal_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"scope_kind": "organization",
"scope_id": "string",
"scope_name": "string",
"source": "manual",
"source_key": "string",
"granted_by_actor_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"created_at": "2026-09-08T12:02:11Z",
"permissions": [
"string"
],
"is_owner": true,
"built_in_role": "owner",
"permission_policy_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
}
],
"team_ids": [
"7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
],
"created_at": "2026-09-08T12:02:11Z",
"updated_at": "2026-09-08T12:02:11Z"
}
}Suspend or reactivate a member
Sets a member's status to suspended or active. A suspended member cannot sign in or act until reactivated. Permissions are changed through PUT /api/v1/members/{id}/role or, where the edition offers custom permissions, the member's permission policies.
You cannot change your own membership. Changing a member who holds the owner role requires holding it yourself. Members managed by your directory cannot be changed here, and the organization must keep at least one active owner.
Suspending a member that an active escalation path or team escalation policy still targets is refused with membership_in_escalation_path; the paths are listed in details.escalation_paths and the policies in details.team_escalation_policies. Pass force to suspend anyway. Those targets then reach nobody until the path or policy is edited.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The membership's id. |
Request body
Suspend even while an active escalation path targets the member.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The updated membership |
400 | ErrorResponse |
|
403 | ErrorResponse | You cannot change members, this is your own membership, or the member holds the owner role and you do not |
404 | ErrorResponse | No such member |
409 | ErrorResponse | The member is managed by your directory, is already removed, or is the last active owner. Or an active escalation path targets the member: |
Response body200
A person's membership of the organization, as stored.
Example
curl -X PATCH "$WITHHUMAN_URL/api/v1/members/{id}" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "active",
"force": true
}'{
"member": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"user_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "active",
"admission_source": "manual",
"directory_managed": true,
"assignments": [
{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"principal_kind": "membership",
"principal_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"scope_kind": "organization",
"scope_id": "string",
"scope_name": "string",
"source": "manual",
"source_key": "string",
"granted_by_actor_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"created_at": "2026-09-08T12:02:11Z",
"permissions": [
"string"
],
"is_owner": true,
"built_in_role": "owner",
"permission_policy_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
}
],
"team_ids": [
"7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
],
"created_at": "2026-09-08T12:02:11Z",
"updated_at": "2026-09-08T12:02:11Z"
}
}Remove a member
Removes a member from the organization. Their sessions are revoked at once. The membership record is kept with status deprovisioned, because decisions and audit events refer to it.
You cannot remove yourself. Removing a member who holds the owner role requires holding it yourself, and the organization must keep at least one active owner.
Removing a member that an active escalation path or team escalation policy still targets is refused with membership_in_escalation_path; the paths are listed in details.escalation_paths and the policies in details.team_escalation_policies. Pass force=true to remove anyway. Those targets then reach nobody until the path or policy is edited, and the audit event records which paths and policies were left behind.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The membership's id. |
force | query · boolean | Remove even while an active escalation path targets the member. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
204 | The member is removed | |
403 | ErrorResponse | You cannot change members, this is your own membership, or the member holds the owner role and you do not |
404 | ErrorResponse | No such member |
409 | ErrorResponse | The member is managed by your directory or is the last active owner. Or an active escalation path targets the member: |
Example
curl -X DELETE "$WITHHUMAN_URL/api/v1/members/{id}" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"List permissions
/api/v1/permissionsSession or API keyHuman permission vocabulary. Requires permission-policy read or write access at any scope.
Request
No parameters or body.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The permissions |
401 | ErrorResponse | You are not signed in |
403 | ErrorResponse | You cannot read roles |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/permissions" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"permissions": [
{
"key": "request.decide",
"area": "request",
"description": "Approve or deny requests routed to you",
"holders": [
"human"
],
"resource": "organization",
"dangerous": true
}
]
}Get members permission policies
/api/v1/members/{id}/permission_policiesSession or API keyRequest
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | PermissionPoliciesPage | Policy operation completed |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"name": "string",
"policies": [
{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
],
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1,
"resources": [
{
"id": "string",
"name": "string",
"kind": "organization"
}
],
"source": "manual",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"can_edit": true,
"read_only_reason": "string"
}
],
"resources": [
{
"id": "string",
"name": "string",
"kind": "organization"
}
],
"permissions": [
{
"key": "request.decide",
"area": "request",
"description": "Approve or deny requests routed to you",
"holders": [
"human"
],
"resource": "organization",
"dangerous": true
}
],
"can_create": true,
"is_owner": true,
"read_only_reason": "string"
}Post members permission policies
Refused with 403 custom_permissions_unavailable where the edition offers predefined roles alone (custom_permissions_enabled false).
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | |
Idempotency-Keyrequired | header · string |
Request body
One of organization, team, agent
Empty for organization scope; otherwise the selected team IDs or agent slugs.
Response
Response codes
| Status | Body | Description |
|---|---|---|
201 | PermissionPolicy | Policy operation completed |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body201
One of organization, team, agent
Empty for organization scope; otherwise the selected team IDs or agent slugs.
One of manual, directory
Example
curl -X POST "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies" \
-b "withhuman_session=$WITHHUMAN_SESSION" \
-H "Idempotency-Key: string" \
-H "Content-Type: application/json" \
-d '{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
]
}'{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
],
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1,
"resources": [
{
"id": "string",
"name": "string",
"kind": "organization"
}
],
"source": "manual",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"can_edit": true,
"read_only_reason": "string"
}Get members permission policy
/api/v1/members/{id}/permission_policies/{policy_id}Session or API keyRequest
Parameters
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | PermissionPolicy | Policy operation completed |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
One of organization, team, agent
Empty for organization scope; otherwise the selected team IDs or agent slugs.
One of manual, directory
Example
curl -X GET "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies/{policy_id}" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
],
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1,
"resources": [
{
"id": "string",
"name": "string",
"kind": "organization"
}
],
"source": "manual",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"can_edit": true,
"read_only_reason": "string"
}Put members permission policy
/api/v1/members/{id}/permission_policies/{policy_id}Session cookieRequires permission_policy.writeRefused with 403 custom_permissions_unavailable where the edition offers predefined roles alone (custom_permissions_enabled false).
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | |
policy_idrequired | path · uuid | |
Idempotency-Keyrequired | header · string |
Request body
One of organization, team, agent
Empty for organization scope; otherwise the selected team IDs or agent slugs.
Required when updating an existing policy.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | PermissionPolicy | Policy operation completed |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
One of organization, team, agent
Empty for organization scope; otherwise the selected team IDs or agent slugs.
One of manual, directory
Example
curl -X PUT "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies/{policy_id}" \
-b "withhuman_session=$WITHHUMAN_SESSION" \
-H "Idempotency-Key: string" \
-H "Content-Type: application/json" \
-d '{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
],
"revision": 1
}'{
"scope_kind": "organization",
"resource_ids": [
"string"
],
"permissions": [
"string"
],
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1,
"resources": [
{
"id": "string",
"name": "string",
"kind": "organization"
}
],
"source": "manual",
"via_team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"via_team_name": "string",
"can_edit": true,
"read_only_reason": "string"
}Delete members permission policy
/api/v1/members/{id}/permission_policies/{policy_id}Session cookieRequires permission_policy.writeRefused with 403 custom_permissions_unavailable where the edition offers predefined roles alone (custom_permissions_enabled false).
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | |
policy_idrequired | path · uuid | |
Idempotency-Keyrequired | header · string | |
revisionrequired | query · integer |
Response
Response codes
| Status | Body | Description |
|---|---|---|
204 | Policy operation completed | |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Example
curl -X DELETE "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies/{policy_id}?revision=1" \
-b "withhuman_session=$WITHHUMAN_SESSION" \
-H "Idempotency-Key: string"