# API keys (/docs/reference/api/keys)



API keys [#api-keys]

API keys need admin permission to manage keys. User requests follow organization membership and key access rules.

GET `/v1/keys` [#get-v1keys]

List API keys for the current cluster. Requires an `admin` API key or JWT.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in [Authentication](/docs/reference/authentication#existing-database-roles).

Request:

```bash
# List all API keys for a cluster.
curl -X GET "https://api.rawtree.com/v1/keys" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"
```

Expected response: **HTTP 200**.

```json
{
  "keys": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "token": "...abcd1234",
      "name": "reporting",
      "principal_type": "user",
      "principal_id": "11111111-1111-4111-8111-111111111111",
      "expires_at": null,
      "permission": "read_only",
      "database": {
        "name": "analytics"
      },
      "created_at": "2026-11-09T10:00:00Z"
    }
  ]
}
```

Errors: `401`, `403`. See [API errors](/docs/reference/errors).

POST `/v1/keys` [#post-v1keys]

Create a cluster-wide API key. Requires an `admin` API key or JWT. The database
selected on this request is stored as the key's default for later requests that
omit a database selector; if none is selected, the service stores `default`.

```json
{ "name": "my-agent", "permission": "read_write" }
```

Valid permissions:

* `admin`
* `read_write`
* `write_only`
* `read_only`

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in [Authentication](/docs/reference/authentication#existing-database-roles).

Parameters:

| Field            | Location | Type                    | Required | Notes                                                               |
| ---------------- | -------- | ----------------------- | -------- | ------------------------------------------------------------------- |
| `principal_type` | body     | null or PrincipalType   | No       | —                                                                   |
| `principal_id`   | body     | string or null          | No       | —                                                                   |
| `expires_at`     | body     | string or null          | No       | Expiration instant in RFC 3339 format. Omitted or null means never. |
| `name`           | body     | string                  | Yes      | —                                                                   |
| `permission`     | body     | null or PermissionLevel | No       | —                                                                   |
| `database_roles` | body     | array or null           | No       | Existing ClickHouse roles. Mutually exclusive with permission.      |

Request:

```bash
# Create a new API key for a cluster.
curl -X POST "https://api.rawtree.com/v1/keys?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "reporting",
  "permission": "read_only"
}'
```

Expected response: **HTTP 201**.

```json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "token": "rt_REPLACE_WITH_RETURNED_TOKEN",
  "name": "reporting",
  "principal_type": "user",
  "principal_id": "11111111-1111-4111-8111-111111111111",
  "expires_at": null,
  "permission": "read_only",
  "database": {
    "name": "analytics"
  }
}
```

Errors: `400`, `401`, `403`. See [API errors](/docs/reference/errors).

DELETE `/v1/keys/{id_or_token}` [#delete-v1keysid_or_token]

Delete an API key by UUID or full `rt_...` token.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in [Authentication](/docs/reference/authentication#existing-database-roles).

Request:

```bash
# Permanently delete an API key (cannot be undone).
curl -X DELETE "https://api.rawtree.com/v1/keys/11111111-1111-4111-8111-111111111111" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"
```

Expected response: **HTTP 200**.

```json
{
  "deleted": true
}
```

Errors: `400`, `401`, `403`. See [API errors](/docs/reference/errors).
