Chat-API
Chat completions and model discovery on the organisation's approved processing. Needs a personal key with chat:complete; an organisation integration key gets 403 integration_not_permitted.
- Basisadresse
https://api.komplai.dk
List the permitted chat models
GET /v1/models
The models this key may use for POST /v1/chat/completions, with their context and output limits, the reasoning efforts they take and, in komplai's EU cloud, the provider's token rates. processing chooses which processing to list: komplai's local infrastructure, komplai's EU cloud or one of your organisation's own connections. It sends no text and runs no model. Needs a personal key with chat:complete.
- Scopes
chat:complete- Nøgler
- Personlig nøgle
Prøv kaldet
Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.
En nøgle, der starter med kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.
Svar
Request-Id
Forespørgselsparametre
Which processing to list. komplai-local: komplai's local infrastructure in Denmark, with no AI charge (local is accepted too). eu-cloud: komplai's EU cloud, when your organisation has EU processing approved for Chat; usage is metered at the provider's price and counts towards the organisation's monthly AI spending cap. connection:<id>: one of your organisation's own connections that its administrator has made available through the API, shown with its value on the hub's AI processing page; the organisation pays the provider itself, and the usage does not count towards the cap. Leave it out to list your organisation's Chat processing: local infrastructure, or EU cloud when that is what your organisation's Chat uses.
- Mønster
^(komplai-local|local|eu-cloud|connection:[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})$
Svar
200 OK
The models this key may use at that processing. On local infrastructure: the models your organisation has switched on, or every selectable model while it has switched on none. In EU cloud: the models on your organisation's EU route, with their rates. For a connection: the one model or router it names. The list grants no access of its own.
Headere
Body
Underfelter (14)
Only for komplai's EU cloud: the provider's prices, which usage is metered at and counted towards the organisation's monthly AI spending cap. Local infrastructure has no AI charge and no rates.
Underfelter (5)
400 Bad Request
The request was refused before processing.
Fejlkoder
invalid_inputThe request is not what the operation documents, for example invalid JSON, a field that is not listed or a value out of range.
Headere
401 Unauthorized
The key is missing or not valid.
Fejlkoder
api_key_requiredNo Authorization: Bearer header with a komplai key.invalid_api_keyThe key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.invalid_tokenThe key was revoked or expired, or its access ended, while the request was admitted or processed.
Headere
403 Forbidden
The key may not do this, or the organisation's access does not cover it.
Fejlkoder
integration_not_permittedAn organisation integration key cannot use this operation or this option.insufficient_scopeThe key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.identity_retiredThe person behind a personal key has been removed from komplai.processing_not_enabledThe processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.processing_choice_not_allowedThe organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
Headere
404 Not Found
Not found.
Fejlkoder
connection_not_foundNo connection with this id is available to you through the API.
Headere
429 Too Many Requests
Refused for now. Wait the seconds in Retry-After before you try again.
Fejlkoder
rate_limitedToo many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.
Headere
503 Service Unavailable
Processing is not available right now.
Fejlkoder
chat_cloud_unavailableThe organisation's EU cloud setup cannot be used right now.access_service_unavailableKeys and access could not be checked.
Headere
/v1/modelscurl https://api.komplai.dk/v1/models \
-H "Authorization: Bearer $KOMPLAI_TOKEN"$headers = @{
Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$request = @{
Method = 'Get'
Uri = 'https://api.komplai.dk/v1/models'
Headers = $headers
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100import os
import requests
response = requests.get(
"https://api.komplai.dk/v1/models",
headers={
"Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
},
timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())const response = await fetch("https://api.komplai.dk/v1/models", {
headers: {
Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
},
});
console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());using System;
using System.Net.Http;
using System.Net.Http.Headers;
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.komplai.dk/v1/models");
request.Headers.Authorization = new AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.
{
"object": "list",
"data": [
{
"id": "qwen3.8-27b",
"object": "model",
"owned_by": "komplai",
"name": "Qwen3.8 27B",
"context_tokens": 32768,
"max_output_tokens": 4000,
"reasoning_efforts": ["none", "low", "medium", "high"]
},
{
"id": "qwen3.8-27b-q8",
"object": "model",
"owned_by": "komplai",
"name": "Qwen3.8 27B (Q8)",
"context_tokens": 32768,
"max_output_tokens": 4000,
"reasoning_efforts": ["none", "low", "medium", "high"]
}
]
}{
"object": "list",
"data": [
{
"id": "mistral-small-3.2-24b-instruct-2506",
"object": "model",
"owned_by": "komplai",
"name": "Mistral Small 3.2 (24B)",
"context_tokens": 128000,
"max_output_tokens": 32768,
"reasoning_efforts": ["none"],
"rates": {
"currency": "DKK",
"unit": "micro_dkk_per_million_tokens",
"input": 1119000,
"output": 2611000,
"cached_input": 1119000
}
},
{
"id": "qwen3.5-397b-a17b",
"object": "model",
"owned_by": "komplai",
"name": "Qwen3.5 (397B-A17B)",
"context_tokens": 250000,
"max_output_tokens": 16384,
"reasoning_efforts": ["none", "low", "medium", "high"],
"rates": {
"currency": "DKK",
"unit": "micro_dkk_per_million_tokens",
"input": 4476000,
"output": 26856000,
"cached_input": 4476000
}
}
]
}{
"object": "list",
"data": [
{
"id": "openrouter/free",
"object": "model",
"owned_by": "openrouter",
"name": "OpenRouter, gratis modeller",
"processing": "connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31"
}
]
}{
"error": "invalid_input",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/invalid_input"
}{
"error": "api_key_required",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/api_key_required"
}{
"error": "integration_not_permitted",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/integration_not_permitted"
}{
"error": "connection_not_found",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/connection_not_found"
}{
"error": "rate_limited",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/rate_limited"
}{
"error": "chat_cloud_unavailable",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/chat_cloud_unavailable"
}Create a chat completion
POST /v1/chat/completions
An OpenAI-compatible chat completion with text only, returned whole (stream false). It runs where processing says: komplai's local infrastructure in Denmark, komplai's EU cloud when your organisation has it approved for Chat, or one of your organisation's own connections; without processing, where your organisation's Chat runs. The API never moves a call to other processing or another model, also not when the chosen one fails. At most 32 messages and 80,000 UTF-16 code units of text; the model has 120 seconds to answer. In EU cloud, usage is metered at the provider's price and counts towards the organisation's monthly AI spending cap; the call stops when the cap, the organisation's own limit or your personal limit is reached. Needs a personal key with chat:complete.
- Scopes
chat:complete- Nøgler
- Personlig nøgle
Prøv kaldet
Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.
En nøgle, der starter med kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.
Svar
Request-Id
Body i kaldet
The conversation, oldest first: at most 32 messages and 80,000 UTF-16 code units of content together.
- Elementer
- 1 til 32
A model id from GET /v1/models at the same processing, with at least one character that is not white space. Leave it out for the default there: the model you chose in the hub, else your organisation's default. A model you may not use answers 409 model_not_enabled; the API never picks another one. For a connection, leave it out or send the model the connection names.
- Mønster
\S- Længde
- 1 til 200
Where the model runs. komplai-local: komplai's local infrastructure in Denmark, with no AI charge (local is accepted too). eu-cloud: komplai's EU cloud, when your organisation has EU processing approved for Chat; usage is metered at the provider's price and counts towards the organisation's monthly AI spending cap. connection:<id>: one of your organisation's own connections that its administrator has made available through the API, shown with its value on the hub's AI processing page; the organisation pays the provider itself, and the usage does not count towards the cap. Leave it out for your organisation's Chat processing. The API never moves a call to other processing, also not when the chosen one fails.
- Mønster
^(komplai-local|local|eu-cloud|connection:[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})$
Leave it out for plain text. json_object asks for a JSON object; json_schema asks for JSON that follows your schema. A connection to Anthropic takes only text.
En af
JSON schemaobject
Underfelter (4)
Svar
200 OK
The whole answer, as an OpenAI-compatible chat.completion. Nothing is stored but the call's metadata (who, when, model, tokens).
Headere
Body
- Elementer
- 1 til 1
Underfelter (4)
400 Bad Request
The request was refused before processing.
Fejlkoder
invalid_inputThe request is not what the operation documents, for example invalid JSON, a field that is not listed or a value out of range.
Headere
401 Unauthorized
The key is missing or not valid.
Fejlkoder
api_key_requiredNo Authorization: Bearer header with a komplai key.invalid_api_keyThe key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.invalid_tokenThe key was revoked or expired, or its access ended, while the request was admitted or processed.
Headere
403 Forbidden
The key may not do this, or the organisation's access does not cover it.
Fejlkoder
integration_not_permittedAn organisation integration key cannot use this operation or this option.insufficient_scopeThe key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.identity_retiredThe person behind a personal key has been removed from komplai.app_not_assignedThe key's person lost the app or their membership while the request was admitted.processing_not_enabledThe processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.processing_not_approvedThe organisation's processing approval for the app is missing or was withdrawn.processing_choice_not_allowedThe organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.ai_credit_not_grantedNo monthly AI spending cap is set up for this month, so eu-cloud cannot run.
Headere
404 Not Found
Not found.
Fejlkoder
connection_not_foundNo connection with this id is available to you through the API.model_not_enabledThe model is not one you may use at this processing, or it is not offered there right now.
Headere
409 Conflict
Conflict with the current state.
Fejlkoder
model_not_enabledThe model is not one you may use at this processing, or it is not offered there right now.reasoning_not_enabledThe model does not take this reasoning_effort, or one of the organisation's own connections was sent one other than none.connection_model_unavailableThe provider behind the connection does not know the model the connection names.
Headere
413 Content Too Large
Too large.
Fejlkoder
context_limitThe input and the requested output do not fit the model: max_tokens is over the model's limit, the input with max_tokens is over its context, or, in Redact, a part of the text does not fit even after it was asked again in halves down to 1,500 characters.Payload Too LargeFastify's reason phrase: the body is over the operation's byte limit.
Headere
415 Unsupported Media Type
The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.
Fejlkoder
Unsupported Media TypeFastify's reason phrase: the body has no Content-Type, or one the API does not read, such as XML or form data.
Headere
429 Too Many Requests
Refused for now. Wait the seconds in Retry-After before you try again.
Fejlkoder
rate_limitedToo many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.ai_credit_exhaustedThe organisation's monthly AI spending cap for EU cloud is reached, or its own lower limit, or on a pilot the pilot's total allowance. Local processing keeps working.person_ai_credit_exhaustedYour personal AI limit is reached (personal keys only).connection_rate_limitedThe provider behind the connection refused the call for now.
Headere
502 Bad Gateway
A processing service failed. No partial result is returned.
Fejlkoder
service_unavailableThe model failed or could not be reached, or local infrastructure is not set up for this call right now.invalid_responseThe model's answer failed validation, so nothing was returned.eu_cloud_refusedkomplai's EU cloud refused the call, so the model did not answer it.connection_unauthorizedThe provider refused the connection's key.connection_payment_requiredThe provider behind the connection wants payment on the organisation's account.connection_request_refusedThe provider behind the connection refused the request, for example a value it does not take.connection_failedThe provider behind one of the organisation's own connections could not be reached or failed.
Headere
503 Service Unavailable
Processing is not available right now.
Fejlkoder
service_unavailableThe model failed or could not be reached, or local infrastructure is not set up for this call right now.chat_cloud_unavailableThe organisation's EU cloud setup cannot be used right now.connection_unavailableThe connection cannot be used: its key cannot be read or its address is refused.access_service_unavailableKeys and access could not be checked.
Headere
504 Gateway Timeout
The call timed out.
Fejlkoder
timeoutThe model did not answer in time. The call reached the model, so its outcome is unknown.
Headere
/v1/chat/completionscurl https://api.komplai.dk/v1/chat/completions \
-H "Authorization: Bearer $KOMPLAI_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"messages": [
{
"role": "system",
"content": "Svar kort og på dansk."
},
{
"role": "user",
"content": "Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?"
}
],
"max_tokens": 256
}'$headers = @{
Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
messages = @(
[ordered]@{
role = 'system'
content = 'Svar kort og på dansk.'
},
[ordered]@{
role = 'user'
content = 'Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?'
}
)
max_tokens = 256
} | ConvertTo-Json -Depth 100
$request = @{
Method = 'Post'
Uri = 'https://api.komplai.dk/v1/chat/completions'
Headers = $headers
ContentType = 'application/json; charset=utf-8'
Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100import os
import requests
response = requests.post(
"https://api.komplai.dk/v1/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
},
json={
"messages": [
{
"role": "system",
"content": "Svar kort og på dansk.",
},
{
"role": "user",
"content": "Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?",
},
],
"max_tokens": 256,
},
timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())const response = await fetch("https://api.komplai.dk/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
messages: [
{
role: "system",
content: "Svar kort og på dansk.",
},
{
role: "user",
content: "Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?",
},
],
max_tokens: 256,
}),
});
console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/chat/completions");
request.Headers.Authorization = new AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
""messages"": [
{
""role"": ""system"",
""content"": ""Svar kort og på dansk.""
},
{
""role"": ""user"",
""content"": ""Hvor lang tid har jeg til at klage over en afgørelse om boligstøtte?""
}
],
""max_tokens"": 256
}", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.
{
"id": "chatcmpl-8c1d5e3a-2f7b-4a9c-b6e0-3d4f5a6b7c8d",
"object": "chat.completion",
"created": 1792483200,
"model": "qwen3.8-27b",
"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"
}
],
"usage": {
"prompt_tokens": 41,
"completion_tokens": 33
}
}{
"id": "chatcmpl-8c1d5e3a-2f7b-4a9c-b6e0-3d4f5a6b7c8d",
"object": "chat.completion",
"created": 1792483200,
"model": "qwen3.8-27b",
"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"
}
],
"usage": {
"prompt_tokens": 27,
"completion_tokens": 33
}
}{
"id": "chatcmpl-8c1d5e3a-2f7b-4a9c-b6e0-3d4f5a6b7c8d",
"object": "chat.completion",
"created": 1792483200,
"model": "qwen3.8-27b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"uger\":4,\"kilde\":\"Afgørelsens klagevejledning\"}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 64,
"completion_tokens": 15
}
}{
"id": "chatcmpl-8c1d5e3a-2f7b-4a9c-b6e0-3d4f5a6b7c8d",
"object": "chat.completion",
"created": 1792483200,
"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"
}
],
"usage": {
"prompt_tokens": 29,
"completion_tokens": 35
}
}{
"error": "invalid_input",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/invalid_input"
}{
"error": "api_key_required",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/api_key_required"
}{
"error": "integration_not_permitted",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/integration_not_permitted"
}{
"error": "connection_not_found",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/connection_not_found"
}{
"error": "model_not_enabled",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/model_not_enabled"
}{
"error": "context_limit",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/context_limit"
}{
"error": "Unsupported Media Type",
"statusCode": 415,
"code": "FST_ERR_CTP_INVALID_MEDIA_TYPE",
"message": "Unsupported Media Type",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/unsupported-media-type"
}{
"error": "rate_limited",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/rate_limited"
}{
"error": "service_unavailable",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/service_unavailable"
}{
"error": "service_unavailable",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/service_unavailable"
}{
"error": "timeout",
"request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
"doc_url": "https://developers.komplai.dk/errors/timeout"
}