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

# Update API Key

> Rename an API key or replace its permissions without rotating the secret

## Overview

Changes a key's name and/or permissions in place. The key material is untouched, so agents that already hold the key keep working with the new rules on their next call. Use this to tighten an allow-list, add a spend cap, or turn on the confirmation requirement for destructive calls without re-pasting a new secret into every agent config.

Permissions are replaced as a whole. To change one field, read the key first (`GET /v1/api-keys`) and send the full object back with the change.

**Auth:** JWT (dashboard) or an API key belonging to the same account.

## Path Parameters

<ParamField path="key_id" type="string" required>
  The API key UUID to update
</ParamField>

## Body

Send at least one field.

<ParamField body="name" type="string">
  New display name. Leading and trailing whitespace is trimmed; an empty name is rejected.
</ParamField>

<ParamField body="permissions" type="object">
  Replacement permissions. Send `{}` (or an object whose fields are all `null`) for full access.

  <Expandable title="Permissions object">
    <ParamField body="allowed_services" type="string[] | null">
      Service UUIDs this key may call. `null` means all services.
    </ParamField>

    <ParamField body="allowed_tools" type="string[] | null">
      Tool UUIDs this key may call. `null` means all tools. Services and tools are combined with OR.
    </ParamField>

    <ParamField body="max_spend_per_call_cents" type="integer | null">
      Refuse any single call priced above this amount.
    </ParamField>

    <ParamField body="max_spend_per_day_cents" type="integer | null">
      Refuse calls once the key's spend for the current UTC day would exceed this amount.
    </ParamField>

    <ParamField body="require_confirmation" type="boolean | null">
      When `true`, destructive tool calls (non-GET methods, or tools flagged destructive) return `409 confirmation_required` with a short-lived `confirm_token`; the call goes through only when it is repeated with that token. The token is bound to the key, the tool and the exact arguments, and expires after five minutes.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="agent_name" type="string">
  Name of the agent this key belongs to
</ParamField>

<ParamField body="agent_type" type="string">
  One of `coding_agent`, `assistant`, `workflow`, `service`, `other`
</ParamField>

<ParamField body="purpose" type="string">
  One line on what the key is for
</ParamField>

## Response

The updated key, in the same shape as `GET /v1/api-keys`. The secret is never returned here.

<ResponseField name="id" type="string">API key UUID</ResponseField>
<ResponseField name="key_prefix" type="string">First 8 characters of the key</ResponseField>
<ResponseField name="name" type="string">Key name</ResponseField>
<ResponseField name="created_at" type="string">Creation timestamp</ResponseField>
<ResponseField name="last_used" type="string">Last usage timestamp</ResponseField>
<ResponseField name="permissions" type="object">Permissions as stored. `null` means unrestricted.</ResponseField>

## Errors

| Status | Meaning                                            |
| ------ | -------------------------------------------------- |
| 400    | Empty body, or an empty name                       |
| 404    | No active key with that id belongs to this account |

Every update is recorded in the audit log as `key.update` with the list of changed fields.

## Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X PATCH "https://api.danubeai.com/v1/api-keys/key_abc123" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "permissions": {
        "allowed_services": ["service_uuid_1"],
        "allowed_tools": null,
        "max_spend_per_call_cents": null,
        "max_spend_per_day_cents": 500,
        "require_confirmation": true
      }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "id": "key_abc123",
    "key_prefix": "nQ3vX8pK",
    "name": "My Production Key",
    "created_at": "2026-01-15T10:00:00Z",
    "last_used": "2026-09-01T18:22:10Z",
    "permissions": {
      "allowed_services": ["service_uuid_1"],
      "allowed_tools": null,
      "max_spend_per_call_cents": null,
      "max_spend_per_day_cents": 500,
      "require_confirmation": true
    }
  }
  ```
</ResponseExample>
