# API reference

> Base URLs, versions, the OpenAPI document, JSON conventions, request ids and retries, and every endpoint of komplai's API with a console to try it.

komplai's API takes JSON and answers with JSON over HTTPS. Every call sends your key in the `Authorization` header:

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

GET /v1/access shows what your key can reach, where each Redact layer processes text and which limits apply. [API keys and authentication](https://developers.komplai.dk/authentication) explains the two kinds of key.

## Endpoints

Each endpoint lists the scopes and keys it needs, its fields and its responses, with code samples in curl, PowerShell, Python, JavaScript and C#. The samples read your key from the environment variable `KOMPLAI_TOKEN`. Signed in to the hub, **APIs and integrations › API reference** shows the operations your own access covers.

## Base URLs

| Environment | API | Keys from |
| --- | --- | --- |
| Production | `https://api.komplai.dk` | `https://hub.komplai.dk` |
| Test | `https://api.test.komplai.dk` | `https://hub.test.komplai.dk` |

Create the key in the hub of the environment you call. Each environment serves the OpenAPI document for the version it runs at `/v1/openapi.json`.

## Versions and stability

Every path starts with `/v1`. The OpenAPI document's `info.version` is the version of the contract, 1.3.0 in the document this reference is built from. The [changelog](https://developers.komplai.dk/changelog) lists what each version changed.

Each operation has `x-komplai-stability`:

- `stable` keeps its contract.
- `beta` may still change, and komplai gives notice before it does. Decide, Coding and Redact's PDF and Word input are in beta.
- `alpha` is early and may change without notice.

A request field marked `preview` is an early option inside an operation and may change without notice: Redact's `engine` and `sources`. Leave them out unless your organisation's administrator has turned on the Redact Agentic preview.

## The OpenAPI document

[/openapi.json](https://developers.komplai.dk/openapi.json) on this site is OpenAPI 3.1, a copy of the document the production API serves at `https://api.komplai.dk/v1/openapi.json`. This reference is built from it. GET /v1/openapi.json needs no key and ignores any `Authorization` header, so a tool that always sends a key still gets it.

Besides standard OpenAPI, the document has:

| Extension | Contents |
| --- | --- |
| `x-komplai-scopes` | The scopes an operation needs. |
| `x-komplai-principals` | The kinds of key an operation accepts: `person` for a personal API key, `integration` for an organisation integration key. |
| `x-komplai-stability` | `stable`, `beta` or `alpha` on each operation and tag, `preview` on a request field. |
| `x-komplai-error-codes` | At the root: every error code with its statuses, its meaning, what to do, its page and the operations that return it. |

### Import into Postman

- [OpenAPI document](https://developers.komplai.dk/openapi.json): OpenAPI 3.1.
- [Postman collection](https://developers.komplai.dk/downloads/komplai-api.postman_collection.json): every endpoint, with example bodies, grouped like this reference, with bearer authentication from the variable `token`.
- [Postman environment](https://developers.komplai.dk/downloads/komplai-api.postman_environment.json): the variables `baseUrl` (`https://api.komplai.dk`) and `token`, a secret that starts empty.

1. In Postman, import the collection and the environment and select the environment. For another tool, use the OpenAPI document.
2. Put your key in `token`. For the test environment, set `baseUrl` to `https://api.test.komplai.dk`.
3. Send GET /v1/access to check that the key works.

Optional headers, such as `Idempotency-Key` and `Prefer`, are in the requests that take them but switched off. `Idempotency-Key` holds Postman's `{{$guid}}`, a new UUID on each send. In other tools, generate a UUID for each job or leave the header out.

## Requests and answers

- Send a body as JSON with `Content-Type: application/json`. Another content type answers 400 or 415.
- Redact, Chat and Coding refuse a field they do not document, with 400 [`invalid_body`](https://developers.komplai.dk/errors/invalid_body), [`invalid_input`](https://developers.komplai.dk/errors/invalid_input) or [`invalid_coding_input`](https://developers.komplai.dk/errors/invalid_coding_input). Decide ignores fields it does not list.
- Chat and Coding use OpenAI's chat completion format.
- Text lengths and offsets count UTF-16 code units, as string length does in JavaScript and .NET. In Python, `len(text.encode("utf-16-le")) // 2` gives the same count.
- Ids such as a text job's `id` and `organisation_id` are UUIDs; a Chat answer's `id` starts with `chatcmpl-`. Times such as `createdAt` and `expiresAt` are ISO 8601 in UTC. `created` in Chat and Coding answers is seconds since 1970 (UTC).
- A call that succeeds answers 200, or 202 when it has created a text job or when you ask for the result of a job that is still queued or running.
- Answers to calls with a key carry `Cache-Control: private, no-store`.
- A call that fails answers with a status and an error body. See [Errors](https://developers.komplai.dk/errors).

## Request-Id

Every response to a call the API handles carries a `Request-Id` header with a UUID, and an error body repeats it as `request_id`. Log it with each call and quote it when you ask komplai about one.

To have your own id used, send it in `X-Request-Id`. It must be one valid UUID; on other values the API makes a new one. The exception is POST /v1/coding/chat/completions, which requires `X-Request-Id` and answers 400 [`invalid_request_id`](https://developers.komplai.dk/errors/invalid_request_id) without it: a new version 4 UUID for each operation, and the same one again only to retry an operation whose outcome you do not know. komplai then answers 409 [`duplicate_request`](https://developers.komplai.dk/errors/duplicate_request) instead of calling the model a second time.

A response without `Request-Id` was answered before the API handled the call, for example by the gateway while the API restarts. Treat it by its status.

## Retries and idempotency

Whether you can send a call again depends on whether it may already have reached a model.

- **Text jobs.** Send `Idempotency-Key` with a new UUID for each job on POST /v1/redact/jobs and POST /v1/redact/file/jobs, and on POST /v1/redact and POST /v1/redact/file with `Prefer: respond-async`. If the connection drops, send the same request with the same `Idempotency-Key`: within the job's lifetime you get the same job back, with `reused` `true`, instead of a second job. The same `Idempotency-Key` with another body answers 409 [`idempotency_conflict`](https://developers.komplai.dk/errors/idempotency_conflict). An `Idempotency-Key` is bound to your organisation, the owner of the API key (a person or an integration) and the API key itself.
- **Coding.** `X-Request-Id`, as above.
- **Chat and synchronous Redact** have no idempotency. A call that timed out or lost its connection may already have reached the model, and calls in EU cloud count towards the monthly AI spending cap. Do not send them again automatically, and switch off automatic retries of POST in your HTTP client or SDK.
- **Calls without AI charge that change nothing,** such as GET operations, POST /v1/redact/detect and POST /v1/redact/restore, can be sent again. Each one counts against your request limit.
- **After 429,** wait the seconds in `Retry-After`. [Errors](https://developers.komplai.dk/errors) says when trying again helps.

Poll a text job at most every 2 seconds. While the job is queued or running, GET /v1/redact/jobs/{id}/result answers 202 with `Retry-After: 2`.

## Calling from a browser

The API accepts browser calls only from komplai's own sites, including the consoles on this site. Call it from a server, a script or an integration platform: a key in a web page is visible to everyone who opens it.

## Try a call

Each endpoint has a console that sends the call from your browser to the API with a key you paste. The key stays in the page's memory and is forgotten when you leave the page; the console never stores it in the browser. On developers.test.komplai.dk, the console calls the test environment.

Calls are real: komplai processes what you send, each call counts towards your key's limits, and processing in EU cloud counts towards your organisation's monthly AI spending cap. Use test data.

---

https://developers.komplai.dk/api
