# Members

The people in the organization, their status, and their permissions.

A member receives permissions directly and through their teams. Permission
policies control their direct access; team permissions are inherited. You
can grant only access you hold and are allowed to manage.

Suspension pauses access while keeping permissions. Removal revokes the
member's sessions and personal API keys in the organization, and keeps the
record as `deprovisioned` for past decisions and audit events.

See [Membership management](/docs/web-app/membership-management) for the
member list, status changes and directory-managed members, or
[Permissions](/docs/web-app/permissions) for assigning access.

## List members

`GET /api/v1/members`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Requires: `membership.read`

Returns every member of the organization, with their status and the roles they hold, directly or through their teams.

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `limit` | query | integer | no | How many members to return. Defaults to 200. |

### Response

| Status | Body | Description |
| --- | --- | --- |
| 200 | object | The members |
| 401 | ErrorResponse | You are not signed in |
| 403 | ErrorResponse | You cannot read members |

Response body (200):

- `members` · array<Member> · required
  - `id` · uuid · required: The membership id. Other endpoints refer to a member by this id.
  - `display_name` · string · required
  - `email` · string · required
  - `status` · enum · required: `active` can sign in and act. `suspended` cannot until reactivated. `deprovisioned` was removed and is kept for the record. One of `active`, `suspended`, `deprovisioned`.
  - `assignments` · array<RoleAssignment> · required: The roles the member holds, directly and through their teams.
    - `id` · uuid · required
    - `organization_id` · uuid · required
    - `principal_kind` · enum · required: What holds the role. One of `membership`, `team`, `agent`.
    - `principal_id` · uuid · required: The membership, team or agent that holds it.
    - `scope_kind` · enum · required: Where the role applies. One of `organization`, `team`, `agent`.
    - `scope_id` · string: The team id or the agent slug. Absent for `organization`.
    - `scope_name` · string: The team's name, for a team scope.
    - `source` · enum · required: Whether a person granted it or your directory did. One of `manual`, `directory`.
    - `source_key` · string: The directory group that produced it. Present for `directory` only.
    - `granted_by_actor_id` · uuid: The member who granted it. Present for `manual` only.
    - `via_team_id` · uuid: The team the role is inherited through. Present when a member holds it through a team rather than directly.
    - `via_team_name` · string: That team's name.
    - `created_at` · date-time · required
    - `permissions` · array<string> · required
    - `is_owner` · boolean · required
    - `permission_policy_id` · uuid
  - `admission_source` · enum · required: How the person joined: added by hand, by accepting an invitation, on first SSO sign-in, or by directory sync. One of `manual`, `invite`, `sso_jit`, `directory`.
  - `directory_managed` · boolean · required: Whether your directory owns this membership. Status changes here are refused.
  - `team_ids` · array<uuid> · required: The teams the member is on.
  - `created_at` · date-time · required

### Example

```bash
curl -X GET "$WITHHUMAN_URL/api/v1/members" \
  -H "Authorization: Bearer $WITHHUMAN_API_KEY"
```

200 response

```json
{
  "members": [
    {
      "id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
      "display_name": "Ada Lovelace",
      "email": "ada@example.com",
      "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,
          "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"
    }
  ]
}
```

## Suspend or reactivate a member

`PATCH /api/v1/members/{id}`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Requires: `membership.write`

Sets a member's status to `suspended` or `active`. A suspended member cannot sign in or act until reactivated. Permissions are changed through 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

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes | The membership's id. |

Request body:

- `status` · enum · required: `active` or `suspended`. One of `active`, `suspended`.
- `force` · boolean: Suspend even while an active escalation path targets the member.

### Response

| Status | Body | Description |
| --- | --- | --- |
| 200 | object | The updated membership |
| 400 | ErrorResponse | `status` is not `active` or `suspended` |
| 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: `error.code` is `membership_in_escalation_path` and `error.details.escalation_paths` lists the paths |

Response body (200):

- `member` · Membership · required: A person's membership of the organization, as stored.
  - `id` · uuid · required: The membership id. Other endpoints refer to a member by this id.
  - `user_id` · uuid · required: The person's user id, shared across organizations.
  - `organization_id` · uuid · required
  - `status` · enum · required: `active` can sign in and act. `suspended` cannot until reactivated. `deprovisioned` was removed and is kept for the record. One of `active`, `suspended`, `deprovisioned`.
  - `admission_source` · enum · required: How the person joined: added by hand, by accepting an invitation, on first SSO sign-in, or by directory sync. One of `manual`, `invite`, `sso_jit`, `directory`.
  - `directory_managed` · boolean · required: Whether your directory owns this membership. Status changes here are refused.
  - `assignments` · array<RoleAssignment> · required: The roles the member holds, directly and through their teams.
    - `id` · uuid · required
    - `organization_id` · uuid · required
    - `principal_kind` · enum · required: What holds the role. One of `membership`, `team`, `agent`.
    - `principal_id` · uuid · required: The membership, team or agent that holds it.
    - `scope_kind` · enum · required: Where the role applies. One of `organization`, `team`, `agent`.
    - `scope_id` · string: The team id or the agent slug. Absent for `organization`.
    - `scope_name` · string: The team's name, for a team scope.
    - `source` · enum · required: Whether a person granted it or your directory did. One of `manual`, `directory`.
    - `source_key` · string: The directory group that produced it. Present for `directory` only.
    - `granted_by_actor_id` · uuid: The member who granted it. Present for `manual` only.
    - `via_team_id` · uuid: The team the role is inherited through. Present when a member holds it through a team rather than directly.
    - `via_team_name` · string: That team's name.
    - `created_at` · date-time · required
    - `permissions` · array<string> · required
    - `is_owner` · boolean · required
    - `permission_policy_id` · uuid
  - `team_ids` · array<uuid>: The teams the member is on.
  - `created_at` · date-time
  - `updated_at` · date-time

### Example

```bash
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
}'
```

200 response

```json
{
  "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,
        "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

`DELETE /api/v1/members/{id}`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Requires: `membership.write`

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

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes | The membership's id. |
| `force` | query | boolean | no | Remove even while an active escalation path targets the member. |

### Response

| 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: `error.code` is `membership_in_escalation_path` and `error.details.escalation_paths` lists the paths |

### Example

```bash
curl -X DELETE "$WITHHUMAN_URL/api/v1/members/{id}" \
  -H "Authorization: Bearer $WITHHUMAN_API_KEY"
```

## List permissions

`GET /api/v1/permissions`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Self-service: acts on the caller's own account, no permission needed.

Human permission vocabulary. Requires permission-policy read or write access at any scope.

### Request

No parameters or body.

### Response

| Status | Body | Description |
| --- | --- | --- |
| 200 | object | The permissions |
| 401 | ErrorResponse | You are not signed in |
| 403 | ErrorResponse | You cannot read roles |

Response body (200):

- `permissions` · array<PermissionDescriptor> · required
  - `key` · string · required: The permission key, shaped `resource.action`.
  - `area` · string · required: The key's first segment, for grouping.
  - `description` · string · required: What the permission allows.
  - `holders` · array<enum> · required: Who can hold it: people, agents, or the gateway.
  - `resource` · enum · required: What kind of thing a check on this permission is about. A grant must cover that thing's scope. One of `organization`, `team`, `agent`, `request`, `scope`.
  - `dangerous` · boolean · required: Whether granting or using it changes what other people can do, or cannot be undone. Such permissions need a fresh, strong sign-in to use and never arrive through directory sync or first SSO sign-in.

### Example

```bash
curl -X GET "$WITHHUMAN_URL/api/v1/permissions" \
  -H "Authorization: Bearer $WITHHUMAN_API_KEY"
```

200 response

```json
{
  "permissions": [
    {
      "key": "request.decide",
      "area": "request",
      "description": "Approve or deny requests routed to you",
      "holders": [
        "human"
      ],
      "resource": "organization",
      "dangerous": true
    }
  ]
}
```

## Get members permission policies

`GET /api/v1/members/{id}/permission_policies`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Self-service: acts on the caller's own account, no permission needed.

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes |  |

### Response

| 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 body (200):

- `name` · string · required
- `policies` · array<PermissionPolicy> · required
  - `scope_kind` · enum · required One of `organization`, `team`, `agent`.
  - `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
  - `permissions` · array<string> · required
  - `id` · uuid · required
  - `revision` · int64 · required
  - `resources` · array<PermissionResource> · required
    - `id` · string · required
    - `name` · string · required
    - `kind` · enum · required One of `organization`, `team`, `agent`.
  - `source` · enum · required One of `manual`, `directory`.
  - `via_team_id` · uuid
  - `via_team_name` · string
  - `can_edit` · boolean · required
  - `read_only_reason` · string
- `resources` · array<PermissionResource> · required
  - `id` · string · required
  - `name` · string · required
  - `kind` · enum · required One of `organization`, `team`, `agent`.
- `permissions` · array<PermissionDescriptor> · required
  - `key` · string · required: The permission key, shaped `resource.action`.
  - `area` · string · required: The key's first segment, for grouping.
  - `description` · string · required: What the permission allows.
  - `holders` · array<enum> · required: Who can hold it: people, agents, or the gateway.
  - `resource` · enum · required: What kind of thing a check on this permission is about. A grant must cover that thing's scope. One of `organization`, `team`, `agent`, `request`, `scope`.
  - `dangerous` · boolean · required: Whether granting or using it changes what other people can do, or cannot be undone. Such permissions need a fresh, strong sign-in to use and never arrive through directory sync or first SSO sign-in.
- `can_create` · boolean · required
- `is_owner` · boolean · required
- `read_only_reason` · string

### Example

```bash
curl -X GET "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies" \
  -H "Authorization: Bearer $WITHHUMAN_API_KEY"
```

200 response

```json
{
  "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

`POST /api/v1/members/{id}/permission_policies`

Auth: Reviewer session cookie (`withhuman_session`), browser only; a personal API key is refused

Requires: `permission_policy.write`

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes |  |
| `Idempotency-Key` | header | string | yes |  |

Request body:

- `scope_kind` · enum · required One of `organization`, `team`, `agent`.
- `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
- `permissions` · array<string> · required

### Response

| 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 body (201):

- `scope_kind` · enum · required One of `organization`, `team`, `agent`.
- `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
- `permissions` · array<string> · required
- `id` · uuid · required
- `revision` · int64 · required
- `resources` · array<PermissionResource> · required
  - `id` · string · required
  - `name` · string · required
  - `kind` · enum · required One of `organization`, `team`, `agent`.
- `source` · enum · required One of `manual`, `directory`.
- `via_team_id` · uuid
- `via_team_name` · string
- `can_edit` · boolean · required
- `read_only_reason` · string

### Example

```bash
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"
  ]
}'
```

201 response

```json
{
  "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

`GET /api/v1/members/{id}/permission_policies/{policy_id}`

Auth: Reviewer session cookie (`withhuman_session`) or personal API key (`Authorization: Bearer $WITHHUMAN_API_KEY`)

Self-service: acts on the caller's own account, no permission needed.

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes |  |
| `policy_id` | path | uuid | yes |  |

### Response

| 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 body (200):

- `scope_kind` · enum · required One of `organization`, `team`, `agent`.
- `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
- `permissions` · array<string> · required
- `id` · uuid · required
- `revision` · int64 · required
- `resources` · array<PermissionResource> · required
  - `id` · string · required
  - `name` · string · required
  - `kind` · enum · required One of `organization`, `team`, `agent`.
- `source` · enum · required One of `manual`, `directory`.
- `via_team_id` · uuid
- `via_team_name` · string
- `can_edit` · boolean · required
- `read_only_reason` · string

### Example

```bash
curl -X GET "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies/{policy_id}" \
  -H "Authorization: Bearer $WITHHUMAN_API_KEY"
```

200 response

```json
{
  "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

`PUT /api/v1/members/{id}/permission_policies/{policy_id}`

Auth: Reviewer session cookie (`withhuman_session`), browser only; a personal API key is refused

Requires: `permission_policy.write`

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes |  |
| `policy_id` | path | uuid | yes |  |
| `Idempotency-Key` | header | string | yes |  |

Request body:

- `scope_kind` · enum · required One of `organization`, `team`, `agent`.
- `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
- `permissions` · array<string> · required
- `revision` · int64 · required: Required when updating an existing policy.

### Response

| 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 body (200):

- `scope_kind` · enum · required One of `organization`, `team`, `agent`.
- `resource_ids` · array<string> · required: Empty for organization scope; otherwise the selected team IDs or agent slugs.
- `permissions` · array<string> · required
- `id` · uuid · required
- `revision` · int64 · required
- `resources` · array<PermissionResource> · required
  - `id` · string · required
  - `name` · string · required
  - `kind` · enum · required One of `organization`, `team`, `agent`.
- `source` · enum · required One of `manual`, `directory`.
- `via_team_id` · uuid
- `via_team_name` · string
- `can_edit` · boolean · required
- `read_only_reason` · string

### Example

```bash
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
}'
```

200 response

```json
{
  "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

`DELETE /api/v1/members/{id}/permission_policies/{policy_id}`

Auth: Reviewer session cookie (`withhuman_session`), browser only; a personal API key is refused

Requires: `permission_policy.write`

### Request

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes |  |
| `policy_id` | path | uuid | yes |  |
| `Idempotency-Key` | header | string | yes |  |
| `revision` | query | integer | yes |  |

### Response

| 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

```bash
curl -X DELETE "$WITHHUMAN_URL/api/v1/members/{id}/permission_policies/{policy_id}?revision=1" \
  -b "withhuman_session=$WITHHUMAN_SESSION" \
  -H "Idempotency-Key: string"
```
