> ## 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.

# API Keys

> Rotate the `sk_live_` API keys your integrations use.

API keys (`sk_live_...`) are the primary credential for the
ThunderPhone REST API. They are **secret** — treat them like a
password. Each key is bound to exactly one organization; when an API
call authenticates with a key, we look up the bound org automatically,
which is why the rest of this reference never asks for an org id in
the URL path.

This page documents the endpoints for **creating, listing, and
revoking** keys — the same operations the dashboard exposes at
**Settings → Keys**. You can create your first key from the
dashboard without ever using this API.

## Endpoints

| Method   | Path                              | Required role | Description          |
| -------- | --------------------------------- | ------------- | -------------------- |
| `GET`    | `/v1/developer/api-keys`          | `admin+`      | List API keys        |
| `POST`   | `/v1/developer/api-keys`          | `admin+`      | Create a new API key |
| `DELETE` | `/v1/developer/api-keys/{key_id}` | `admin+`      | Revoke an API key    |

<Warning>
  These endpoints require an `admin` or `owner` role. You can use them
  with an existing API key (if its creator has admin+ permissions) to
  rotate keys programmatically.
</Warning>

## API key object

```json theme={null}
{
  "id": "b1c2d3e4-...",
  "name": "production",
  "key_prefix": "sk_live_abcde12",
  "is_active": true,
  "created_at": "2026-04-20T18:24:10.113Z",
  "last_used_at": "2026-04-20T18:25:06.201Z",
  "revoked_at": null
}
```

| Field          | Type              | Description                                                                                                                 |
| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `id`           | UUID              | Public id used by the revoke endpoint                                                                                       |
| `name`         | string            | Display label                                                                                                               |
| `key_prefix`   | string            | First 15 chars of the raw key for UI display (always `sk_live_` + 7 hex chars). The full key is NOT returned after creation |
| `is_active`    | boolean           | `false` once the key is revoked                                                                                             |
| `created_at`   | timestamp         |                                                                                                                             |
| `last_used_at` | timestamp \| null | Updated best-effort on every successful request                                                                             |
| `revoked_at`   | timestamp \| null | If set, the key is revoked and will no longer authenticate                                                                  |

***

## List API keys

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

Returns an array of [API key objects](#api-key-object) — both active
and revoked keys, sorted by `created_at` descending.

***

## Create an API key

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/developer/api-keys \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "production"}'
  ```

  ```python Python theme={null}
  result = requests.post(
      "https://api.thunderphone.com/v1/developer/api-keys",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
      json={"name": "production"},
  ).json()
  new_key = result["key"]
  ```
</CodeGroup>

| Field  | Type   | Required | Description                                             |
| ------ | ------ | -------- | ------------------------------------------------------- |
| `name` | string | no       | Display label, 1–120 chars. Defaults to `"Default key"` |

Returns `201 Created` with the [API key object](#api-key-object) plus
an extra top-level `key` field containing the raw `sk_live_` value:

```json theme={null}
{
  "id": "b1c2d3e4-...",
  "name": "production",
  "key_prefix": "sk_live_abcde12",
  "is_active": true,
  "created_at": "2026-04-20T18:24:10.113Z",
  "last_used_at": null,
  "revoked_at": null,
  "key": "sk_live_abcdef1234567890abcdef1234567890abcdef123456"
}
```

<Warning>
  **`key` is returned only once.** Store it in your secret manager
  immediately — if you lose it, revoke it and create a new one. Every
  subsequent `GET` returns only the `key_prefix`.
</Warning>

***

## Revoke an API key

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

Returns `204 No Content`. Revoked keys are permanently invalidated —
all future requests using the key return `401 Unauthorized`. You
cannot un-revoke; create a new key instead.

<Note>
  You can revoke the key you're currently using, but do it from a
  different key or your revoke call will succeed and then your next
  call will fail.
</Note>

***

## Related

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/api-reference/introduction">
    How `sk_live_` keys are attached to requests.
  </Card>

  <Card title="Publishable Keys" icon="window-maximize" href="/api-reference/publishable-keys">
    Public `pk_live_` keys for the widget — different lifecycle.
  </Card>
</CardGroup>
