> For the complete documentation index, see [llms.txt](https://docs.duku.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.duku.ai/integrations/api-keys.md).

# API Keys

API keys provide machine-to-machine access to the Duku platform.

Each API key is one base64-encoded string. It contains the OAuth2 client ID and secret. Exchange the key for a short-lived Bearer token, then use the token against the GraphQL API.

### Limits and scope

* Each key is scoped to one organisation.
* Each user can have up to **10 API keys**.
* Keys do not expire unless you set an expiry during creation.
* Organisation admins can create, view, rotate, and revoke keys.

### Generate a key

1. Open **Settings → API Keys** in Viewport
2. Click **Generate API Key**
3. Enter a label like `GitHub Actions` or `CI Pipeline`
4. Click **Generate**
5. Copy the API key.

{% hint style="warning" %}
The API key is shown once. Store it in your secret manager immediately.
{% endhint %}

### Exchange the key for an access token

Base64-decode the key, then split its value on the first colon.

```bash
DECODED_KEY=$(printf '%s' '<your_api_key>' | base64 --decode)
CLIENT_ID=${DECODED_KEY%%:*}
CLIENT_SECRET=${DECODED_KEY#*:}

curl -X POST https://auth.duku.ai/realms/duku/protocol/openid-connect/token \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET"
```

Example response:

```json
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer"
}
```

Access tokens are short-lived, typically about five minutes. Fetch a fresh token rather than caching one for a long-running job.

### Use the access token

```bash
curl -X POST https://platform.duku.ai/graphql \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ subjects { id name } }"}'
```

### Rotate a key

1. Open **Settings → API Keys**
2. Click **Rotate** on the key
3. Copy and securely store the new API key. It is shown once.
4. The previous key is invalid immediately

### Revoke a key

1. Open **Settings → API Keys**
2. Click **Revoke**
3. The key is deleted permanently

### Best practices

* Use one key per integration
* Rotate keys regularly
* Never commit secrets

### See also

Use [Triggering explorations from any CI](/integrations/triggering-explorations-from-any-ci.md) for a complete Platform API walkthrough.
