Kasimir Docs DEEN Zur App →

API: Chat Completions

OpenAI-kompatibler Chat-Completions-Endpunkt von Kasimir mit Bearer-API-Key, Streaming, Modell-Governance und Usage-Abrechnung.

Unter https://kasimir.ai/api/v1 stellt Kasimir eine OpenAI-kompatible Schnittstelle bereit. POST /api/v1/chat/completions nimmt denselben Request-Body wie die OpenAI Chat Completions API entgegen. Es gelten die Regeln eurer Firma: Firmen-API-Schlüssel, nur freigegebene Modelle, EU-Freigabe und Monatsbudget. Bestehende OpenAI-SDKs funktionieren ohne Code-Änderung – es genügt, base_url und api_key zu setzen.

Endpunkt

Methode

POST

URL

https://kasimir.ai/api/v1/chat/completions

Auth

Authorization: Bearer kasi_…

Benötigter Scope

chat:write

Content-Type

application/json

Antwort

application/json (sync) oder text/event-stream (Streaming)

Authentifizierung

Alle Aufrufe werden über einen Firmen-API-Key authentifiziert, der im Header Authorization: Bearer <secret> mitgesendet wird. Keys haben das Format kasi_<32-Zeichen> und werden in der Kasimir-Oberfläche unter Administration → Zugriff von Workspace-Ownern oder -Admins erzeugt.

Der vollständige Schlüssel wird nur einmal angezeigt – direkt nach dem Erstellen. Kasimir kann ihn danach nicht mehr anzeigen. Geht er verloren, widerrufe ihn und erstelle einen neuen.

Jeder Key trägt Scopes. Neu erstellte Keys erhalten standardmäßig chat:read und chat:write. Für Chat Completions ist chat:write erforderlich — fehlt der Scope, antwortet die API mit 403.

# Schlägt mit 401 fehl, wenn der Header fehlt oder der Key ungültig/widerrufen ist.
Authorization: Bearer kasi_abcdef0123456789abcdef0123456789

Jeder erfolgreiche Aufruf aktualisiert die „letzte Nutzung“ des Schlüssels, sodass sich ungenutzte Keys in der Verwaltung erkennen lassen.

Request-Body

Der Body folgt dem OpenAI-Schema. model und messages sind Pflicht. Weitergereicht werden nur diese Felder der OpenAI-Chat-API: temperature, top_p, max_tokens, max_completion_tokens, stop, n, presence_penalty, frequency_penalty, seed, response_format, tools, tool_choice, parallel_tool_calls, user, logit_bias, logprobs, top_logprobs und reasoning_effort. Andere Felder ignoriert die API ohne Fehlermeldung.

Feld

Typ

Pflicht

Beschreibung

model

string

ja

Kasimir-Modell-Slug (siehe „Modelle"). Nicht der OpenAI-Modellname.

messages

array

ja

Mindestens 1 Nachricht im OpenAI-Chat-Format ({ role, content, … }).

stream

boolean

nein

true → Server-Sent-Events-Stream. Default false.

temperature, top_p, max_tokens, stop, tools, tool_choice, response_format, seed, …

div.

nein

Werden an das Modell weitergereicht (vollständige Liste oben). n muss zwischen 1 und 8 liegen.

Im Streaming-Modus liefert Kasimir am Ende automatisch die Verbrauchsangaben (usage) mit – du musst stream_options nicht selbst setzen.

Bilder, Audio und Dateien in messages nimmt die API nur eingebettet an – als data:-URI bzw. Base64. Eine https://-Adresse (z. B. in image_url) ergibt 400: Lade entfernte Medien selbst und sende sie Base64-kodiert. Ein Bild an ein Modell ohne Bildverständnis ergibt ebenfalls 400.

Modelle

model erwartet einen Kasimir-Slug, nicht den Modellnamen des Anbieters. Es gelten dieselben Regeln wie bei der Modellauswahl in der App:

  • Das Modell muss für deine Firma aktiv und vom Typ chat sein.

  • Für eure Firma deaktivierte Modelle sind nicht aufrufbar → 403.

  • Nicht-EU-Modelle sind nur verfügbar, wenn eure Firma sie freigeschaltet hat → sonst 403.

  • Im Tarif Basic sind nur die selbst gehosteten Modelle aufrufbar; alle anderen ergeben 403.

Die für deinen Schlüssel gültigen Slugs listet GET /api/v1/models auf (siehe unten). Die Antwort nennt im model-Feld immer den Kasimir-Slug.

Antwort (synchron)

Bei stream: false (oder ausgelassenem stream) ist die Antwort ein vollständiges OpenAI-Chat-Completion-Objekt. Das model-Feld wird auf den Kasimir-Slug normalisiert.

{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "created": 1750000000,
  "model": "gemma-4-31b",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Hallo! Wie kann ich helfen?" },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 18, "completion_tokens": 9, "total_tokens": 27 }
}

Antwort (Streaming)

Bei stream: true antwortet der Endpunkt mit Content-Type: text/event-stream im OpenAI-Format (data: {…}-Zeilen, abschließend data: [DONE]).

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"gemma-4-31b","choices":[{"index":0,"delta":{"role":"assistant","content":"Hallo"},"finish_reason":null}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"gemma-4-31b","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":9,"total_tokens":27}}

data: [DONE]
Request-Fluss: Auth- und Governance-Gates vor dem Proxy, mit Usage-Metering nach der Antwort.
Request-Fluss: Auth- und Governance-Gates vor dem Proxy, mit Usage-Metering nach der Antwort.

Budget & Usage-Metering

Jeder Aufruf wird vor der Weiterleitung gegen das Monats-Budget der Firma geprüft. Ist ein Monatsbudget gesetzt und hat der gesamte KI-Verbrauch eurer Firma im laufenden Kalendermonat (API, Chat, Workflows und alles Weitere) es erreicht, antwortet die API mit 402. Ohne Budget gibt es keine Grenze.

Jeder Aufruf wird mit Modell, Tokens und Kosten in Euro verbucht und zählt zum Monatsbudget. Beim Streaming geschieht das am Ende des Streams – auch bei vorzeitigem Abbruch für die bis dahin erzeugten Tokens.

Kosten = (prompt_tokens / 1000) × Preis_input + (completion_tokens / 1000) × Preis_output, gerundet auf 6 Nachkommastellen, in EUR. Die Preise stammen aus der Modellkonfiguration.

Fehler

Fehler werden im OpenAI-Fehlerschema zurückgegeben, damit Standard-SDKs sie normal verarbeiten:

{ "error": { "message": "Missing scope: chat:write", "type": "permission_error", "code": null } }

HTTP-Status

type

Bedeutung

400

invalid_request_error

Body ungültig (fehlendes model/messages, leeres messages-Array).

401

authentication_error

Bearer-Token fehlt, Key unbekannt oder widerrufen.

402

insufficient_quota

Monats-Budget der Firma erreicht.

403

permission_error

Scope chat:write fehlt, Modell für die Firma deaktiviert, Nicht-EU-Modell nicht freigeschaltet, Modell nicht im Tarif enthalten oder Firma gesperrt.

404

not_found_error

Modell-Slug unbekannt oder inaktiv.

429

invalid_request_error

Zu viele Anfragen in kurzer Zeit mit diesem Schlüssel, oder das Modell ist gerade ausgelastet.

5xx

api_error

Vorübergehender Fehler bei der Verarbeitung.

Tritt ein Fehler während eines bereits begonnenen Streams auf, kann er nicht mehr in das JSON-Fehlerschema umgewandelt werden — die Verbindung bricht ab. Behandle Stream-Abbrüche client-seitig.

Beispiele

curl — synchron

curl https://kasimir.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $KASIMIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-4-31b",
    "messages": [
      { "role": "system", "content": "Du bist ein hilfreicher Assistent." },
      { "role": "user", "content": "Schreibe einen Einzeiler über Datenschutz." }
    ],
    "temperature": 0.7
  }'

curl — Streaming

curl -N https://kasimir.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $KASIMIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-4-31b",
    "messages": [{ "role": "user", "content": "Zähle von 1 bis 5." }],
    "stream": true
  }'

Python — OpenAI SDK (synchron)

Da Kasimir OpenAI-kompatibel ist, genügt es, base_url und api_key zu setzen.

from openai import OpenAI

client = OpenAI(
    base_url="https://kasimir.ai/api/v1",
    api_key="kasi_…",  # dein Kasimir-API-Key
)

resp = client.chat.completions.create(
    model="gemma-4-31b",
    messages=[
        {"role": "system", "content": "Du bist ein hilfreicher Assistent."},
        {"role": "user", "content": "Nenne drei Vorteile von EU-Hosting."},
    ],
    temperature=0.7,
)

print(resp.choices[0].message.content)
print(resp.usage)  # prompt_tokens / completion_tokens / total_tokens

Python — OpenAI SDK (Streaming)

from openai import OpenAI

client = OpenAI(base_url="https://kasimir.ai/api/v1", api_key="kasi_…")

stream = client.chat.completions.create(
    model="gemma-4-31b",
    messages=[{"role": "user", "content": "Erkläre RAG in zwei Sätzen."}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content if chunk.choices else None
    if delta:
        print(delta, end="", flush=True)
print()

Fehlerbehandlung (Python)

from openai import OpenAI, APIStatusError

client = OpenAI(base_url="https://kasimir.ai/api/v1", api_key="kasi_…")

try:
    client.chat.completions.create(
        model="gemma-4-31b",
        messages=[{"role": "user", "content": "Hi"}],
    )
except APIStatusError as e:
    if e.status_code == 402:
        print("Monats-Budget erreicht — bitte Budget erhöhen.")
    elif e.status_code in (401, 403):
        print("Auth/Scope-Problem:", e.message)
    else:
        raise

Verwandte Endpunkte

Dieselbe Authentifizierung, Governance und dasselbe Metering gelten für:

Endpunkt

Zweck

GET /api/v1/models

OpenAI-kompatible Liste der für deine Firma erlaubten Chat- und Embedding-Modelle ({ object: "list", data: [{ id, object, created, owned_by }] }). Kein Scope erforderlich (nur gültiger Key).

POST /api/v1/embeddings

OpenAI-kompatible Embeddings (model + input). Benötigt Scope chat:write.

POST /api/v1/assistants/{id}/run

Führt einen firmenweit freigegebenen Kasimir-Agenten per API aus.

curl https://kasimir.ai/api/v1/models \
  -H "Authorization: Bearer $KASIMIR_API_KEY"