# API keys and authentication

> The two kinds of komplai API key, how you get, renew and revoke them, the scopes that limit them and what GET /v1/access tells you.

Every call to an operation sends a key as a bearer token in the `Authorization` header. The only call without a key is GET /v1/openapi.json, which is public.

```bash
curl https://api.komplai.dk/v1/access \
  -H "Authorization: Bearer $KOMPLAI_TOKEN"
```

Send the whole key. The API reads it only from this header, so it never belongs in a URL. Answers to calls with a key carry `Cache-Control: private, no-store`.

## Two kinds of key

| | Personal API key | Organisation integration key |
| --- | --- | --- |
| Starts with | `kp_live_` | `kp_org_` |
| Belongs to | You, in one organisation | One of your organisation's own systems, not a person |
| Created by | You, in the hub | komplai, when your organisation asks |
| Reaches | The tools assigned to you: Redact, Chat, Decide, Coding and Register lookup, within the key's scopes | Redact and GET /v1/access only |
| Valid for | 7, 30, 90 or 365 days, as you choose | Up to 365 days, set by komplai |
| Request limit | Yours, shared with your other keys and your use of the hub | The integration's own, kept when komplai issues a new key |
| Managed under | **APIs and integrations › API keys** | **Organisation › Sign-in and security › Integration keys** |

komplai stores only a hash of each key and its first characters, so a key cannot be shown again after it was issued. Keep it in a secret store, never in code, a URL or an e-mail.

## Scopes

A scope allows a group of operations. Each operation's page in the [API reference](https://developers.komplai.dk/api) lists the scopes and the kinds of key it accepts.

| Scope | Operations | Keys |
| --- | --- | --- |
| `access:read` | GET /v1/access | Both |
| `redact:detect` | POST /v1/redact/detect | Both |
| `redact:process` | POST /v1/redact, POST /v1/redact/restore, the text job operations under /v1/redact/jobs, and POST /v1/redact/file and /v1/redact/file/jobs (Beta) | Both |
| `chat:complete` | GET /v1/models, POST /v1/chat/completions | Personal |
| `decide:process` | POST /v1/decide, POST /v1/decide/batch (Beta) | Personal |
| `coding:read` | GET /v1/coding/account, GET /v1/coding/models (Beta) | Personal |
| `coding:complete` | POST /v1/coding/chat/completions (Beta) | Personal |
| `mcp:read` | Register lookup from an MCP client (Beta) | Personal |

You can give a personal API key only scopes for tools that are assigned to you. Give it only the scopes the system needs. The API checks the scopes against your current access on every call: when your assignment or your organisation's processing approval no longer covers a tool, the call answers 403 [`insufficient_scope`](https://developers.komplai.dk/errors/insufficient_scope) or 401 [`invalid_api_key`](https://developers.komplai.dk/errors/invalid_api_key).

An organisation integration key on an operation it does not reach gets 403 [`integration_not_permitted`](https://developers.komplai.dk/errors/integration_not_permitted), before its scopes are checked.

## Personal API keys

### Create a key

[Get started](https://developers.komplai.dk/get-started) walks you through it: **APIs and integrations › API keys › Create API key**, then the purpose, a name, the validity and the permissions.

- The key belongs to you and the organisation you have selected in the hub. If you belong to several organisations, switch to the right one before you create the key.
- You can have up to 20 active keys in each organisation.
- After the hub has shown the key once, the list shows its name, the first characters of the key, its scopes, status, expiry date and when it was last used.

### Renew a key

Renewing creates a new key and revokes the old one in the same step.

1. Under **APIs and integrations › API keys**, choose **Renew** next to the key.
2. Choose the **Validity** and check the permissions.
3. Choose **Renew key** and copy the new key.

The old key stops working at once, so put the new key in your system straight away. A text job is visible only to the key that created it: read or delete its result before you renew. Only you can renew your own keys.

### Revoke a key

Choose **Revoke** next to the key and then **Revoke key**. Access with the key stops immediately. Your organisation's administrator sees the members' keys on the same page and can revoke them too.

### When a key stops working

- It reaches its expiry date, shown under **Expires**.
- You or your administrator revoke it, or you renew it.
- You leave the organisation, or no tool the key covers is assigned to you any longer.
- Your organisation's API access for the tool ends.

A call with such a key answers 401 [`invalid_api_key`](https://developers.komplai.dk/errors/invalid_api_key). If the key stops while a call is running, the call answers 401 [`invalid_token`](https://developers.komplai.dk/errors/invalid_token).

## Organisation integration keys

An organisation integration key lets one of your organisation's own systems, such as a robot or an integration platform, call Redact without a person. Calls with it are recorded under the integration's name, never under a person.

- **Getting a key.** [Contact us](https://en.komplai.dk/#kontakt) with the system's name, what it will do and a contact person at your organisation. komplai issues the key and delivers it once to the contact person through Secret. The contact person gets no access with the key and needs no account.
- **What it reaches.** GET /v1/access and Redact: detection, pseudonymisation, restore, text jobs and PDF and Word input. Chat, Decide, Coding, Register lookup and `engine` `agentic` answer 403 [`integration_not_permitted`](https://developers.komplai.dk/errors/integration_not_permitted). Redact in Word and the Coding client accept personal API keys only.
- **Requirements.** The key works while it is active, your organisation's agreement includes Redact through the API and the processing is approved. The API checks this on every call and during every text job. If one of them ends, every integration key in the organisation stops at once.
- **Usage.** Calls count towards your organisation's request limits and its monthly AI spending cap. An integration has no personal limit. Its request limit belongs to the integration, so a new key does not reset it.
- **A new key.** komplai issues the next key for the same integration. The old key stops the moment the new one is issued, with no overlap, and its queued, running and finished text jobs are invalidated. Replace keys between your system's batches.
- **Revoking.** Your organisation's administrator opens **Organisation › Sign-in and security › Integration keys**, chooses **Revoke** and then **Revoke key**. The system loses access at once, queued and running jobs stop and results can no longer be fetched. The integration stays, so komplai can issue a new key for it.

The **Integration keys** page shows each integration's name, contact person, key, status, expiry and last use. Its statuses:

| Status | Meaning |
| --- | --- |
| Active | The key works. |
| No access to Redact | The key is valid, but your organisation cannot use Redact through the API at the moment. |
| Expired | The key has passed its expiry date. komplai can issue a new key. |
| Stopped | Your organisation can no longer use Redact through the API, so the key stopped. komplai can issue a new key. |
| Revoked by your administrator, Revoked by komplai | The key was revoked. The integration still exists, so komplai can issue a new key. |
| Closed | komplai has closed the integration. It cannot get a new key. |

## What GET /v1/access returns

GET /v1/access counts as one request, sends no text and runs no model. Call it when your system starts, and before a run where the processing matters. The full example is in the [reference](https://developers.komplai.dk/reference/account#readAccess).

| Field | Contents |
| --- | --- |
| `organisation_id` | Your organisation's id. |
| `principal` | Only for an organisation integration key: `type` `integration`, `integration_id` and `name`. A personal API key's answer has no `principal`. |
| `scopes` | Every scope the key has. |
| `services[]` | One entry per tool the key reaches, with `service`, the key's `scopes` for it, `hosting`, `processing` and `limits`. |
| `services[].hosting.processing.layers` | For Redact: one entry per layer (`regex`, `ner`, `llm`) and processing choice, with where it processes text, whether it is set up, the NER places and the models a call may name. |
| `services[].processing` | What your organisation's agreement allows: `data_mode` (`synthetic` for test data only, `personal` for personal data under `agreement_reference`), `storage` with what is stored and for how long, and for Redact `text_contract` with its options and limits. |
| `services[].limits.requests_per_minute` | Calls per minute for the tool: per person for a personal API key, per integration for an organisation integration key. |
| `limits` | `organisation_requests_per_minute` and `shared_requests_per_minute`, and `requests_per_minute` when the key reaches one tool. |
| `hosting`, `processing` | A summary, when the key reaches one tool. |

`services[].edition` is deprecated and always `custom`. Read `scopes` and `processing` instead.

---

https://developers.komplai.dk/authentication
