# Your own AI connections

> Add your organisation's own AI infrastructure or provider account in the hub, choose whether Chat and the API may use it, and call it with processing connection:<id>.

Your organisation can run Chat on its own AI: its own infrastructure, such as Azure OpenAI, its own hardware or another OpenAI-compatible endpoint, or its own account with a provider such as Anthropic, OpenAI, Mistral AI or OpenRouter. An administrator adds each connection in the hub and decides whether people can pick it in Chat and whether it can be used through the API.

The agreement with the provider is your organisation's own. The provider is not a komplai subprocessor, your organisation pays it directly, and the usage does not count towards the monthly AI spending cap. Decide, Redact's detection, Index and search in Documents always use komplai's validated models, so connections do not apply to them.

## Add a connection

You need to be an administrator of the organisation. The page is there when your organisation has Chat or Documents.

1. [Sign in](https://hub.komplai.dk/login) and open **Organisation › AI and processing › Connections** (`/settings/ai`). The page is called **AI connections**.
2. Under **Your connections**, open **Add a connection**.
3. Choose the **Type**. **Your account with a provider** takes a **Provider**: Anthropic, OpenAI, Mistral AI, OpenRouter, or **Another provider (OpenAI-compatible)**. **Your own infrastructure** is an OpenAI-compatible endpoint, for example Azure OpenAI or your own hardware.
4. Enter a **Name**. People see it in Chat, for example *Azure Sweden*.
5. For your own infrastructure or another provider, enter the **API address**, **Where is data processed?** and **Does data stay in the EU/EEA?** (*Yes*, *No* or *Don't know*). For another provider, also enter the **Provider's name**. The address must use https and be reachable from the internet.
6. Enter the **Model** as the provider writes it. On Azure, it is the deployment's name. On OpenRouter, `openrouter/free` picks among OpenRouter's free models, or you can name one model.
7. Paste the **API key**. It is stored encrypted, and afterwards only its last four characters are shown.
8. Choose **Can be chosen in Chat** and **Can be used through the API**. A new connection starts with Chat ticked and the API not ticked.
9. Select **Add connection**. The page checks the connection straight away, without sending a message, and says whether the provider accepted the key and lists the model.

## What people see about a connection

Every connection states where it processes data, who runs it and whether data leaves the EU/EEA, on the page and next to the choice in Chat:

| Provider | Processed in | Data leaves the EU/EEA |
| --- | --- | --- |
| Anthropic | The United States | Yes |
| OpenAI | The United States | Yes |
| Mistral AI | France | No |
| OpenRouter | The United States; OpenRouter forwards each request to the model's provider, which may be in another country | Yes |
| Your own infrastructure or another provider | Where your administrator states | As your administrator states |

For your own infrastructure and another provider, these are your administrator's statements, and the hub shows them as yours.

- **Free models.** OpenRouter's models that end in `:free`, and the `openrouter/free` router, carry a notice next to the choice: the provider may store and use what is sent. Use them for testing, synthetic data and ideas.
- **Routers.** A router such as `openrouter/free` picks a model for each request. The model that answered is shown in Chat and in the usage log, and the API returns it in `model`.

## Check, change or delete a connection

- **Check the connection** tests the key and the model without sending a message. A connection that does not answer within 15 seconds is reported as not answering.
- **Edit** changes any field. Leave **API key** empty to keep the key; if you change provider, enter a new key.
- **Delete connection** deletes the key too, and the connection can no longer be chosen in Chat or used through the API. A connection that drafting uses cannot be deleted until you choose other processing for drafting.

The same page has **Drafting in Documents, templates and Word**: where text is sent when someone asks for a draft or a suggestion. Choose **Local infrastructure** or one of your connections and select **Save choice**.

## How keys and addresses are protected

- An administrator types the key once. It is stored encrypted and never sent back to a browser. komplai's staff never receive or handle it.
- komplai's operators see your connections read-only, with the host of your own address, but never the key, its last characters or the full address.
- The address is checked when it is saved and again before every call. It must use https, may not point to an internal or private network address and may not redirect.
- Creating, changing and deleting a connection, and changing the drafting choice, are written to the organisation's **Audit log**, without the key.
- Only the organisation's administrators can open the page. komplai's read-only support access cannot.

## Use a connection through the API

A call can run on a connection when:

- it uses a personal API key (`kp_live_...`) with `chat:complete`. An organisation integration key (`kp_org_...`) is refused with [integration_not_permitted](https://developers.komplai.dk/errors/integration_not_permitted);
- the person behind the key has access to Chat, and your organisation's Chat processing is approved;
- the connection has **Can be used through the API** ticked. The connection then shows **Value for processing in the API**, such as `connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31`.

The choices under **AI and processing › Processing** cover komplai's own processing; a connection follows its own two switches.

1. Copy the connection's value from the Connections page.
2. List its model with GET /v1/models. The list has one entry: the model or router the connection names.

   ```bash
   curl "https://api.komplai.dk/v1/models?processing=connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31" \
     -H "Authorization: Bearer $KOMPLAI_TOKEN"
   ```

   ```json
   {
     "object": "list",
     "data": [
       {
         "id": "openrouter/free",
         "object": "model",
         "owned_by": "openrouter",
         "name": "OpenRouter, gratis modeller",
         "processing": "connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31"
       }
     ]
   }
   ```

3. Send POST /v1/chat/completions with the value in `processing`. Leave `model` out, or send the model the connection names.

   ```bash
   curl https://api.komplai.dk/v1/chat/completions \
     -H "Authorization: Bearer $KOMPLAI_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"processing": "connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31", "messages": [{"role": "user", "content": "Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?"}], "max_tokens": 256}'
   ```

4. Read the answer. `model` is the model that answered, which a router chooses per request; `requested_model` is the model or router the connection names, and `processing` repeats the connection.

   ```json
   {
     "object": "chat.completion",
     "model": "meta-llama/llama-3.3-70b-instruct:free",
     "requested_model": "openrouter/free",
     "processing": "connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31",
     "choices": [
       {
         "index": 0,
         "message": {
           "role": "assistant",
           "content": "Du har normalt 4 uger til at klage, regnet fra den dag du fik afgørelsen. Fristen står i afgørelsens klagevejledning."
         },
         "finish_reason": "stop"
       }
     ]
   }
   ```

A call on a connection follows the same rules as other Chat calls: text only, the whole answer at once, at most 32 messages and 80,000 UTF-16 code units, and 120 seconds for the model to answer. komplai stores the call's metadata and the model that answered, not the messages. In addition:

- `reasoning_effort` can only be `none`; any other value is refused with [reasoning_not_enabled](https://developers.komplai.dk/errors/reasoning_not_enabled).
- A connection to Anthropic takes a `temperature` of at most 1, only text as `response_format`, and at least one message that is not a system message. Anything else is refused with [invalid_input](https://developers.komplai.dk/errors/invalid_input).
- A `model` other than the connection's own is refused with [model_not_enabled](https://developers.komplai.dk/errors/model_not_enabled).

The API never moves a call from a connection to komplai's processing or to another connection, also not when the connection fails. The [Chat reference](https://developers.komplai.dk/reference/chat#createChatCompletion) has every field. A call on a connection can also stop with these errors:

| Code | Status | What happened |
| --- | --- | --- |
| [connection_not_found](https://developers.komplai.dk/errors/connection_not_found) | 404 | No connection with this id is available to you through the API. |
| [processing_choice_not_allowed](https://developers.komplai.dk/errors/processing_choice_not_allowed) | 403 | The connection is not made available through the API. |
| [connection_model_unavailable](https://developers.komplai.dk/errors/connection_model_unavailable) | 409 | The provider does not know the model the connection names. |
| [connection_rate_limited](https://developers.komplai.dk/errors/connection_rate_limited) | 429 | The provider refused the call for now. Wait the seconds in `Retry-After`. |
| [connection_unauthorized](https://developers.komplai.dk/errors/connection_unauthorized) | 502 | The provider refused the connection's key. |
| [connection_payment_required](https://developers.komplai.dk/errors/connection_payment_required) | 502 | The provider wants payment on your organisation's account. |
| [connection_request_refused](https://developers.komplai.dk/errors/connection_request_refused) | 502 | The provider refused the request, for example a value it does not take. |
| [connection_failed](https://developers.komplai.dk/errors/connection_failed) | 502 | The provider could not be reached or failed. |
| [connection_unavailable](https://developers.komplai.dk/errors/connection_unavailable) | 503 | The connection's key cannot be read, or its address is refused. |
| [timeout](https://developers.komplai.dk/errors/timeout) | 504 | The model did not answer within 120 seconds. |

---

https://developers.komplai.dk/guides/ai-connections
