> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Members

> List members, update roles, transfer ownership, and leave an organization.

Manage users within your organization. The endpoints on this page scope
to the org bound to your API key — you don't need to pass an org id.

## Endpoints

| Method   | Path                                         | Required role | Description            |
| -------- | -------------------------------------------- | ------------- | ---------------------- |
| `GET`    | `/v1/members`                                | any member    | List members           |
| `DELETE` | `/v1/members/{member_id}`                    | `admin+`      | Remove a member        |
| `PATCH`  | `/v1/members/{member_id}/role`               | `owner`       | Update a member's role |
| `POST`   | `/v1/members/{member_id}/transfer-ownership` | `owner`       | Transfer ownership     |
| `POST`   | `/v1/leave`                                  | any member    | Leave the organization |

## Member object

```json theme={null}
{
  "id": 1,
  "email": "jane@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "role": "admin",
  "has_passkey": true,
  "created_at": "2026-04-20T18:24:10.113Z"
}
```

| Field                     | Type      | Description                                                  |
| ------------------------- | --------- | ------------------------------------------------------------ |
| `id`                      | integer   | Membership id (not user id)                                  |
| `email`                   | string    | Member's email                                               |
| `first_name`, `last_name` | string    | Member's display name                                        |
| `role`                    | string    | `owner`, `admin`, or `member`                                |
| `has_passkey`             | boolean   | Whether the member has a passkey registered on their account |
| `created_at`              | timestamp | ISO 8601 UTC                                                 |

### Role hierarchy

| Role     | Can invite | Can remove members           | Can change roles | Can transfer ownership |
| -------- | ---------- | ---------------------------- | ---------------- | ---------------------- |
| `owner`  | ✓          | ✓ (including admins)         | ✓                | ✓                      |
| `admin`  | ✓          | ✓ (members only, not admins) | —                | —                      |
| `member` | —          | —                            | —                | —                      |

Each org has exactly one `owner`.

***

## List members

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.thunderphone.com/v1/members \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```

  ```python Python theme={null}
  members = requests.get(
      "https://api.thunderphone.com/v1/members",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
  ).json()
  ```

  ```javascript Node.js theme={null}
  const members = await fetch("https://api.thunderphone.com/v1/members", {
    headers: { Authorization: `Bearer ${process.env.THUNDERPHONE_API_KEY}` },
  }).then((r) => r.json());
  ```
</CodeGroup>

Returns a JSON array of [Member objects](#member-object), sorted by `created_at` ascending.

***

## Remove a member

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.thunderphone.com/v1/members/5 \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```

  ```python Python theme={null}
  requests.delete(
      f"https://api.thunderphone.com/v1/members/{member_id}",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
  )
  ```
</CodeGroup>

Returns `204 No Content`.

| Status | Condition                                                                                         |
| ------ | ------------------------------------------------------------------------------------------------- |
| `204`  | Removed                                                                                           |
| `400`  | Caller tried to remove themself — use [`POST /v1/leave`](#leave-organization) instead             |
| `403`  | Caller is not admin/owner; caller is admin trying to remove another admin; or target is the owner |
| `404`  | No such member in this org                                                                        |

<Note>
  You cannot remove yourself with this endpoint — use
  [`POST /v1/leave`](#leave-organization) instead.
</Note>

***

## Update member role

Only the owner can change roles. Supported target roles are `admin` and
`member`. To promote someone to owner, use
[Transfer ownership](#transfer-ownership).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH https://api.thunderphone.com/v1/members/5/role \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"role": "admin"}'
  ```

  ```python Python theme={null}
  requests.patch(
      f"https://api.thunderphone.com/v1/members/{member_id}/role",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
      json={"role": "admin"},
  )
  ```
</CodeGroup>

| Field  | Type   | Required | Allowed values    |
| ------ | ------ | -------- | ----------------- |
| `role` | string | yes      | `admin`, `member` |

Returns `200 OK` with the updated [Member object](#member-object).

***

## Transfer ownership

Promotes another member to `owner` and demotes the current owner to
`admin`. Atomic — if any step fails, no change is applied.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/members/5/transfer-ownership \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```

  ```python Python theme={null}
  requests.post(
      f"https://api.thunderphone.com/v1/members/{member_id}/transfer-ownership",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
  )
  ```
</CodeGroup>

<Warning>
  Irreversible without the new owner's cooperation. Make sure you trust
  the recipient before calling this endpoint.
</Warning>

Returns `200 OK`:

```json theme={null}
{ "detail": "Ownership transferred." }
```

Errors:

| Status | Condition                                                            |
| ------ | -------------------------------------------------------------------- |
| `400`  | Target is already the owner (e.g. you passed your own membership id) |
| `403`  | Caller is not the owner                                              |
| `404`  | Target membership not found                                          |

***

## Leave organization

Remove the caller's own membership from the org.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/leave \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```

  ```python Python theme={null}
  requests.post(
      "https://api.thunderphone.com/v1/leave",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
  )
  ```
</CodeGroup>

Returns `204 No Content`. Errors:

| Status | Condition                                                                                     |
| ------ | --------------------------------------------------------------------------------------------- |
| `403`  | Caller is the owner — transfer ownership first, **or** this is the caller's only organization |
| `404`  | Caller is no longer a member of this org                                                      |

***

## Related

<CardGroup cols={2}>
  <Card title="Invites" icon="envelope" href="/api-reference/invites">
    Invite users to join this organization.
  </Card>

  <Card title="Organizations" icon="building" href="/api-reference/organizations">
    Manage the org resource itself.
  </Card>
</CardGroup>
