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

# OpenAI-kompatibel

> Localmind als Drop-in für OpenAI-SDKs: Agenten auflisten und stateless per Chat Completions ansprechen.

Die Localmind API stellt eine **OpenAI-kompatible** Oberfläche bereit. Eine bestehende OpenAI-SDK-Codebasis stellen Sie mit drei Änderungen auf Localmind um: `base_url` auf Ihre Instanz, `api_key` auf Ihren persönlichen API-Key und `model` auf eine **Agent-UUID** statt eines Modellnamens.

```python theme={null}
from openai import OpenAI

client = OpenAI(
    base_url="https://<deine-instanz>-api.localmind.ai/v1",  # Host Ihrer Instanz, -api-Suffix beachten
    api_key="sk-…",
)
```

<Note>
  In Localmind wählt der `model`-Parameter **keinen** Modellnamen wie `gpt-4`, sondern einen **Agent** über dessen UUID. Welches Sprachmodell der Agent nutzt, ist am Agent hinterlegt (**Agent bearbeiten → Modell**); verfügbar sind die dem Space über die Library bereitgestellten Modelle. Die Modell-Aufrufe laufen hinter einem LiteLLM-Proxy. Die UUIDs der für Sie zugänglichen Agenten liefert `GET /v1/models`.
</Note>

## `GET /v1/models`

Listet alle Agenten, auf die Ihr API-Key Zugriff hat (nicht gelöscht, keine System-Agenten), im OpenAI-`/models`-Format. Das Feld `name` spart einen zusätzlichen Lookup; `owned_by` ist die Org-ID.

<ParamField header="Authorization" type="string" required>
  `Bearer sk-…` — Ihr persönlicher API-Key.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://<deine-instanz>-api.localmind.ai/v1/models" \
    -H "Authorization: Bearer sk-…"
  ```

  ```python Python (OpenAI-SDK) theme={null}
  for m in client.models.list().data:
      print(m.id, m.name)   # id = Agent-UUID, name = Anzeigename
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "object": "list",
    "data": [
      {
        "id": "{agent_id}",
        "name": "Bürgerservice Assistent",
        "object": "model",
        "created": 1781346834,
        "owned_by": "{org_id}"
      }
    ]
  }
  ```
</ResponseExample>

<ResponseField name="object" type="string">
  Immer `"list"`.
</ResponseField>

<ResponseField name="data" type="array">
  Die zugänglichen Agenten. Jeder Eintrag hat die folgenden Felder.
</ResponseField>

<ResponseField name="data[].id" type="string">
  Die **Agent-UUID**. Diesen Wert verwenden Sie als `model` in `POST /v1/chat/completions`.
</ResponseField>

<ResponseField name="data[].name" type="string">
  Anzeigename des Agents (nur zur Lesbarkeit, nicht zum Routing).
</ResponseField>

<ResponseField name="data[].object" type="string">
  Immer `"model"`.
</ResponseField>

<ResponseField name="data[].created" type="integer">
  Erstellungszeitpunkt als Unix-Timestamp.
</ResponseField>

<ResponseField name="data[].owned_by" type="string">
  Die Organisation, der der Agent gehört (Org-ID).
</ResponseField>

<Note>
  Die Liste ist auf das verengt, was Ihr Key erreicht: Ein Key mit dem Scope „ausgewählte Spaces" zeigt nur Agenten aus diesen Spaces. Wie der Key Rollen und Spaces einschränkt, beschreibt [Authentifizierung und Rollen](/api-reference/Authentifizierung-und-Rollen).
</Note>

## `POST /v1/chat/completions`

OpenAI-kompatibler Chat-Endpunkt — **stateless** und **single-shot**: Es gibt keinen serverseitigen Conversation-State. Den bisherigen Verlauf senden Sie bei jedem Aufruf vollständig im `messages`-Array mit.

<ParamField header="Authorization" type="string" required>
  `Bearer sk-…` — Ihr persönlicher API-Key.
</ParamField>

<ParamField body="model" type="string" required>
  Die **Agent-UUID** aus `GET /v1/models`. Kein Modellname-Routing. Eine unbekannte UUID liefert `404 {"detail":"Model '…' not found"}`.
</ParamField>

<ParamField body="messages" type="array" required>
  Die Nachrichten der Konversation. Jede Nachricht hat ein `role` (`system`, `user` oder `assistant`) und ein `content`.
</ParamField>

<ParamField body="stream" type="boolean" default="false">
  Bei `true` wird die Antwort als Server-Sent-Events (SSE) gestreamt.
</ParamField>

<ParamField body="temperature" type="number">
  Überschreibt den am Agent hinterlegten Default.
</ParamField>

<ParamField body="max_tokens" type="integer">
  Maximale Anzahl generierter Tokens; überschreibt den Agent-Default. Das Alias `max_completion_tokens` wird ebenfalls akzeptiert.
</ParamField>

<ParamField body="response_format" type="object">
  JSON-Mode über `{"type": "json_object"}`. Wird via LiteLLM an das Modell durchgereicht — die **strikte Gültigkeit ist modellabhängig** und wird nicht hart erzwungen.
</ParamField>

<ParamField body="stream_options" type="object">
  Mit `{"include_usage": true}` enthält der Stream am Ende einen zusätzlichen Chunk mit den Usage-Zahlen.
</ParamField>

<Note>
  Die Parameter `top_p`, `stop`, `presence_penalty`, `frequency_penalty`, `seed`, `n` und `logit_bias` werden **akzeptiert, aber ignoriert** — sie lösen keinen `422`-Fehler aus, haben aber keine Wirkung.
</Note>

### Hinweise zum Verhalten

* **Tools laufen intern.** Ruft der Agent ein Tool auf (z. B. Hybrid Search über seine Wissensquellen), geschieht das serverseitig. Im Response ist `tool_calls` deshalb immer `null` — es gibt keine `function_call`-Ausgabe.
* **Kein Conversation-State.** Der Endpunkt persistiert nichts. Für mehrstufige Chats senden Sie den Verlauf im `messages`-Array mit. Siehe auch [Agenten](/api-reference/Agenten).

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://<deine-instanz>-api.localmind.ai/v1/chat/completions" \
    -H "Authorization: Bearer sk-…" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "{agent_id}",
      "messages": [
        {"role": "user", "content": "Wie beantrage ich einen Reisepass?"}
      ],
      "stream": false,
      "temperature": 0.7,
      "max_tokens": 2048
    }'
  ```

  ```python Python (OpenAI-SDK) theme={null}
  resp = client.chat.completions.create(
      model="{agent_id}",                       # Agent-UUID, kein Modellname
      messages=[
          {"role": "user", "content": "Wie beantrage ich einen Reisepass?"}
      ],
  )
  print(resp.choices[0].message.content)
  ```

  ```json Request-Body theme={null}
  {
    "model": "{agent_id}",
    "messages": [
      {"role": "user", "content": "Wie beantrage ich einen Reisepass?"}
    ],
    "stream": false,
    "temperature": 0.7,
    "max_tokens": 2048,
    "response_format": {"type": "json_object"},
    "stream_options": {"include_usage": true}
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "id": "chatcmpl-…",
    "object": "chat.completion",
    "created": 1781435623,
    "model": "{agent_id}",
    "choices": [
      {
        "index": 0,
        "message": {
          "role": "assistant",
          "content": "Einen Reisepass beantragen Sie …",
          "tool_calls": null,
          "refusal": null
        },
        "finish_reason": "stop",
        "logprobs": null
      }
    ],
    "usage": {
      "prompt_tokens": 3787,
      "completion_tokens": 6,
      "total_tokens": 3793
    },
    "system_fingerprint": null,
    "service_tier": null
  }
  ```
</ResponseExample>

<ResponseField name="id" type="string">
  Eindeutige ID der Antwort (`chatcmpl-…`).
</ResponseField>

<ResponseField name="object" type="string">
  Immer `"chat.completion"` (nicht-gestreamt).
</ResponseField>

<ResponseField name="model" type="string">
  Die angefragte Agent-UUID.
</ResponseField>

<ResponseField name="choices" type="array">
  Die generierten Antworten. `choices[0].message.content` enthält den Text des Agents; `tool_calls` ist immer `null`; `finish_reason` ist typischerweise `"stop"`.
</ResponseField>

<ResponseField name="usage" type="object">
  Token-Verbrauch mit `prompt_tokens`, `completion_tokens` und `total_tokens`.
</ResponseField>

### Streaming

Mit `"stream": true` antwortet der Endpunkt als Server-Sent-Events. Jede Zeile beginnt mit `data:` und enthält ein `chat.completion.chunk`-Objekt; der jeweilige Text-Teil steht in `choices[0].delta`. Mit `stream_options.include_usage` folgt am Ende ein Chunk mit den Usage-Zahlen. Den Abschluss markiert die Zeile `data: [DONE]`.

```text Stream (gekürzt) theme={null}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant"}}],"usage":null}

data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"Einen "}}],"usage":null}

data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"Reisepass …"}}],"usage":null}

data: {"object":"chat.completion.chunk","choices":[{"delta":{}}],"usage":{"prompt_tokens":3787,"completion_tokens":6,"total_tokens":3793}}

data: [DONE]
```

## Fehler

<ResponseExample>
  ```json 404 — Agent-UUID unbekannt theme={null}
  { "detail": "Model '{agent_id}' not found" }
  ```
</ResponseExample>

Eine unbekannte oder nicht zugängliche `model`-UUID liefert `404`. Listen Sie die gültigen Agenten erneut mit `GET /v1/models`. Alle Statuscodes und das Fehlermodell beschreibt [Konventionen und Fehler](/api-reference/Konventionen-und-Fehler).

## Verwandte Seiten

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/api-reference/Quickstart">
    Key erstellen, Agenten auflisten und die erste Anfrage senden.
  </Card>

  <Card title="Agenten" icon="bot" href="/api-reference/Agenten">
    Agenten programmatisch finden und ihre vollständige Konfiguration lesen.
  </Card>

  <Card title="Use Cases" icon="lightbulb" href="/api-reference/Use-Cases">
    Fertige Rezepte: OpenAI-Drop-in, RAG, Chatbot, n8n.
  </Card>

  <Card title="Authentifizierung und Rollen" icon="shield-check" href="/api-reference/Authentifizierung-und-Rollen">
    Wie Ihr Key Rollen erbt, an die Org gebunden ist und den Zugriff verengt.
  </Card>
</CardGroup>
