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:
X-Server-Key: sk_live_...Authorization: Bearer sk_live_...Jede Antwort trägt Rate-Limit-Header, damit Sie proaktiv drosseln können, statt nur auf 429 zu reagieren:
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 17
X-RateLimit-Reset: 1721834400Fehlerantworten haben neben der menschenlesbaren error-Meldung ein stabiles code-Feld zum programmatischen Abgleich:
{ "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:
{ "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
/api/v1/knowledge/textLegt 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.
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"
}/api/v1/knowledgeLädt eine Datei hoch (PDF, DOCX, TXT, etc.). Die Datei wird automatisch geparst und in Chunks unterteilt.
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"
}/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.
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/api/v1/knowledge/ext/{externalId}Dokument per External ID abrufen oder löschen — ohne die interne UUID kennen zu müssen.
// 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/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.
// 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/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.
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/api/v1/knowledgeDokumente 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.
// 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
}/api/v1/statsStatistiken abrufen — Anzahl Dokumente, Chunks und Embeddings.
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
/api/v1/synthesizeText 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.
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" }/api/v1/synthesize/streamSprachsynthese 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.
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..."}/api/v1/synthesize/voicesVerfügbare Stimmen des konfigurierten TTS-Providers auflisten. Antwort wird 1 Stunde gecacht.
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
/api/v1/conversationsKonversationen des Tenants auflisten (Cursor-Pagination), optional auf ein Zeitfenster [from, to) eingeschränkt (Default: letzte 30 Tage, max. Fensterbreite 100 Tage).
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
}/api/v1/conversations/{sessionID}/messagesVollständiges, dauerhaft gespeichertes Transkript einer Konversation abrufen.
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
/api/v1/forms/submissionsFormular-Submissions (Leads) des Tenants auflisten (Cursor-Pagination).
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.
/api/v1/forms/submissions/{id}/statusStatus eines Leads setzen — new, contacted, converted oder archived.
PATCH /api/v1/forms/submissions/3f7a1b2c-.../status
X-Server-Key: YOUR_SERVER_API_KEY
Content-Type: application/json
{ "status": "contacted" }
// Response 204 No ContentAgent-Config
System-Prompt und Widget-Einstellungen programmatisch pflegen — "Agent as Code" aus der eigenen CI/CD-Pipeline
/api/v1/promptsAktive Prompt-Konfiguration abrufen: gewähltes Template, individueller System-Prompt-Override, verfügbare Templates.
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
}/api/v1/promptsAktives Template und/oder individuellen System-Prompt setzen.
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" }/api/v1/settings/widgetWidget-Einstellungen (Branding, Begrüßungstext, Terminbuchung, Formulare, …) setzen. Vollständiges WidgetSettings-Objekt im Body — siehe Admin-Dashboard-Export als Vorlage.
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
/api/v1/workflowsAlle Workflows des Tenants auflisten. Secret-Header von api_call-Workflows sind maskiert (has_value statt Klartext).
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 }] }/api/v1/workflowsNeuen Workflow anlegen — immer inaktiv (active=false), erst nach vollständiger Config per PATCH aktivierbar.
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, ... }/api/v1/workflows/{id}Workflow abrufen, teilweise aktualisieren (name/config/active/position) oder löschen.
// 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/api/v1/workflows/{id}/test-api-callEinen 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.
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
/api/v1/analyticsPlan-Nutzung (Conversations, Crawl-Seiten, Speicher) und Wissensbasis-Kennzahlen für den aktuellen Abrechnungszeitraum.
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
}/api/v1/analytics/conversationsTä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.
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 }]
}