Skip to content

API reference

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.

Base URL
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
Try it

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.

A key that starts with kp_live_. It stays on this page until you leave it and is sent only to api.komplai.dk.

Parameters

Query parameters

  • processing string

    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.

    Pattern
    ^(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})$

Responses

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.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • object string required
    One of
    list
  • data object[] required
    Child fields (14)
    • id string required

      The value for model in POST /v1/chat/completions.

    • object string required
      One of
      model
    • owned_by string required

      komplai for komplai's processing; for one of the organisation's own connections, the provider it uses, such as openrouter.

    • name string required

      The name people see, or the connection's name.

    • context_tokens integer

      The model's context in tokens: input and output together. Missing for a connection.

    • max_output_tokens integer

      The most max_tokens the model takes, at most 32,768. Missing for a connection.

    • reasoning_efforts string[]

      The reasoning_effort values the model accepts. none means it does not reason. Missing for a connection.

      Each item is one of
      none low medium high xhigh max
    • rates object

      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.

      Child fields (5)
      • currency string required
        One of
        DKK
      • unit string required

        Each rate is in millionths of a krone per million tokens, so 1000000 is one krone per million tokens.

        One of
        micro_dkk_per_million_tokens
      • input integer required

        Per million input tokens.

        Value
        at least 0
      • output integer required

        Per million output tokens. Reasoning counts as output.

        Value
        at least 0
      • cached_input integer required

        Per million cached input tokens; the input rate where the provider has no cached rate.

        Value
        at least 0
    • processing string

      Only for a connection: the value to send as processing.

400 Bad Request

The request was refused before processing.

Error codes

  • invalid_input The request is not what the operation documents, for example invalid JSON, a field that is not listed or a value out of range.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Error codes

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The 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_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Error codes

  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • insufficient_scope The 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_retired The person behind a personal key has been removed from komplai.
  • processing_not_enabled The 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_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Error codes

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Error codes

  • rate_limited Too 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.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer required

    Seconds to wait before trying again (at most 60).

    Value
    1 to 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Error codes

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
RequestGET /v1/models
curl
curl https://api.komplai.dk/v1/models \
  -H "Authorization: Bearer $KOMPLAI_TOKEN"
PowerShell
$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 100
Python
import 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())
JavaScript
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());
C#
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());

Set the environment variable KOMPLAI_TOKEN to your key first.

Response
200 OK
{
  "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"]
    }
  ]
}
200 OK
{
  "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
      }
    }
  ]
}
200 OK
{
  "object": "list",
  "data": [
    {
      "id": "openrouter/free",
      "object": "model",
      "owned_by": "openrouter",
      "name": "OpenRouter, gratis modeller",
      "processing": "connection:6d3f9a2e-1b4c-4e7d-8a5f-0c2b9e4d7a31"
    }
  ]
}
400 Bad Request
{
  "error": "invalid_input",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_input"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "integration_not_permitted",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/integration_not_permitted"
}
404 Not Found
{
  "error": "connection_not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/connection_not_found"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "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
Try it

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.

A key that starts with kp_live_. It stays on this page until you leave it and is sent only to api.komplai.dk.

Request body

  • messages object[] required

    The conversation, oldest first: at most 32 messages and 80,000 UTF-16 code units of content together.

    Items
    1 to 32
    Child fields (2)
    • role string required
      One of
      system user assistant
    • content string required

      Text only, with at least one character that is not white space. Images, files and tool results are refused.

      Pattern
      \S
      Length
      1 to 80,000
  • model string

    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.

    Pattern
    \S
    Length
    1 to 200
  • processing string

    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.

    Pattern
    ^(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})$
  • max_tokens integer

    The most tokens the answer may have. The model's own max_output_tokens (GET /v1/models) is lower for most models, and the input and max_tokens together must fit its context; otherwise 413 context_limit.

    Default
    2000
    Value
    1 to 32,768
  • temperature number

    Sampling temperature. Leave it out for the model's default. A connection to Anthropic takes at most 1.

    Value
    0 to 2
  • stream boolean

    Always false: the whole answer is returned at once.

    One of
    false
    Default
    false
  • response_format object

    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.

    One of

    • Text or JSON objectobject
      • type string required
        One of
        text json_object
    • JSON schemaobject
      • type string required
        One of
        json_schema
      • json_schema object required
        Child fields (4)
        • name string required
          Pattern
          ^[A-Za-z0-9_-]{1,64}$
        • schema object required

          A JSON Schema for the answer: at most 32,768 bytes for the whole response_format, 24 levels deep and 2,048 values. A $ref must point inside the schema (start with #).

          Can hold fields that are not listed here.

        • strict boolean

          Ask the model to follow the schema exactly.

        • description string
          Length
          at most 1,024
  • reasoning_effort string

    How much the model reasons before it answers, from the model's reasoning_efforts in GET /v1/models. Leave it out for the model's default. A value the model does not take answers 409 reasoning_not_enabled; a connection takes only none.

    One of
    none low medium high xhigh max

Responses

200 OK

The whole answer, as an OpenAI-compatible chat.completion. Nothing is stored but the call's metadata (who, when, model, tokens).

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • id string required

    chatcmpl- followed by the id komplai records the call under.

  • object string required
    One of
    chat.completion
  • created integer required

    When the answer was ready, in seconds since 1970 (UTC).

  • model string required

    The model that answered. For a connection to a router, the model the router chose; requested_model is the connection's own.

  • requested_model string

    Only for a connection: the model or router it names.

  • processing string

    Only for a connection: connection:<id>.

  • choices object[] required
    Items
    1 to 1
    Child fields (5)
    • index integer required
      One of
      0
    • message object required
      Child fields (2)
      • role string required
        One of
        assistant
      • content string required

        The answer, never empty.

    • finish_reason string required

      length: the answer reached max_tokens and is cut off.

      One of
      stop length
  • usage object required
    Child fields (4)
    • prompt_tokens integer required nullable

      Input tokens, as the model reported them; null when it did not.

    • completion_tokens integer required nullable

      Output tokens, reasoning included; null when the model did not report them.

    • prompt_tokens_details object

      Only when the model reports cached input.

      Child fields (1)
      • cached_tokens integer required
        Value
        at least 0
400 Bad Request

The request was refused before processing.

Error codes

  • invalid_input The request is not what the operation documents, for example invalid JSON, a field that is not listed or a value out of range.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Error codes

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The 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_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Error codes

  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • insufficient_scope The 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_retired The person behind a personal key has been removed from komplai.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • processing_not_enabled The 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_approved The organisation's processing approval for the app is missing or was withdrawn.
  • processing_choice_not_allowed The 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_granted No monthly AI spending cap is set up for this month, so eu-cloud cannot run.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Error codes

  • connection_not_found No connection with this id is available to you through the API.
  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Error codes

  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.
  • reasoning_not_enabled The model does not take this reasoning_effort, or one of the organisation's own connections was sent one other than none.
  • connection_model_unavailable The provider behind the connection does not know the model the connection names.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Error codes

  • context_limit The 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 Large Fastify's reason phrase: the body is over the operation's byte limit.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
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.

Error codes

  • Unsupported Media Type Fastify's reason phrase: the body has no Content-Type, or one the API does not read, such as XML or form data.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Error codes

  • rate_limited Too 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_exhausted The 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_exhausted Your personal AI limit is reached (personal keys only).
  • connection_rate_limited The provider behind the connection refused the call for now.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer

    Seconds to wait before trying again (at most 60). Sent with rate_limited and with a provider's own limit; ai_credit_exhausted and person_ai_credit_exhausted carry none, because waiting does not lift a spending limit.

    Value
    1 to 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

502 Bad Gateway

A processing service failed. No partial result is returned.

Error codes

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
503 Service Unavailable

Processing is not available right now.

Error codes

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
504 Gateway Timeout

The call timed out.

Error codes

  • timeout The model did not answer in time. The call reached the model, so its outcome is unknown.

Headers

  • Request-Id string required

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
RequestPOST /v1/chat/completions
curl
curl 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
  }'
PowerShell
$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 100
Python
import 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())
JavaScript
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());
C#
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());

Set the environment variable KOMPLAI_TOKEN to your key first.

Response
200 OK
{
  "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
  }
}
200 OK
{
  "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
  }
}
200 OK
{
  "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
  }
}
200 OK
{
  "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
  }
}
400 Bad Request
{
  "error": "invalid_input",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_input"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "integration_not_permitted",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/integration_not_permitted"
}
404 Not Found
{
  "error": "connection_not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/connection_not_found"
}
409 Conflict
{
  "error": "model_not_enabled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/model_not_enabled"
}
413 Content Too Large
{
  "error": "context_limit",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/context_limit"
}
415 Unsupported Media Type
{
  "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"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
502 Bad Gateway
{
  "error": "service_unavailable",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/service_unavailable"
}
503 Service Unavailable
{
  "error": "service_unavailable",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/service_unavailable"
}
504 Gateway Timeout
{
  "error": "timeout",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/timeout"
}
komplaidevelopers
Contact us

Search the documentation

Use the arrow keys to choose and Enter to open.