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

# API Key Management

> Create, list, update, and delete API keys programmatically.

Routeway's key management endpoints let you create and configure API keys without visiting the dashboard. This is essential for automating key rotation, provisioning keys for new services, and enforcing per-key spending limits.

<Info>
  All endpoints on this page require a **management key**. Create one from [Dashboard → Management Keys](https://routeway.ai/dashboard/management-keys).
</Info>

<Info>
  The full key value is only returned once — when you create it. After that, the key is masked in list and detail responses. Store it securely immediately after creation.
</Info>

## List All Keys

`GET /v1/account/keys` returns all API keys for your account with masked values.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import os
    import requests

    headers = {"Authorization": f"Bearer {os.getenv('ROUTEWAY_MANAGEMENT_KEY')}"}

    response = requests.get("https://api.routeway.ai/v1/account/keys", headers=headers)
    keys = response.json()["data"]

    for key in keys:
        print(f"ID: {key['api_key_id']} | Label: {key['label']} | Key: {key['key']}")
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch("https://api.routeway.ai/v1/account/keys", {
      headers: { Authorization: `Bearer ${process.env.ROUTEWAY_MANAGEMENT_KEY}` },
    });

    const { data: keys } = await response.json();

    for (const key of keys) {
      console.log(`ID: ${key.api_key_id} | Label: ${key.label} | Key: ${key.key}`);
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.routeway.ai/v1/account/keys \
      -H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY"
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "data": [
    {
      "api_key_id": 1,
      "key": "rw-abc1234...5678",
      "label": "production",
      "daily_limit": 1000,
      "created_at": "2025-06-01T00:00:00Z"
    },
    {
      "api_key_id": 2,
      "key": "rw-def5678...9012",
      "label": "staging",
      "daily_limit": 100,
      "created_at": "2025-06-10T00:00:00Z"
    }
  ]
}
```

***

## Create a Key

`POST /v1/account/keys` creates a new API key with optional configuration.

### Parameters

| Parameter          | Type      | Description                                             |
| ------------------ | --------- | ------------------------------------------------------- |
| `label`            | string    | Human-readable name (e.g. `"production"`, `"staging"`)  |
| `daily_limit`      | integer   | Maximum spend or requests per day                       |
| `minute_limit`     | integer   | Maximum requests per minute                             |
| `allowed_models`   | string\[] | Whitelist of model IDs this key can access              |
| `balance`          | number    | Pre-allocated balance (in dollars) attached to this key |
| `use_subs_first`   | boolean   | Consume subscription quota before PAYG credit           |
| `fallback_to_payg` | boolean   | Fall back to PAYG when subscription quota is exhausted  |

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import os
    import requests

    headers = {
        "Authorization": f"Bearer {os.getenv('ROUTEWAY_MANAGEMENT_KEY')}",
        "Content-Type": "application/json"
    }

    response = requests.post(
        "https://api.routeway.ai/v1/account/keys",
        headers=headers,
        json={
            "label": "backend-service",
            "daily_limit": 500,
            "minute_limit": 30,
            "allowed_models": ["gpt-4o", "gpt-4o-mini", "claude-sonnet-4-20250514"]
        }
    )

    new_key = response.json()["data"]
    print(f"Key created: {new_key['key']}")  # Save this! Only shown once.
    print(f"ID: {new_key['api_key_id']}")
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch("https://api.routeway.ai/v1/account/keys", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.ROUTEWAY_MANAGEMENT_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        label: "backend-service",
        daily_limit: 500,
        minute_limit: 30,
        allowed_models: ["gpt-4o", "gpt-4o-mini", "claude-sonnet-4-20250514"],
      }),
    });

    const { data: newKey } = await response.json();
    console.log(`Key created: ${newKey.key}`); // Save this! Only shown once.
    console.log(`ID: ${newKey.api_key_id}`);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.routeway.ai/v1/account/keys \
      -H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "label": "backend-service",
        "daily_limit": 500,
        "minute_limit": 30,
        "allowed_models": ["gpt-4o", "gpt-4o-mini", "claude-sonnet-4-20250514"]
      }'
    ```
  </Tab>
</Tabs>

<Warning>
  The full API key value is only returned in the creation response. Copy and store it in a secrets manager immediately — you cannot retrieve it again.
</Warning>

***

## Get Key Details

`GET /v1/account/keys/{key_id}` returns detailed information about a specific key, including current usage.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    key_id = 1

    response = requests.get(
        f"https://api.routeway.ai/v1/account/keys/{key_id}",
        headers=headers
    )

    detail = response.json()["data"]
    print(f"Label: {detail['label']}")
    print(f"Usage today: ${detail['usage_today']:.2f}")
    print(f"Daily limit: {detail['daily_limit']}")
    print(f"Last used: {detail['last_used_at']}")
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.routeway.ai/v1/account/keys/1 \
      -H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY"
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "data": {
    "api_key_id": 1,
    "key": "rw-abc1234...5678",
    "label": "production",
    "daily_limit": 1000,
    "minute_limit": 60,
    "balance": 10.00,
    "usage_today": 3.21,
    "usage_minute": 0,
    "created_at": "2025-06-01T00:00:00Z",
    "last_used_at": "2025-06-15T11:00:00Z",
    "use_subs_first": true,
    "fallback_to_payg": false
  }
}
```

### Key Detail Fields

| Field              | Description                                     |
| ------------------ | ----------------------------------------------- |
| `api_key_id`       | Unique identifier for the key                   |
| `key`              | Masked key value                                |
| `label`            | Human-readable name                             |
| `daily_limit`      | Maximum spend/requests per day                  |
| `minute_limit`     | Maximum requests per minute                     |
| `balance`          | Pre-allocated balance on this key               |
| `usage_today`      | Amount spent today                              |
| `usage_minute`     | Requests made in the current minute             |
| `created_at`       | When the key was created                        |
| `last_used_at`     | When the key was last used for a request        |
| `use_subs_first`   | Whether subscription quota is used before PAYG  |
| `fallback_to_payg` | Whether PAYG is used when subscription runs out |

***

## Update a Key

`PATCH /v1/account/keys/{key_id}` updates one or more settings on an existing key. Only include the fields you want to change.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    key_id = 1

    response = requests.patch(
        f"https://api.routeway.ai/v1/account/keys/{key_id}",
        headers=headers,
        json={
            "label": "production-v2",
            "daily_limit": 2000,
            "allowed_models": ["gpt-4o", "gpt-4o-mini"]
        }
    )

    updated = response.json()["data"]
    print(f"Updated key {updated['api_key_id']}: {updated['label']}")
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X PATCH https://api.routeway.ai/v1/account/keys/1 \
      -H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "label": "production-v2",
        "daily_limit": 2000
      }'
    ```
  </Tab>
</Tabs>

<Tip>
  Use updates to adjust limits dynamically — for example, increase a key's `daily_limit` during a traffic spike, or tighten `allowed_models` for a service that should only use cheap models.
</Tip>

***

## Delete a Key

`DELETE /v1/account/keys/{key_id}` permanently deletes a key. Any requests using this key will immediately start returning `401`.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    key_id = 2

    response = requests.delete(
        f"https://api.routeway.ai/v1/account/keys/{key_id}",
        headers=headers
    )

    print(response.json()["message"])  # "API key successfully deleted."
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X DELETE https://api.routeway.ai/v1/account/keys/2 \
      -H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY"
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "message": "API key successfully deleted."
}
```

<Warning>
  Deletion is permanent and immediate. Any application using this key will lose access instantly. Make sure to rotate keys gracefully — create the new key first, update your services, then delete the old one.
</Warning>

***

## Key Rotation Pattern

A safe key rotation workflow:

```python theme={null}
import os
import requests

headers = {
    "Authorization": f"Bearer {os.getenv('ROUTEWAY_MANAGEMENT_KEY')}",
    "Content-Type": "application/json"
}

# 1. Create new key with same settings
response = requests.post(
    "https://api.routeway.ai/v1/account/keys",
    headers=headers,
    json={"label": "production-rotated", "daily_limit": 1000}
)
new_key = response.json()["data"]["key"]
print(f"New key: {new_key}")

# 2. Deploy new key to your services
# ... update secrets manager, redeploy, etc.

# 3. Verify the new key is working
# ... check activity logs for requests using the new key

# 4. Delete the old key
old_key_id = 1
requests.delete(
    f"https://api.routeway.ai/v1/account/keys/{old_key_id}",
    headers=headers
)
print(f"Old key {old_key_id} deleted.")
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Use descriptive labels" icon="tag">
    Name keys after the service or environment they belong to (e.g. `"prod-backend"`, `"staging-worker"`). This makes it easy to audit usage.
  </Card>

  <Card title="Set daily limits" icon="shield">
    Always configure a `daily_limit` on production keys to prevent runaway costs from bugs or attacks.
  </Card>

  <Card title="Restrict models" icon="lock">
    Use `allowed_models` to limit expensive models to keys that actually need them. A chatbot key probably doesn't need access to image generation models.
  </Card>

  <Card title="Rotate regularly" icon="refresh-cw">
    Rotate keys periodically (e.g. monthly) and immediately if a key may have been exposed.
  </Card>
</CardGroup>
