> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akumi.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a chat completion

> OpenAI-compatible: point an existing OpenAI client at this base URL and change
nothing else. Pass a single `model`, or an ordered `models` chain to fall back
automatically when a provider is unavailable. Every request is metered and
audited.



## OpenAPI

````yaml /api-reference/openapi.json post /chat/completions
openapi: 3.1.0
info:
  title: Akumi
  version: 0.0.1
servers:
  - url: https://api.akumi.eu/v1
    description: Production
security:
  - http: []
tags:
  - name: Audit log
  - name: Chat completions
  - name: Embeddings
  - name: Models
  - name: Recall
  - name: Scores
paths:
  /chat/completions:
    post:
      tags:
        - Chat completions
      summary: Create a chat completion
      description: >-
        OpenAI-compatible: point an existing OpenAI client at this base URL and
        change

        nothing else. Pass a single `model`, or an ordered `models` chain to
        fall back

        automatically when a provider is unavailable. Every request is metered
        and

        audited.
      operationId: v1.chat.completions
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatCompletionsRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    const: chat.completion
                  created:
                    type: integer
                  model:
                    type: string
                  choices:
                    type: array
                    items:
                      type: object
                      properties:
                        index:
                          type: integer
                        message:
                          type: object
                          properties:
                            role:
                              type: string
                              const: assistant
                            content:
                              type:
                                - string
                                - 'null'
                            tool_calls:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  type:
                                    type: string
                                    const: function
                                  function:
                                    type: object
                                    properties:
                                      name:
                                        type: string
                                      arguments:
                                        type: string
                                    required:
                                      - name
                                      - arguments
                                required:
                                  - id
                                  - type
                                  - function
                          required:
                            - role
                            - content
                        finish_reason:
                          type: string
                      required:
                        - index
                        - message
                        - finish_reason
                  usage:
                    type: object
                    properties:
                      prompt_tokens:
                        type: integer
                      completion_tokens:
                        type: integer
                      total_tokens:
                        type: integer
                      credits:
                        type: object
                        properties:
                          base:
                            type: integer
                          services:
                            type: integer
                          total:
                            type: integer
                        required:
                          - base
                          - services
                          - total
                    required:
                      - prompt_tokens
                      - completion_tokens
                      - total_tokens
                      - credits
                  sources:
                    type: array
                    items:
                      type: object
                      additionalProperties: {}
                required:
                  - id
                  - object
                  - created
                  - model
                  - choices
                  - usage
                  - sources
            text/event-stream:
              schema:
                type: string
          headers:
            Transfer-Encoding:
              required: true
              schema:
                type: string
                enum:
                  - chunked
        '401':
          $ref: '#/components/responses/AuthenticationException'
        '422':
          $ref: '#/components/responses/ValidationException'
components:
  schemas:
    ChatCompletionsRequest:
      type: object
      properties:
        model:
          type: string
          description: |-
            Exactly one of `model` / `models` is required: a single model slug,
            or an ordered chain of slugs/aliases to try in turn (see RouteIntent
            and RoutePlanner). `prohibits:models` on `model` is what turns
            sending both into a 422 rather than `models` silently winning.
        models:
          type: array
          items:
            type: string
          minItems: 1
        provider:
          type: object
          description: >-
            The `provider` preferences object (OpenRouter-parity routing

            controls). Every field may only narrow what workspace policy

            already permits; see
            App\Services\Inference\Data\ProviderPreferences.
          properties:
            order:
              type:
                - array
                - 'null'
              items:
                type: string
            only:
              type:
                - array
                - 'null'
              items:
                type: string
            ignore:
              type:
                - array
                - 'null'
              items:
                type: string
            allow_fallbacks:
              type:
                - boolean
                - 'null'
            require_parameters:
              type:
                - boolean
                - 'null'
            residency:
              type:
                - string
                - 'null'
              description: |-
                Validated against the accepted set here, in front of
                App\Services\Inference\Enums\Residency::fromWireValue(), which
                throws on anything it does not recognise. Without this rule an
                unrecognised value would reach that parser from a real request
                and turn into an unhandled 500 instead of a 422.
              enum:
                - eu
                - any
                - null
        messages:
          type: array
          items:
            type: object
            properties:
              role:
                type: string
                enum:
                  - system
                  - user
                  - assistant
                  - tool
              content:
                type:
                  - string
                  - 'null'
              name:
                type:
                  - string
                  - 'null'
              tool_call_id:
                type:
                  - string
                  - 'null'
              tool_calls:
                type:
                  - array
                  - 'null'
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    function:
                      type: object
                      properties:
                        name:
                          type: string
                        arguments:
                          type:
                            - string
                            - 'null'
            required:
              - role
          minItems: 1
        temperature:
          type:
            - number
            - 'null'
        max_tokens:
          type:
            - integer
            - 'null'
          minimum: 1
        stream:
          type:
            - boolean
            - 'null'
        stream_options:
          type: object
          description: |-
            OpenAI's opt-in for a trailing usage-only chunk on streamed
            responses. Usage is always attached to the finish chunk regardless
            (see RunChatCompletion::streamResponse()); this only controls the
            additional empty-choices frame emitted after it.
          properties:
            include_usage:
              type:
                - boolean
                - 'null'
        firewall:
          type:
            - boolean
            - 'null'
          description: |-
            Defaults true. Set false to opt out of the firewall and accept
            non-EU routing; honoured only when the organization has recorded a
            compliance acceptance, otherwise the egress guard refuses the call.
        firewall_language:
          anyOf:
            - $ref: '#/components/schemas/PiiLanguage'
              description: |-
                The language the firewall analyses this request as, overriding
                the workspace's setting for this call only. `auto` detects per
                message. A caller sending several languages needs this per call
                rather than a workspace each; one that always sends the same
                language should set it on the workspace and omit it here.
            - type: 'null'
        collection:
          type:
            - array
            - 'null'
          description: |-
            Narrows retrieval to named knowledge collections. Omit it (the
            default) to blend the whole workspace: personal memory, the
            workspace's shared knowledge, and every collection in it. Pass a
            collection slug, or a list of slugs, to read only those plus the
            caller's own personal memory. A slug the workspace does not have
            is rejected, never ignored.
          items:
            type: string
            maxLength: 255
        user:
          type:
            - string
            - 'null'
          description: >-
            Optional end-user id (OpenAI's `user`). Scopes long-term memory
            facts.
          maxLength: 255
        thread:
          type:
            - string
            - 'null'
          description: >-
            Optional conversation thread id. Present = opt into server-side
            thread

            replay/append (Memory service); a client-chosen, organization-scoped
            string.
          maxLength: 255
        tags:
          type:
            - array
            - 'null'
          description: |-
            Free-form labels recorded on the trace, at most ten of at most 64
            characters each. They do not change how the request is served:
            they make the trace explorer able to answer questions about it
            afterwards.
          items:
            type: string
            maxLength: 64
          maxItems: 10
        name:
          type:
            - string
            - 'null'
          description: A human label for this request, shown on its trace.
          maxLength: 120
        top_p:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 1
        stop:
          type:
            - array
            - 'null'
          description: >-
            stop accepts a bare string or an array of strings; `stop.*`
            validates

            array elements when an array is supplied but does not apply to a
            scalar.
          items:
            type: string
        presence_penalty:
          type:
            - number
            - 'null'
          minimum: -2
          maximum: 2
        frequency_penalty:
          type:
            - number
            - 'null'
          minimum: -2
          maximum: 2
        'n':
          type:
            - integer
            - 'null'
          minimum: 1
        seed:
          type:
            - integer
            - 'null'
        logit_bias:
          type:
            - array
            - 'null'
          items:
            type: number
            minimum: -100
            maximum: 100
        logprobs:
          type:
            - boolean
            - 'null'
        top_logprobs:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 20
        max_completion_tokens:
          type:
            - integer
            - 'null'
          minimum: 1
        tools:
          type:
            - array
            - 'null'
          items:
            type: object
            properties:
              type:
                type:
                  - string
                  - 'null'
                enum:
                  - function
                  - null
              function:
                type: object
                properties:
                  name:
                    type: string
                  description:
                    type:
                      - string
                      - 'null'
                  parameters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: string
        tool_choice:
          type:
            - string
            - 'null'
          description: >-
            tool_choice may be a string ('none'|'auto'|'required') OR an object

            ({type:'function',function:{name}}); the controller normalises it
            downstream.
        parallel_tool_calls:
          type:
            - boolean
            - 'null'
        cache:
          type:
            - boolean
            - 'null'
          description: |-
            Set false to bypass the response cache for this request even when
            the Cache service is enabled and the request would otherwise be
            cacheable. Defaults true (cache enabled when service is on).
        response_format:
          type: object
          properties:
            type:
              type: string
              enum:
                - text
                - json_object
                - json_schema
            json_schema:
              type:
                - object
                - 'null'
              properties:
                name:
                  type: string
                schema:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                strict:
                  type:
                    - boolean
                    - 'null'
      required:
        - messages
      title: ChatCompletionsRequest
    PiiLanguage:
      type: string
      description: >
        The language a workspace's text is analysed as. WHY THIS EXISTS AT ALL.
        The self-hosted GLiNER detector is one multilingual model that reads
        Dutch, German and French without being told which, so the platform never
        had to know. Azure AI Language does have to be told: it rejects `auto`
        outright, and analysing Dutch as English is not a no-op. A Dutch citizen
        number comes back as `EUNationalIdentificationNumber` instead of
        `NLCitizensServiceNumber`, which the mapping does not know, so the BSN
        goes out in plaintext. Getting this wrong leaks.  ONLY THE FOUR THE
        CORPORA COVER. Azure supports around eighty languages, and offering them
        here would claim a detection quality nobody has measured. These four are
        the ones `pii-corpus-gretel.json` and `pii-eval-cases.json` score, so
        these four are the ones offered. Adding a fifth means adding cases for
        it first.
      enum:
        - auto
        - nl
        - en
        - fr
        - de
      title: PiiLanguage
  responses:
    AuthenticationException:
      description: Unauthenticated
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Error overview.
            required:
              - message
    ValidationException:
      description: Validation error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Errors overview.
              errors:
                type: object
                description: A detailed description of each field that failed validation.
                additionalProperties:
                  type: array
                  items:
                    type: string
            required:
              - message
              - errors
  securitySchemes:
    http:
      type: http
      scheme: bearer

````