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

# API Keys: create, list, update, and revoke credentials

> Create, list, update, and revoke Overwatch API keys via the REST API. The full key is shown only once at creation — store it immediately.

API keys let you authenticate programmatically with the Overwatch REST API. You can manage keys from the dashboard or through the API itself. Every key is scoped to your organization and carries a role that governs what it can do.

<Warning>
  Only organization **owners** can create, update, or delete API keys. Requests made with an `admin` or `viewer` key return `403 Forbidden` on all write operations in this section.
</Warning>

***

## List API keys

```
GET /api/v1/api-keys
```

Returns all API keys in your organization. The response includes metadata and a `keyPrefix` for identification, but never the full key value — Overwatch stores only a SHA-256 hash after creation.

### Response

```json theme={null}
{
  "data": [
    {
      "id": "key_01j...",
      "name": "CI deploy key",
      "keyPrefix": "ow_live_sk_a3f8",
      "role": "admin",
      "expiresAt": null,
      "lastUsedAt": "2025-04-15T09:45:00.000Z",
      "createdAt": "2025-01-15T00:00:00.000Z"
    }
  ]
}
```

<ResponseField name="data" type="ApiKey[]">
  Array of API key metadata objects.

  <Expandable title="ApiKey fields">
    <ResponseField name="id" type="string">Unique key ID. Use this to update or revoke the key.</ResponseField>
    <ResponseField name="name" type="string">Display name for the key.</ResponseField>
    <ResponseField name="keyPrefix" type="string">First 16 characters of the key (e.g. `ow_live_sk_a3f8`). Use this to identify the key in logs without exposing the full secret.</ResponseField>
    <ResponseField name="role" type="string">The role this key carries: `owner`, `admin`, or `viewer`.</ResponseField>
    <ResponseField name="expiresAt" type="string | null">ISO 8601 expiration timestamp, or `null` if the key does not expire.</ResponseField>
    <ResponseField name="lastUsedAt" type="string | null">ISO 8601 timestamp of the most recent authenticated request made with this key, or `null` if the key has never been used.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 creation timestamp.</ResponseField>
  </Expandable>
</ResponseField>

### Example

```bash theme={null}
curl https://overwatchapp.dev/api/v1/api-keys \
  -H "Authorization: Bearer $API_KEY"
```

***

## Create an API key

```
POST /api/v1/api-keys
```

Creates a new API key. The plaintext key is included in the response **once** and cannot be retrieved again. Store it immediately in a secrets manager or environment variable.

### Request body

<ParamField body="name" type="string" required>
  A descriptive name for the key, e.g. `"CI deploy key"` or `"Grafana dashboard"`.
</ParamField>

<ParamField body="role" type="string">
  Role to assign to the key: `owner`, `admin`, or `viewer`. Defaults to your own role. You cannot create a key with a higher role than your own.
</ParamField>

<ParamField body="expiresAt" type="string">
  Optional ISO 8601 date/time string after which the key is automatically rejected, e.g. `"2026-01-01T00:00:00.000Z"`. Omit for a non-expiring key.
</ParamField>

### Response

Returns `201 Created`. The `data` object includes all the standard metadata fields plus a `key` field containing the full plaintext API key.

```json theme={null}
{
  "data": {
    "id": "key_01j...",
    "name": "CI deploy key",
    "keyPrefix": "ow_live_sk_a3f8",
    "role": "admin",
    "expiresAt": null,
    "createdAt": "2025-04-15T10:00:00.000Z",
    "key": "ow_live_sk_a3f8c2d1e4b5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1"
  }
}
```

<ResponseField name="data.key" type="string">
  The full plaintext API key. This is the only time Overwatch returns the key value. Copy it now.
</ResponseField>

<Note>
  Overwatch stores only a SHA-256 hash of the key. If you lose the plaintext, you must revoke the key and create a new one.
</Note>

### Example

```bash theme={null}
curl -X POST https://overwatchapp.dev/api/v1/api-keys \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI deploy key",
    "role": "admin",
    "expiresAt": "2026-01-01T00:00:00.000Z"
  }'
```

***

## Update an API key

```
PATCH /api/v1/api-keys/:id
```

Updates the name, role, or expiration date of an existing key. You cannot rotate the key value itself — to get a new secret, delete the key and create a replacement.

### Path parameters

<ParamField path="id" type="string" required>
  The API key ID.
</ParamField>

### Request body

<ParamField body="name" type="string">
  New display name for the key.
</ParamField>

<ParamField body="role" type="string">
  New role: `owner`, `admin`, or `viewer`. You cannot assign a role higher than your own.
</ParamField>

<ParamField body="expiresAt" type="string | null">
  New expiration date as an ISO 8601 string, or `null` to remove an existing expiration and make the key non-expiring.
</ParamField>

### Response

Returns the updated key metadata with `200 OK`. The plaintext key is not included.

```json theme={null}
{
  "data": {
    "id": "key_01j...",
    "name": "CI deploy key (updated)",
    "keyPrefix": "ow_live_sk_a3f8",
    "role": "viewer",
    "expiresAt": null,
    "lastUsedAt": "2025-04-15T09:45:00.000Z",
    "createdAt": "2025-01-15T00:00:00.000Z"
  }
}
```

### Example

```bash theme={null}
curl -X PATCH https://overwatchapp.dev/api/v1/api-keys/$KEY_ID \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "role": "viewer" }'
```

***

## Revoke an API key

```
DELETE /api/v1/api-keys/:id
```

Permanently revokes an API key. Any requests made with the revoked key after deletion return `401 Unauthorized` immediately. This action is irreversible.

### Path parameters

<ParamField path="id" type="string" required>
  The API key ID.
</ParamField>

### Response

```json theme={null}
{
  "data": { "id": "key_01j..." }
}
```

### Example

```bash theme={null}
curl -X DELETE https://overwatchapp.dev/api/v1/api-keys/$KEY_ID \
  -H "Authorization: Bearer $API_KEY"
```
