API-REFERENZ

Server API

Knowledge Base programmatisch verwalten

Sicherheitshinweis

Den Server API Key niemals im Frontend-Code, in Git-Repositories oder öffentlich zugänglichen Dateien speichern. Er gehört ausschließlich in serverseitige Umgebungsvariablen (z.B. .env auf dem Server, CI/CD-Secrets).



Umfang: Mit vollem API-Zugang erlaubt der Server Key nicht nur Lesezugriff, sondern auch Schreiboperationen — u.a. das Überschreiben Ihres System-Prompts und Ihrer Widget-Einstellungen (Agent-Config) sowie das Anlegen, Ändern und Testausführen von Custom Actions (Workflows), inklusive gespeicherter Secrets in deren Konfiguration. Ein geleakter Key erlaubt damit vollen Konfigurationszugriff auf Ihren Tenant, nicht nur Datenzugriff.

Authentifizierung, Fehler & Rate-Limits

Der API-Zugang hängt an Ihrem Tarif

Im Professional-Tarif sind lesende Aufrufe möglich (GET), im Enterprise-Tarif zusätzlich alle übrigen. In den Tarifen Free und Starter ist die Server-API nicht enthalten.



Maßgeblich ist die HTTP-Methode, nicht die Wirkung: Auch ein POST, der nichts ändert — der Testaufruf einer Aktion etwa —, verlangt den vollen Zugang. Sprachsynthese gehört ebenfalls dorthin, über beide Wege: POST /synthesize und GET /synthesize/stream erzeugen dasselbe Audio. Die Stimmenliste (GET /synthesize/voices) bleibt ein Leseaufruf.



Ein Aufruf, den Ihr Tarif nicht abdeckt, antwortet mit 402 und dem Code entitlement_required. Ihr Schlüssel bleibt dabei gültig — nach einem Tarifwechsel funktionieren dieselben Aufrufe ohne Änderung an Ihrer Integration.

Der Server API Key kann wahlweise als X-Server-Key-Header oder als Bearer-Token im Authorization-Header übergeben werden — beide Formen sind gleichwertig:

HTTP
X-Server-Key: sk_live_...
HTTP
Authorization: Bearer sk_live_...

Jede Antwort trägt Rate-Limit-Header, damit Sie proaktiv drosseln können, statt nur auf 429 zu reagieren:

HTTP
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 17
X-RateLimit-Reset: 1721834400

Fehlerantworten haben neben der menschenlesbaren error-Meldung ein stabiles code-Feld zum programmatischen Abgleich:

JSON
{ "error": "document not found", "code": "not_found" }

Mögliche Codes: invalid_request, unauthorized, entitlement_required, not_found, conflict, rate_limited, service_unavailable, upstream_error, internal_error.

Eine Antwort mit entitlement_required trägt zusätzlich das Feld feature mit dem Schlüssel des fehlenden Rechts:

JSON
{ "error": "Ihr Tarif erlaubt nur lesende API-Zugriffe.", "code": "entitlement_required", "feature": "features.api_access" }

Server API

Knowledge Base programmatisch verwalten — aus CMS, CI/CD-Pipeline oder Backend-Service

POST/api/v1/knowledge/text

Legt ein Text-Dokument an. Das optionale Feld external_id erlaubt später einen idempotenten Upsert. Bei doppelter external_id antwortet die API mit 409 Conflict — verwenden Sie in diesem Fall PUT.

HTTP
POST /api/v1/knowledge/text
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "filename": "FAQ",
  "text": "Hier steht der Inhalt des Dokuments...",
  "external_id": "faq-main"
}

// Response 201 Created
{
  "id": "3f7a...",
  "filename": "FAQ",
  "external_id": "faq-main",
  "status": "processing"
}
POST/api/v1/knowledge

Lädt eine Datei hoch (PDF, DOCX, TXT, etc.). Die Datei wird automatisch geparst und in Chunks unterteilt.

HTTP
POST /api/v1/knowledge
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: multipart/form-data

file: <binary>
external_id: "product-catalog" (optional)

// Response 201 Created
{
  "id": "4b2c...",
  "filename": "catalog.pdf",
  "external_id": "product-catalog",
  "status": "processing"
}
PUT/api/v1/knowledge/ext/{externalId}

Idempotenter Upsert: Existiert noch kein Dokument mit dieser External ID, wird es neu angelegt (<NavArrow /> 201). Existiert es bereits, werden Inhalt und Chunks vollständig ersetzt (<NavArrow /> 200). Ideal für regelmäßige Content-Synchronisation.

HTTP
PUT /api/v1/knowledge/ext/{externalId}
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "text": "Aktualisierter FAQ-Inhalt..."
}

// Response 201 Created → Neu angelegt
// Response 200 OK      → Ersetzt
GETDELETE/api/v1/knowledge/ext/{externalId}

Dokument per External ID abrufen oder löschen — ohne die interne UUID kennen zu müssen.

HTTP
// Dokument abrufen
GET /api/v1/knowledge/ext/{externalId}
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "id": "3f7a...",
  "filename": "FAQ",
  "status": "ready",
  "chunks": [...]
}

// Dokument löschen
DELETE /api/v1/knowledge/ext/{externalId}
X-Server-Key: YOUR_SERVER_API_KEY

// Response 204 No Content
GETPATCHDELETE/api/v1/knowledge/{id}

Dokument per interner UUID abrufen (inkl. Chunks), Metadaten aktualisieren (filename, external_id) oder löschen. Für die meisten Integrationen ist der ext/{externalId}-Pfad oben praktischer, da er die von Ihnen vergebene ID direkt verwendet.

HTTP
// Abrufen
GET /api/v1/knowledge/{id}
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "id": "3f7a...",
  "tenant_id": "tenant-uuid",
  "external_id": "faq-main",
  "filename": "FAQ.pdf",
  "mime_type": "application/pdf",
  "file_size": 102400,
  "source": "upload",
  "status": "ready",
  "created_at": "2024-01-15T10:30:00Z",
  "chunks": [{ "id": "chunk-uuid", "content": "...", "chunk_index": 0 }]
}

// Metadaten aktualisieren
PATCH /api/v1/knowledge/{id}
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "filename": "Neuer Name",
  "external_id": "new-external-id" (optional)
}

// Löschen
DELETE /api/v1/knowledge/{id}
X-Server-Key: YOUR_SERVER_API_KEY

// Response 204 No Content
PUT/api/v1/knowledge/{id}/chunks/{chunkId}

Einzelnen Chunk eines Dokuments bearbeiten. Nützlich, um Fehler in einem einzelnen Absatz zu korrigieren, ohne das ganze Dokument neu einzureichen.

HTTP
PUT /api/v1/knowledge/{id}/chunks/{chunkId}
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "content": "Überarbeiteter Chunk-Inhalt..."
}

// Response 200 OK
GET/api/v1/knowledge

Dokumente des Tenants auflisten (Cursor-Pagination). Optional nach external_id filtern.

Cursor-basiert statt Offset-basiert: next_cursor aus der Antwort wird unverändert als ?cursor=... an den nächsten Request angehängt. Das bleibt auch bei parallel neu eingehenden Dokumenten stabil — anders als Offset-Pagination verschiebt sich die Reihenfolge nicht, wenn zwischen zwei Abrufen ein neues Dokument eingefügt wird.

HTTP
// Erste Seite (Default limit 500, max. über ?limit=)
GET /api/v1/knowledge
X-Server-Key: YOUR_SERVER_API_KEY

// Nächste Seite
GET /api/v1/knowledge?cursor=eyJjcmVhdGVkX2F0IjoiLi4uIn0
X-Server-Key: YOUR_SERVER_API_KEY

// Nach external_id filtern
GET /api/v1/knowledge?external_id=faq-main
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "data": [
    { "id": "...", "filename": "FAQ", "status": "ready", ... }
  ],
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiLi4uIn0",
  "has_more": true
}
GET/api/v1/stats

Statistiken abrufen — Anzahl Dokumente, Chunks und Embeddings.

HTTP
GET /api/v1/stats
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "documents": 42,
  "chunks": 156,
  "chunks_with_embedding": 156
}

Text-to-Speech

Sprachsynthese programmatisch nutzen — für eigene Voice-Integrationen außerhalb des Chat-Widgets

POST/api/v1/synthesize

Text in Sprache umwandeln, Antwort als rohe Audio-Bytes (audio/wav oder audio/mpeg je nach format). 503 Service Unavailable, wenn für den Tenant kein TTS konfiguriert ist.

HTTP
POST /api/v1/synthesize
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "text": "Hallo, wie kann ich Ihnen helfen?",
  "voice": "de-DE-female-1" (optional),
  "format": "wav" (optional, "wav" oder "mp3")
}

// Response 200 OK
// Content-Type: audio/wav (oder audio/mpeg)
// <binäre Audiodaten>

// Response 503 Service Unavailable
{ "error": "tts not configured" }
GET/api/v1/synthesize/stream

Sprachsynthese als Server-Sent-Events-Stream — niedrigere Latenz als /synthesize, da Audio-Chunks eintreffen, sobald sie generiert sind. Erstes Event meta liefert das Audioformat (Sample-Rate, Kanäle, Bit-Tiefe), danach folgen chunk-Events mit Base64-kodiertem PCM.

HTTP
GET /api/v1/synthesize/stream?text=Hallo%2C%20wie%20kann%20ich%20helfen%3F&voice=de-DE-female-1
X-Server-Key: YOUR_SERVER_API_KEY

// Response: text/event-stream

event: meta
data: {"sample_rate": 24000, "channels": 1, "bit_depth": 16}

event: chunk
data: {"pcm_b64": "UklGRi..."}

event: chunk
data: {"pcm_b64": "AAABAA..."}
GET/api/v1/synthesize/voices

Verfügbare Stimmen des konfigurierten TTS-Providers auflisten. Antwort wird 1 Stunde gecacht.

HTTP
GET /api/v1/synthesize/voices
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "voices": [
    { "id": "de-DE-female-1", "name": "Anna", "quality": "high", "real_time": true }
  ]
}

Conversations

Chat-Konversationen und Nachrichten lesend abrufen — z.B. für einen eigenen CRM-Sync

GET/api/v1/conversations

Konversationen des Tenants auflisten (Cursor-Pagination), optional auf ein Zeitfenster [from, to) eingeschränkt (Default: letzte 30 Tage, max. Fensterbreite 100 Tage).

HTTP
GET /api/v1/conversations?from=2026-07-01T00:00:00Z&to=2026-08-01T00:00:00Z&limit=50
X-Server-Key: YOUR_SERVER_API_KEY

// Nächste Seite
GET /api/v1/conversations?cursor=eyJzb3J0X2tleSI6Ii4uLiJ9
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "data": [
    {
      "id": "...",
      "session_id": "...",
      "started_at": "2026-07-15T09:12:00Z",
      "message_count": 6,
      "channel": "web",
      "last_message_preview": "Haben Sie am Samstag geöffnet?"
    }
  ],
  "next_cursor": "eyJzb3J0X2tleSI6Ii4uLiJ9",
  "has_more": true
}
GET/api/v1/conversations/{sessionID}/messages

Vollständiges, dauerhaft gespeichertes Transkript einer Konversation abrufen.

HTTP
GET /api/v1/conversations/3f7a1b2c-.../messages
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "messages": [
    { "role": "user", "content": "Haben Sie am Samstag geöffnet?", "created_at": "..." },
    { "role": "assistant", "content": "Ja, samstags von 9 bis 14 Uhr.", "created_at": "..." }
  ]
}

Leads / Contacts

Über Formular-Workflows erfasste Leads abrufen und ihren Status pflegen — z.B. für einen eigenen CRM-Sync

GET/api/v1/forms/submissions

Formular-Submissions (Leads) des Tenants auflisten (Cursor-Pagination).

HTTP
GET /api/v1/forms/submissions?limit=50
X-Server-Key: YOUR_SERVER_API_KEY

// Nächste Seite
GET /api/v1/forms/submissions?cursor=eyJzb3J0X2tleSI6Ii4uLiJ9
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "data": [
    {
      "id": "...",
      "session_id": "...",
      "workflow_id": "...",
      "form_name": "Rückruf anfordern",
      // In der Reihenfolge, in der das Formular fragt. "key" ist die stabile
      // Feld-ID, "label" die Beschriftung aus der Aktion.
      "fields": [
        { "key": "field-a1", "label": "Name", "type": "text", "value": "Max Mustermann" },
        { "key": "field-b2", "label": "E-Mail", "type": "email", "value": "max@example.com" }
      ],
      "status": "new",
      "created_at": "2026-07-15T09:12:00Z"
    }
  ],
  "next_cursor": "eyJzb3J0X2tleSI6Ii4uLiJ9",
  "has_more": false
}

fields war bis August 2026 ein Objekt, das die Antworten unter der Feld-ID ablegte ({"field-a1": "Max Mustermann"}) — ohne Beschriftung und ohne verlässliche Reihenfolge. Seither ist es die oben gezeigte Liste. Sollten Sie noch gegen die alte Form entwickelt haben, lesen Sie statt fields[key] nun den Eintrag mit passendem key.

PATCH/api/v1/forms/submissions/{id}/status

Status eines Leads setzen — new, contacted, converted oder archived.

HTTP
PATCH /api/v1/forms/submissions/3f7a1b2c-.../status
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{ "status": "contacted" }

// Response 204 No Content

Agent-Config

System-Prompt und Widget-Einstellungen programmatisch pflegen — "Agent as Code" aus der eigenen CI/CD-Pipeline

GET/api/v1/prompts

Aktive Prompt-Konfiguration abrufen: gewähltes Template, individueller System-Prompt-Override, verfügbare Templates.

HTTP
GET /api/v1/prompts
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "active_template_id": "handwerker",
  "custom_system_prompt": "Sei besonders knapp und freundlich.",
  "available_templates": [{ "id": "handwerker", "name": "Handwerker" }],
  "can_edit": true
}
PUT/api/v1/prompts

Aktives Template und/oder individuellen System-Prompt setzen.

HTTP
PUT /api/v1/prompts
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{ "custom_system_prompt": "Sei besonders knapp und freundlich." }

// Response 200 OK
{ "message": "Prompt settings updated" }
PATCH/api/v1/settings/widget

Widget-Einstellungen (Branding, Begrüßungstext, Terminbuchung, Formulare, …) setzen. Vollständiges WidgetSettings-Objekt im Body — siehe Admin-Dashboard-Export als Vorlage.

HTTP
PATCH /api/v1/settings/widget
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{ "primary_color": "#6366f1", "bot_name": "Support-Bot", "greeting": "Wie kann ich helfen?" }

// Response 200 OK
{ "message": "Widget settings updated" }

Custom Actions (Workflows)

Chat-Erweiterungen programmatisch verwalten — Formulare, Terminbuchung, Buttons und eigene API-Call-Aktionen, die die KI bei Bedarf aufruft

GET/api/v1/workflows

Alle Workflows des Tenants auflisten. Secret-Header von api_call-Workflows sind maskiert (has_value statt Klartext).

HTTP
GET /api/v1/workflows
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{ "workflows": [{ "id": "...", "name": "Bestellstatus", "type": "api_call", "active": true, "position": 0 }] }
POST/api/v1/workflows

Neuen Workflow anlegen — immer inaktiv (active=false), erst nach vollständiger Config per PATCH aktivierbar.

HTTP
POST /api/v1/workflows
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{
  "name": "Bestellstatus",
  "type": "api_call",
  "config": {
    "description": "Bestellstatus anhand der Bestellnummer abrufen",
    "trigger": "Kunde fragt nach dem Status einer Bestellung",
    "method": "GET",
    "url": "https://shop.example.com/api/orders/{order_id}",
    "parameters": [{ "name": "order_id", "type": "text", "description": "Bestellnummer", "required": true }]
  }
}

// Response 201 Created
{ "id": "...", "name": "Bestellstatus", "type": "api_call", "active": false, ... }
GETPATCHDELETE/api/v1/workflows/{id}

Workflow abrufen, teilweise aktualisieren (name/config/active/position) oder löschen.

HTTP
// Aktivieren, nachdem die Config vollständig ist
PATCH /api/v1/workflows/{id}
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{ "active": true }

// Response 200 OK

// Löschen
DELETE /api/v1/workflows/{id}
X-Server-Key: YOUR_SERVER_API_KEY

// Response 204 No Content
POST/api/v1/workflows/{id}/test-api-call

Einen api_call-Workflow mit Test-Parametern ausführen (nur für type=api_call). Nützlich, um URL/Header/Body vor der Aktivierung zu verifizieren.

HTTP
POST /api/v1/workflows/{id}/test-api-call
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json

{ "params": { "order_id": "12345" } }

// Response 200 OK
{ "status_code": 200, "body_preview": "{\"status\":\"shipped\"}" }

Analytics

Nutzungsdaten und Gesprächs-Insights lesend abrufen

GET/api/v1/analytics

Plan-Nutzung (Conversations, Crawl-Seiten, Speicher) und Wissensbasis-Kennzahlen für den aktuellen Abrechnungszeitraum.

HTTP
GET /api/v1/analytics
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "plan_tier": "professional",
  "period_start": "2026-07-01",
  "period_end": "2026-08-01",
  "conversations": { "used": 812, "limit": 2000 },
  "documents": 42,
  "chunks": 156,
  "embedding_progress": 100
}
GET/api/v1/analytics/conversations

Tägliche Gesprächszahlen sowie Themen-/Sentiment-/Länder-Verteilung für ein Zeitfenster [from, to) (Default: letzte 30 Tage, max. Fensterbreite 100 Tage). Themen/Sentiment werden asynchron nachträglich befüllt und erscheinen erst nach einer kurzen Verzögerung.

HTTP
GET /api/v1/analytics/conversations?from=2026-07-01T00:00:00Z&to=2026-08-01T00:00:00Z
X-Server-Key: YOUR_SERVER_API_KEY

// Response 200 OK
{
  "daily_stats": [{ "date": "2026-07-15", "count": 34, "fallback_count": 2, "avg_confidence": 0.87 }],
  "topics": [{ "key": "Öffnungszeiten", "count": 18, "percentage": 22.5 }],
  "sentiment": [{ "key": "positive", "count": 60, "percentage": 75 }],
  "countries": [{ "key": "DE", "count": 70, "percentage": 87.5 }]
}
Nichts gefunden?Schreiben Sie uns Ihre Frage. Wir antworten binnen eines Arbeitstags per E-Mail.Frage an den Support senden