Zum Inhalt springen
XICBOT

Einstellungen

English
Dokumentation · Schnittstelle (API)

Schnittstelle: Widget-Wege

Alle 14 Wege des Widgets unter /api/v1/public/widget/{key}: Einstellungen, Gespräch, Antwortstrom, Einwilligung, Auskunft, Löschung, Werkzeuge und Anhänge.

In einfacher Sprache

Das Chatfenster spricht über eigene Wege mit dem Dienst. Diese Wege brauchen keine Anmeldung. Der Schlüssel des Fensters legt den Assistenten fest. Eine Kennung bindet jeden Aufruf an ein Gespräch. Die Seite zeigt jeden Weg mit Feldern, Antwort und Fehlern. Über diese Wege sendet der Besucher Fragen und bewertet Antworten. Er kann ein Gespräch löschen und Dateien senden. Auch der Widerruf seiner Zustimmung läuft so.

Stand

Alle Themen der Dokumentation

Das Chatfenster spricht mit dem Dienst über 14 Wege unter https://app.xicbot.de/api/v1/public/widget/{key}. Eine Anmeldung brauchen sie nicht: Der Widget-Schlüssel im Pfad bestimmt den Assistenten, und die Gesprächskennung, die der Start eines Gesprächs zurückgibt, bindet jeden weiteren Aufruf an dieses Gespräch. Diese Seite beschreibt jeden Weg mit Anfragefeldern, Antwort und Fehlern. Wie das Chatfenster die Wege nutzt, zeigt Gespräch im Widget; die Wege außerhalb des Widgets stehen unter Öffentliche Wege.

Überblick

Die Pfade in der Tabelle folgen auf https://app.xicbot.de/api/v1/public/widget/{key}. Adresse, Fehlerformat und die Regeln für Aufrufe aus dem Browser beschreibt Grundlagen der Schnittstelle, die Zähler der Drosseln Grenzen der Schnittstelle.

MethodePfad nach {key}ZweckDrossel
GET/Einstellungen des Widgets abrufenwidget
POST/conversationGespräch beginnenwidget
GET/conversation/{conversation}Verlauf ladenwidget
POST/sendFrage senden, Antwort als Ereignisstromwidget-send
POST/conversation/{conversation}/revokeEinwilligung widerrufenwidget
POST/conversation/{conversation}/tool/{call}/confirmWerkzeugaufruf bestätigenwidget-send
POST/conversation/{conversation}/tool/{call}/rejectWerkzeugaufruf ablehnenwidget
POST/conversation/{conversation}/tool/{call}/reportErgebnis einer Formularhilfe meldenwidget
POST/conversation/{conversation}/message/{message}/ratingAntwort bewertenwidget
GET/conversation/{conversation}/exportAuskunft über gespeicherte Datenwidget
DELETE/conversation/{conversation}Gespräch löschenwidget
POST/conversation/{conversation}/attachmentAnhang hochladenwidget-send
GET/conversation/{conversation}/attachmentAnhänge auflistenwidget
GET/conversation/{conversation}/attachment/{attachment}Anhang abrufenwidget

Gemeinsame Regeln

Schlüssel im Pfad

Der Schlüssel {key} ist der Wert des Attributs data-xicbot im Einbaucode: 16 Zufallsbytes, geschrieben als 32 Zeichen aus 0 bis 9 und a bis f. Er ist kein Geheimnis, denn er steht im Quelltext jeder Seite mit dem Widget. Vor jedem Weg prüft der Dienst den Schlüssel und antwortet sonst so:

StatuserrorBedeutung
404unknown_widgetKein Assistent mit diesem Schlüssel, das Widget ist abgeschaltet oder der Assistent ist nicht aktiv.
404unknown_widgetDas Konto, zu dem der Assistent gehört, ist nicht aktiv.
404demo_expiredDie Demo, zu der das Widget gehört, ist abgelaufen.

Einen neuen Schlüssel erzeugt POST /api/v1/assistants/{id}/key mit der Rolle admin, siehe Anmeldung an der Schnittstelle. Der Dienst protokolliert den Wechsel zuerst. Gelingt das nicht, antwortet er mit 500 und not_logged, und der bisherige Schlüssel bleibt stehen. Sonst steht der neue Wert in key, und der alte Schlüssel ergibt ab dann unknown_widget. Tauschen Sie deshalb den Einbaucode auf allen Seiten, siehe Öffentlicher Schlüssel.

Drosseln und Deckel

Zwei Schichten begrenzen die Wege. Die benannte Drossel zählt je Besucher, gebildet aus der IP-Adresse des Besuchers (bei IPv6 den ersten 64 Bit) und dem Widget-Schlüssel: widget erlaubt 60 und widget-send 12 Aufrufe je Minute, siehe Grenzen je Besucher. Dahinter prüft der Dienst die Deckel des Widgets, deren Werte am Konto hängen.

  • Der Deckel für Aufrufe gilt für Einstellungen, Start, Verlauf, Widerruf, Bewertung, Auskunft, Löschen, für Bestätigen, Ablehnen und Rückmelden eines Werkzeugaufrufs sowie für Hochladen, Auflisten und Abrufen von Anhängen. Die Vorgabe sind 60 Aufrufe je Minute und 2000 je Tag.
  • Der Deckel für Fragen gilt nur für POST send. Die Vorgabe sind 10 Fragen je Minute und 200 je Tag.
  • Jeder Deckel zählt auf dem Besucher und, wenn der Aufruf ein Gespräch nennt, zusätzlich auf diesem Gespräch. Das Gespräch kommt aus dem Pfad oder aus conversation_id im Rumpf. Jeder der beiden Zähler kann abweisen; gezählt wird erst, wenn keiner abgewiesen hat.
  • Die Zeitfenster sind 60 Sekunden und 86.400 Sekunden. Ein Deckel unter 1 ist abgeschaltet.

Weist ein Deckel ab, lautet die Antwort 429 mit diesem Rumpf und dem Kopf Retry-After:

FeldInhalt
errortoo_many_requests
limit_per_minMinutenwert des Deckels, der abgewiesen hat, als Zahl
limit_per_dayTageswert desselben Deckels
waitSekunden bis zum nächsten Versuch; derselbe Wert steht in Retry-After

Gesprächskennung

Der Start eines Gesprächs gibt conversation_id zurück, eine UUID. POST send und jeder Weg mit {conversation} im Pfad suchen das Gespräch über diese Kennung, den Assistenten des Schlüssels und den Kanal widget. Passt eines davon nicht, lautet die Antwort 404 mit not_found. Ein Gespräch eines anderen Assistenten oder aus einem anderen Kanal ist über das Widget also nicht erreichbar. Die Kennungen von Nachrichten, Werkzeugaufrufen und Anhängen sind ebenfalls UUIDs und werden nur innerhalb des genannten Gesprächs gesucht.

Aufrufe aus dem Browser

Die CORS-Regeln unter /api/v1/public/ lassen die Herkunft null zu. Das Chatfenster läuft in einem Rahmen mit sandbox="allow-scripts" ohne allow-same-origin, und ein solcher Rahmen sendet Origin: null. Welche Seiten ein Gespräch beginnen dürfen, entscheidet nicht CORS, sondern die Domainliste beim Start eines Gesprächs. Methoden, Köpfe und die Gültigkeit der Vorabfrage stehen unter Schnittstelle: Grundlagen.

Fehler

Fehler kommen als JSON mit einem Code in error; einige Wege legen weitere Felder dazu, die Tabellen unten nennen sie. Die Prüfung der Anfragefelder antwortet mit 422, einem Text in message und je Feld einer Liste in errors, siehe Fehlerformat. Werten Sie den Code aus, nicht den Text. Hat der Antwortstrom von POST send einmal begonnen, meldet er Fehler als Ereignis und nicht mehr als Status.

Einstellungen abrufen

GET /api/v1/public/widget/{key}/

Liefert Darstellung, Texte und Schalter des Widgets. Das Chatfenster ruft den Weg beim Laden auf und baut sich daraus auf. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
AbfrageparameterPflichtRegel
hostneinRechnername der einbettenden Seite. Eine ganze Adresse wird auf den Rechnernamen gekürzt, in Kleinbuchstaben; was über 120 Zeichen hinausgeht, wird abgeschnitten.
previewneinWahrheitswert. Mit true merkt sich der Dienst die Einbindung nicht.
languageneinSprachwunsch. Es zählen die ersten zwei Buchstaben, gültig sind de und en.

Mit host und ohne preview merkt sich der Dienst Zeitpunkt und Rechnernamen der Einbindung, für denselben Rechnernamen höchstens alle 300 Sekunden. Gegen die Domainliste prüft dieser Weg host nicht; das geschieht erst beim Start eines Gesprächs.

language wirkt nur auf die Texte, die der Dienst selbst stellt: note, limit_notice und den Standardtext der Einwilligung. Begrüßung und Ansprache bleiben, wie sie im Assistenten stehen. Ohne gültigen Wunsch gilt en, wenn die aktive Fassung des Assistenten englisch ist, sonst de.

Die Antwort ist ein JSON-Objekt mit diesen Feldern:

FeldInhalt
titleTitel des Widgets; ohne eigenen Titel der Name des Assistenten
color, position, verticalFarbe und Ecke des Widgets als Zeichenketten
offset_x, offset_y, width, height, scale, radiusAbstände, Breite, Höhe und Eckenradius in Pixel, Skalierung in Prozent (100 heißt unverändert), jeweils als ganze Zahl
avatarAdresse des Avatarbilds; eine leere Zeichenkette heißt kein Bild
languageSprache der aktiven Fassung, ohne Fassung de
greetingBegrüßung der aktiven Fassung, sonst leer
outreach_rulesRegeln der proaktiven Ansprache; das Chatfenster wertet sie im Browser aus
noteHinweis auf die Maschine: „Sie schreiben mit einem automatischen Assistenten.“
limit_noticeGrenzenhinweis: „Hinweis: Dieser Assistent ist ein Programm, er kann sich irren und ersetzt keine persönliche Beratung durch unsere Mitarbeiterinnen und Mitarbeiter.“
consenttrue, wenn der Assistent vor der ersten Nachricht eine Einwilligung verlangt
consent_textEigener Einwilligungstext oder der Standardtext in der gewählten Sprache; null ohne Einwilligungspflicht
attachmentstrue, wenn Besucher Dateien anhängen dürfen
attachment_max_bytes5242880, also 5 MiB je Datei
attachment_typesimage/png, image/jpeg, image/webp, application/pdf
attachment_max_count5 Anhänge je Gespräch
formsFormulare, die das Chatfenster ausfüllen darf, siehe unten
readytrue, sobald der Assistent eine aktive Fassung hat

Der Standardtext der Einwilligung lautet „Ich bin damit einverstanden, dass mein Gespräch gespeichert und zur Beantwortung meiner Frage verarbeitet wird.“ Die Grenzen der Anhänge stehen in der Antwort, damit das Chatfenster eine zu große Datei ablehnen kann, bevor sie hochgeladen wird.

Feld in formsInhalt
toolSchlüssel des Werkzeugs
selectorSelektor des Formulars auf der Seite
pageSeite, auf der das Formular steht; leer, wenn keine bestimmte Seite festgelegt ist
fieldsListe der Felder mit name und type
submit_allowedtrue, wenn das Chatfenster das Formular auch absenden darf

forms enthält höchstens 10 Einträge, geordnet nach dem Schlüssel des Werkzeugs: nur aktive Werkzeuge zum Ausfüllen von Formularen, die die öffentliche Rolle nutzen darf. Werte stehen darin keine; das Chatfenster trägt nur in die genannten Felder ein. Einrichtung unter Formulare vorausfüllen, die Regeln für outreach_rules unter Ansprache.

Gespräch beginnen

POST /api/v1/public/widget/{key}/conversation

Legt ein Gespräch im Kanal widget an und gibt seine Kennung zurück. Antwort 201 mit conversation_id. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
FeldPflichtRegel
hostneinZeichenkette, höchstens 120 Zeichen. Rechnername der einbettenden Seite; eine ganze Adresse wird auf den Rechnernamen gekürzt. Leer oder null gilt als fehlend.
visitorneinZeichenkette, höchstens 64 Zeichen. Kennung des Besuchers aus dem Chatfenster; leer wird nicht gespeichert.
viewportneinEiner der Werte handy, tablet, desktop, breit.
consentbei EinwilligungspflichtWahrheitswert. Nur der JSON-Wert true gilt als Einwilligung; 1 oder "1" bestehen die Feldprüfung, reichen aber nicht.
languageneinZeichenkette, höchstens 35 Zeichen. Derselbe Sprachwunsch wie beim Abruf der Einstellungen; es zählen die ersten zwei Buchstaben, gültig sind de und en. Fehlt consent_text, wählt er den Einwilligungstext, über den der Prüfwert gebildet wird; gilt der gezeigte Text nicht mehr, wählt er die Sprache des geltenden Textes in der Antwort. Das Chatfenster schickt hier denselben Wunsch wie beim Abruf der Einstellungen.
consent_textneinZeichenkette, höchstens 2000 Zeichen. Der Einwilligungstext, so wie das Chatfenster ihn gezeigt hat; das Chatfenster schickt ihn mit. Er zählt nur bei Einwilligungspflicht und wenn er nicht leer ist. Verglichen wird mit dem geltenden Text beider Sprachen; Folgen von Leerraum gelten dabei als ein Leerzeichen, Leerraum am Anfang und Ende zählt nicht. Passt er, wird der Prüfwert über den Text in dieser Sprache gebildet.

Der Dienst prüft in dieser Reihenfolge und bricht beim ersten Treffer ab:

  1. Schritt 1

    Felder prüfen

    Ungültige Felder ergeben 422 mit message und errors.

  2. Schritt 2

    Aktive Fassung

    Hat der Assistent keine aktive Fassung, lautet die Antwort 422 mit no_version.

  3. Schritt 3

    Deckel für Aufrufe

    Ist der Deckel erreicht, folgt 429 mit too_many_requests.

  4. Schritt 4

    Domainliste

    Passt host nicht zur Domainliste, lautet die Antwort 403 mit host_not_allowed.

  5. Schritt 5

    Sperrliste

    Ist die IP-Adresse des Besuchers gesperrt, folgt 403 mit blocked.

  6. Schritt 6

    Einwilligung

    Verlangt der Assistent eine Einwilligung und fehlt consent: true, lautet die Antwort 422 mit consent_missing. Passt ein mitgeschickter consent_text zu keinem geltenden Einwilligungstext, folgt 422 mit consent_changed; consent_text trägt dann den geltenden Text in der Sprache, die language wählt. Diese Prüfungen stehen vor dem Anlegen: Ohne die nötige Einwilligung legt der Dienst kein Gespräch an.

  7. Schritt 7

    Anlegen

    Erst jetzt legt der Dienst das Gespräch mit dem Status open an und antwortet mit 201.

Ist die Domainliste des Assistenten leer, darf jede Seite ein Gespräch beginnen. Enthält sie Einträge, muss host angegeben sein und entweder einem Eintrag gleichen oder auf einen Punkt und einen Eintrag enden: Der Eintrag example.com deckt shop.example.com mit ab. Einträge trennt ein Komma oder ein Zeilenumbruch, verglichen wird in Kleinbuchstaben. Die Liste pflegen Sie unter Erlaubte Domains.

Gesperrte Besucher legen kein Gespräch mehr an; die Sperre greift, bevor ein Gespräch angelegt wird. Wie Sie Besucher sperren, steht unter Besucher sperren.

Verlangt der Assistent eine Einwilligung, speichert das Gespräch den Zeitpunkt in consent_at und einen Prüfwert in consent_hash. Der Prüfwert ist ein SHA-256 über den Einwilligungstext, den der Besucher in der gewählten Sprache sieht, die Fassung der Datenschutzhinweise und den Rechnernamen. Das ist der eigene Text des Assistenten, sonst der Standardtext der Sprache. Schicken Sie den gezeigten Wortlaut in consent_text mit, gilt die Sprache, deren Text er entspricht. Fehlt er, wählt language die Sprache wie beim Abruf der Einstellungen; ohne gültigen Wunsch gilt en, wenn die aktive Fassung englisch ist, sonst de. Senden Sie in diesem Fall denselben Wunsch wie beim Abruf der Einstellungen: Gilt der Standardtext, hielte der Prüfwert sonst den Wortlaut einer anderen Sprache fest als den angezeigten. Die Einwilligung hängt damit am Gespräch und nicht an einem Wert im Browser. Mehr unter Einwilligung.

Nach dem Anlegen löst der Dienst den Webhook conversation.started mit conversation_id, assistant_id und channel aus.

StatuserrorBedeutung
422message, errorsEin Feld ist ungültig.
422no_versionDer Assistent hat keine aktive Fassung.
429too_many_requestsDeckel für Aufrufe erreicht.
403host_not_allowedhost fehlt oder passt nicht zur Domainliste.
403blockedDie IP-Adresse des Besuchers ist gesperrt.
422consent_missingEinwilligung verlangt, consent ist nicht true. Es wurde nichts angelegt.
422consent_changedDer mitgeschickte consent_text passt zu keinem geltenden Einwilligungstext; consent_text in der Antwort trägt den geltenden Text. Es wurde nichts angelegt.

Frage senden

POST /api/v1/public/widget/{key}/send

Speichert die Frage des Besuchers und antwortet mit einem Ereignisstrom. Die Gesprächskennung steht im Rumpf, nicht im Pfad. Zählt gegen den Deckel für Fragen, nicht gegen den für Aufrufe.

Anmeldung
Keine
Begrenzung
widget-send, 12 je Minute je Besucher, dazu der Deckel für Fragen
FeldPflichtRegel
conversation_idjaKennung aus dem Start, höchstens 64 Zeichen.
textjaDie Frage, 1 bis 4000 Zeichen.
suggestedneinWahrheitswert. true, wenn der Besucher eine vorgeschlagene Folgefrage gewählt hat; der Dienst vermerkt es an der Frage.

Hat das Konto einen kleineren Längendeckel als 4000 Zeichen, gilt dieser. Die Frage wird gespeichert, bevor der Strom beginnt. Steht das Gespräch auf closed, öffnet die gespeicherte Frage es wieder: war es übergeben (escalated_at gesetzt), wird es escalated mit neuem escalated_at, sonst open; resolved_at wird leer. Ein Ereignis geht dabei nicht hinaus, und eine abgewiesene Frage öffnet nichts. Je Gespräch läuft höchstens eine Antwort; der Dienst belegt das Gespräch mit einer bedingten Aktualisierung. Endet ein Lauf nicht sauber, gibt die Belegung das Gespräch nach 180 Sekunden frei.

StatuserrorBedeutung
422message, errorsEin Feld ist ungültig.
429too_many_requestsDeckel für Fragen erreicht.
404not_foundKein Gespräch dieses Assistenten im Kanal widget mit dieser Kennung.
403consent_revokedDie Einwilligung wurde widerrufen.
403consent_missingDer Assistent verlangt eine Einwilligung, das Gespräch hat keine, etwa weil die Pflicht erst nach dem Start eingeschaltet wurde.
403blockedDie IP-Adresse des Besuchers oder dieses Gespräch ist gesperrt.
422no_versionDie Fassung, mit der das Gespräch begonnen hat, besteht nicht mehr.
409reply_in_progressFür dieses Gespräch läuft schon eine Antwort.
413input_too_longDie Frage ist länger als der Längendeckel des Kontos; limit nennt den Deckel, length die Länge.

Befehl in der Schale bash

curl -N https://app.xicbot.de/api/v1/public/widget/0123456789abcdef0123456789abcdef/send \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{"conversation_id":"9d1f6c2a-3b4e-4f5a-8c7d-1e2f3a4b5c6d","text":"Ich habe eine Frage zu meiner Bestellung."}'

Ereignisstrom

Nach den Prüfungen antwortet der Weg mit Status 200, Content-Type: text/event-stream; charset=utf-8 und Cache-Control: no-cache, no-store. Jedes Ereignis besteht aus einer Zeile event: mit dem Namen, einer Zeile data: mit einem JSON-Objekt und einer Leerzeile. Umlaute und Schrägstriche stehen unmaskiert im JSON. Das Chatfenster sendet dazu Accept: text/event-stream. Wie es die Ereignisse darstellt, beschreibt Antwortstrom.

EreignisDatenBedeutung
startconversation_id, question_id (null)Erstes Ereignis jedes Stroms.
texttEin Stück der Antwort. Hängen Sie die Stücke in der Reihenfolge des Eingangs aneinander.
toolWerkzeugaufruf in KurzformDer Assistent hat ein Werkzeug genutzt oder schlägt einen Schritt vor, der eine Bestätigung braucht (needs_confirmation). Felder unter Werkzeugaufrufe.
livelive (true), sinceEin Mitarbeiter hat das Gespräch übernommen; since ist der Zeitpunkt der Übernahme.
errorcode, dazu scope und retry_after oder limitDie Antwort ist gesperrt, siehe Sonderfälle.
model_switchreason (transient)Nach einer vorübergehenden Störung wird die Antwort anders erzeugt; der Strom läuft weiter.
fallbackreason (transient oder error), transientDie Antwort ist gescheitert; es folgt die hinterlegte Notfallantwort als text.
revokedreason (consent_revoked)Die Einwilligung wurde während des Laufs widerrufen; die Antwort wird verworfen.
citationscitationsDie Quellen, die die Antwort nutzt; nur wenn es welche gibt. Bei einer Antwort aus einem Frage-Antwort-Paar genau ein Beleg mit der Frage des Paares.
contact_offeroffered (true)Der Assistent bietet an, den Kontakt herzustellen.
follow_upsquestions, dropped, checked, reasonBis zu 3 vorgeschlagene Folgefragen; nur wenn welche übrig bleiben. checked sagt, ob sie gegen das Wissen geprüft wurden, dropped, wie viele dabei wegfielen. Ohne Prüfung ist reason no_knowledge (kein Wissen hinterlegt) oder no_tenant_context, sonst null.
handoffhandoff (true), reasonÜbergabe an einen Menschen empfohlen. reason ist assistant, conversation_limit oder nach der Themenprüfung ein Text, der die berührten Themen nennt, etwa Gesperrtes Thema: …; ohne einen solchen Text enforcement.
redactiontext, reason (claims oder notice), bei claims auch count und gegebenenfalls partsErsetzt den bisher gezeigten Text ganz durch text. Haben Werkzeugaufrufe die Antwort unterbrochen, kann parts denselben Text in Stücken an diesen Stellen tragen; leere Stücke fallen weg.
verificationstate, claims, totalErgebnis der Belegprüfung: skipped, no_claims, verified, unverified oder no_source.
enforcementstate (clear oder enforced), topics, handoverErgebnis der Themenprüfung.
endstate, message_id, refused, citationsLetztes Ereignis des Stroms.

citations, contact_offer, follow_ups, handoff mit assistant, redaction, verification und enforcement kommen nur, wenn die Antwort regulär zu Ende läuft. Ein gekürzter Strom sieht so aus:

Quelltext text

event: start
data: {"conversation_id":"9d1f6c2a-3b4e-4f5a-8c7d-1e2f3a4b5c6d","question_id":null}

event: text
data: {"t":"Gern helfe ich Ihnen "}

event: text
data: {"t":"bei Ihrer Bestellung."}

event: verification
data: {"state":"no_claims","claims":[],"total":0}

event: enforcement
data: {"state":"clear","topics":[],"handover":false}

event: end
data: {"state":"done","message_id":"4b8e2f10-6c3d-4a5e-9f7b-2d1c0e9a8b76","refused":false,"citations":[]}

Sonderfälle

Die Frage ist in jedem dieser Fälle gespeichert, bevor der Strom beginnt.

  • Übernahme: Hat ein Mitarbeiter das Gespräch übernommen, folgen auf start nur live und end mit state gleich live und message_id gleich null. Die Antwort schreibt der Mitarbeiter, siehe Gespräch übernehmen.
  • Kontingent erschöpft: Es folgen error mit code gleich quota_exhausted, scope gleich month und retry_after in Sekunden bis zum Monatswechsel, dann die Notfallantwort als text und end mit blocked. Der Status bleibt 200; eine 429 für das Kontingent gibt es nur im Kanal der Integrationsschnittstelle. Siehe Kontingent erschöpft.
  • Gesprächsdeckel: Hat der Besucher in diesem Gespräch schon so viele Fragen gestellt, wie der Deckel des Kontos erlaubt, folgen error mit conversation_limit und limit, ein Hinweis als text, handoff mit conversation_limit und end mit blocked. Die Vorgabe sind 60 Fragen, der Wert 0 schaltet den Deckel ab.
  • Störung: Bei einer vorübergehenden Störung kann model_switch kommen, und die Antwort läuft weiter. Scheitert sie, folgen fallback, die Notfallantwort als text und end mit fallback.
  • Widerruf während des Laufs: Bei Gesprächen mit Einwilligung prüft der Lauf höchstens einmal je Sekunde und noch einmal am Ende, ob die Einwilligung widerrufen wurde. Dann verwirft er die Antwort und sendet revoked sowie end mit revoked.
  • Antwort aus einem Frage-Antwort-Paar: Trifft die Frage ein aktives Paar, wird kein Modell gefragt. Auf start folgen die Antwort des Paares in einem einzigen text, citations mit genau einem Beleg (die Frage des Paares als document, chunk_id aus qa: und der Kennung des Paares) und enforcement; berührt die Frage ein gesperrtes Thema oder ein Tabu, können redaction mit notice, ein Hinweis als weiteres text und handoff folgen. Zum Schluss kommt end mit done. verification, follow_ups und contact_offer gibt es dabei nicht. Siehe Frage-Antwort-Paare.
  • Nachbearbeitung: redaction ersetzt den gezeigten Text. Mit claims stehen an Stelle unbelegter Aussagen die Platzhalter [nicht belegt] oder [not backed], mit notice hat die Themenprüfung den Text umgeschrieben. Nach enforcement kann ein Hinweis als weiteres text folgen, ebenso ein Hinweis auf unbelegte Aussagen, wenn der Assistent nur aus seinem Wissen antworten darf.
state in endBedeutung
doneDie Antwort ist regulär zu Ende gelaufen.
fallbackStatt der Antwort steht die Notfallantwort im Gespräch.
revokedDie Einwilligung wurde während des Laufs widerrufen; die Antwort ist verworfen.
blockedKontingent erschöpft oder Gesprächsdeckel erreicht.
liveEin Mitarbeiter hat das Gespräch übernommen.

message_id ist die Kennung der gespeicherten Antwort; mit ihr bewerten Sie die Antwort. Wurde nichts gespeichert, ist der Wert null. refused ist nur bei done true, wenn der Assistent die Frage abgelehnt hat. citations nennt die Quellen des Laufs.

Verlauf laden

GET /api/v1/public/widget/{key}/conversation/{conversation}

Liefert den bisherigen Verlauf, damit das Chatfenster nach einem Neuladen der Seite dort weitermacht, wo der Besucher war. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe

Die Antwort enthält messages und taken_over. messages besteht aus den jüngsten 50 Nachrichten und den jüngsten 50 Werkzeugaufrufen, gemeinsam aufsteigend nach Zeit sortiert. taken_over ist true, solange ein Mitarbeiter das Gespräch übernommen hat. Ist das Gespräch unbekannt, lautet die Antwort 404 mit not_found.

EintragFelder
Frage des Besuchersrole (user), text, citations
Antwort des Assistentenrole (assistant), text, citations, id, rating (null, 0 oder 1)
Nachricht eines Mitarbeitersrole (operator), text, citations, id
Werkzeugaufrufid (w und die Kennung des Aufrufs), role (tool), tool mit dem Aufruf in Kurzform

Einwilligung widerrufen

POST /api/v1/public/widget/{key}/conversation/{conversation}/revoke

Widerruft die Einwilligung für dieses Gespräch. Der Besucher braucht dafür kein Konto, nur die Gesprächskennung. Ein Rumpf ist nicht nötig. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe

Die Antwort lautet {"revoked": true, "run_aborted": …}. run_aborted ist true, wenn das Gespräch in diesem Moment für eine Antwort belegt war; ein laufender Lauf verwirft die Antwort dann und endet mit revoked. Der Widerruf wird einmal gesetzt: Ein zweiter Aufruf antwortet gleich und ändert den Zeitpunkt nicht. Mehr unter Widerruf.

Weg nach dem WiderrufErgebnis
POST send403 mit consent_revoked
Antwort bewerten403 mit consent_revoked
Anhang hochladen422 mit consent_revoked
Verlauf, Auskunft, Löschenbleiben erreichbar

Widerruf, Auskunft und Löschen stehen auch gesperrten Besuchern offen; die Sperrliste prüft der Dienst nur beim Start, beim Senden und beim Hochladen eines Anhangs.

StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht.
404not_foundGespräch unbekannt.
422without_consentDas Gespräch wurde ohne Einwilligung begonnen; es gibt nichts zu widerrufen.

Antwort bewerten

POST /api/v1/public/widget/{key}/conversation/{conversation}/message/{message}/rating

Speichert die Bewertung einer Antwort des Assistenten. {message} ist message_id aus dem Ereignis end oder id aus dem Verlauf. Antwort {"message": {"id": …, "rating": …}}. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
FeldPflichtRegel
ratingja, darf null sein1 für Ja, 0 für Nein auf „War das hilfreich?“; null nimmt die Bewertung zurück.

Der Deckel wird vor den Feldern geprüft. Mit der Note speichert der Dienst den Zeitpunkt; null löscht beides. Wie das Chatfenster die Knöpfe zeigt, steht unter Bewertung.

StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht.
422message, errorsrating fehlt oder ist nicht null, 0 oder 1.
404not_foundGespräch unbekannt oder die Nachricht gehört nicht zu diesem Gespräch.
403consent_revokedDie Einwilligung wurde widerrufen.
422not_rateableDie Nachricht ist keine Antwort des Assistenten.

Auskunft

GET /api/v1/public/widget/{key}/conversation/{conversation}/export

Liefert alles, was zu diesem Gespräch gespeichert ist, als JSON. Der Besucher braucht dafür kein Konto, nur die Gesprächskennung. Zählt gegen den Deckel für Aufrufe; ist das Gespräch unbekannt, lautet die Antwort 404 mit not_found.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
FeldInhalt
conversationstarted, host, message_count, consent_at, consent_revoked_at
messagesAlle Nachrichten, aufsteigend, mit role, text und time
records.tool_callsWerkzeugaufrufe in Kurzform
records.requestsAnfragen mit name, email, phone, subject, time
records.appointmentsTermine mit starts_at, type, name, email, phone, status, time
records.attachmentsAnhänge mit denselben Feldern wie beim Auflisten
records.cartsWarenkörbe mit items, subtotal_cents, discount_cents, coupon_code, shipping_cents, total_cents, currency, status, time
controllerName des Kontos, also des Betreibers der Seite, auf der das Widget läuft
retention_daysAm Konto hinterlegte Aufbewahrungsdauer der Gespräche in Tagen oder null

Zeitpunkte stehen im Format ISO 8601. Mehr zu den Rechten des Besuchers unter Auskunft.

Gespräch löschen

DELETE /api/v1/public/widget/{key}/conversation/{conversation}

Löscht das Gespräch. Der Besucher braucht dafür kein Konto, nur die Gesprächskennung. Antwort {"deleted": true, "messages": n} mit der Zahl der gelöschten Nachrichten. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe

Die Löschung wird zuerst protokolliert: Der Protokolleintrag mit dem Auslöser visitor und den Anzahlen entsteht in derselben Datenbanktransaktion wie das Löschen und vor ihm. Kommt kein Eintrag zustande, löscht der Dienst nichts und antwortet mit 500 und not_logged. Was mit dem Gespräch zusammen gelöscht wird, beschreibt Was mit dem Gespräch geht.

StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht.
404not_foundGespräch unbekannt, auch nach einer bereits erfolgten Löschung.
500not_loggedDer Protokolleintrag kam nicht zustande; es wurde nichts gelöscht. Versuchen Sie es später erneut.

Werkzeugaufrufe

Schlägt der Assistent einen Schritt vor, der etwas verändert, oder ruft er ein lesendes Werkzeug mit der Freigabe mit Bestätigung auf, kommt im Strom ein Ereignis tool mit state gleich proposed und needs_confirmation gleich true. Ausgeführt wird der Schritt erst, wenn der Besucher ihn bestätigt: Der Bestätigungsweg ist der einzige, auf dem ein veränderndes Werkzeug im Widget läuft; der Antwortlauf selbst führt nur Lesendes aus. Die Karten im Chatfenster beschreibt Werkzeugkarten, die Werkzeuge selbst Werkzeuge.

Ereignis, Verlauf, Auskunft und die Wege dieses Abschnitts zeigen einen Aufruf in derselben Kurzform:

FeldInhalt
idKennung des Aufrufs, eine UUID
keySchlüssel des Werkzeugs
kindArt des Werkzeugs
stateZustand, siehe unten
previewVorschau des Schritts für die Karte
inputEingaben des Aufrufs
resultErgebnis nach der Ausführung
reportRückmeldung einer Formularhilfe, sonst leer
errorIm Widget der feste Text „Der Schritt konnte nicht ausgeführt werden.“, ohne Fehler null
needs_confirmationtrue im Zustand proposed
chain_cappedtrue, wenn der Aufruf am Höchstwert von 5 Aufrufen je Antwort gescheitert ist
created_atZeitpunkt des Aufrufs

Dauer und Freigabeweg eines Aufrufs gibt das Widget nicht heraus, im Ergebnis auch nicht die Felder note und email_notified. Je Antwort laufen höchstens 5 Werkzeugaufrufe; ein weiterer endet mit failed und chain_capped gleich true.

stateBedeutung
proposedVorgeschlagen, wartet auf Bestätigung oder Ablehnung.
confirmedBestätigt, die Ausführung läuft.
executedAusgeführt; das Ergebnis steht in result.
rejectedVom Besucher abgelehnt.
expiredDer Vorschlag ist älter als 60 Minuten und lässt sich nicht mehr bestätigen.
failedGescheitert, etwa weil das Werkzeug inzwischen entfernt wurde oder Rolle, Paket oder Pflichtfelder nicht mehr passen.
timeoutDie Ausführung hat ihre Zeitgrenze überschritten.

Aufruf bestätigen

POST /api/v1/public/widget/{key}/conversation/{conversation}/tool/{call}/confirm

Bestätigt einen vorgeschlagenen Schritt und führt ihn aus. Kein Rumpf. Antwort {"call": …, "duplicate": …}. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget-send, 12 je Minute je Besucher, dazu die Deckel für Aufrufe

Zuerst setzt der Dienst einen Vorschlag, der älter als 60 Minuten ist, auf expired. Dann setzt er den Aufruf mit einer bedingten Aktualisierung von proposed auf confirmed; von zwei gleichzeitigen Klicks gewinnt nur einer. Beim Klick prüft er erneut, ob das Werkzeug noch besteht, ob Rolle und Paket es erlauben und ob die Pflichtfelder gefüllt sind; sonst endet der Aufruf mit failed. Die Ausführung endet mit executed, timeout oder failed.

duplicate ist true, wenn der Aufruf schon entschieden war oder ein anderer Klick gewonnen hat; der Schritt läuft dann kein zweites Mal. call zeigt in jedem Fall den aktuellen Stand, auch expired.

Aufruf ablehnen

POST /api/v1/public/widget/{key}/conversation/{conversation}/tool/{call}/reject

Lehnt einen vorgeschlagenen Schritt ab. Kein Rumpf. Antwort {"call": …, "duplicate": …} mit state gleich rejected; ein Vorschlag, der älter als 60 Minuten ist, wird stattdessen expired. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht (Bestätigen und Ablehnen).
404not_foundGespräch unbekannt oder der Aufruf gehört nicht zu diesem Gespräch.

Rückmeldung zur Formularhilfe

POST /api/v1/public/widget/{key}/conversation/{conversation}/tool/{call}/report

Meldet, was das Ladeskript auf der Seite des Kunden mit einem ausgeführten Aufruf der Formularhilfe getan hat. Antwort {"report": …, "duplicate": …}. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
FeldPflichtRegel
gefuelltneinListe mit höchstens 20 Feldnamen zu je höchstens 80 Zeichen: eingetragene Felder
fehlendneinListe wie oben: Felder, die auf der Seite nicht gefunden wurden
gesperrtneinListe wie oben: Felder, die sich nicht füllen ließen
abgesendetneinWahrheitswert: das Formular wurde abgeschickt
gefundenneinWahrheitswert: das Formular wurde auf der Seite gefunden

Der Rumpf ist JSON. Ohne JSON-Kopf liest der Dienst den rohen Rumpf bis 16384 Byte und wertet ihn als JSON aus; so kann das Ladeskript die Meldung als text/plain mit keepalive schicken. Eine solche Anfrage braucht keine Vorabprüfung und übersteht das Verlassen der Seite, etwa wenn das Formular die Seite beim Absenden wechselt.

Die Meldung ist eine Angabe der Seite des Kunden. Behalten werden nur Feldnamen, die in der Anweisung dieses Aufrufs stehen. Gespeichert wird report mit filled, missing, blocked, submitted und form_found; submitted ist nur true, wenn die Anweisung das Absenden vorsah und abgesendet gleich true ist. Angenommen wird die erste Meldung je Aufruf; jede weitere erhält duplicate gleich true und den schon gespeicherten Bericht. Was die Formularhilfe einträgt, beschreibt Formulare vorausfüllen.

StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht.
422invalid_reportRumpf ist kein JSON-Objekt oder ohne JSON-Kopf größer als 16384 Byte.
422–Ein Feld verletzt seine Regel; die Antwort trägt message und errors.
404not_foundGespräch oder Aufruf unbekannt, oder der Aufruf ist keine Formularhilfe.
409not_executedDer Aufruf ist nicht im Zustand executed.

Anhänge

Besucher können Bilder und PDF-Dateien an ein Gespräch hängen, wenn der Assistent das erlaubt; eingeschaltet wird das unter Dateien vom Besucher. Wie der Besucher das im Widget erlebt, steht unter Anhänge im Gespräch. Alle drei Wege zählen neben der benannten Drossel gegen den Deckel für Aufrufe.

GrenzeWert
Größe je Datei5 MiB (5242880 Byte), mindestens 1 Byte
Anhänge je Gespräch5
Artenimage/png, image/jpeg, image/webp, application/pdf

Die Art bestimmt der Dienst am Inhalt der Datei, nicht an Endung oder Angabe des Browsers: PNG, JPEG, WebP und PDF werden an ihren ersten Bytes erkannt, alles andere wird abgewiesen. Auch die Größe misst er an der empfangenen Datei.

Anhang hochladen

POST /api/v1/public/widget/{key}/conversation/{conversation}/attachment

Nimmt eine Datei als multipart/form-data im Feld file an. Antwort 201 mit dem Anhang. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget-send, 12 je Minute je Besucher, dazu die Deckel für Aufrufe
FeldInhalt
idKennung des Anhangs (UUID)
nameBereinigter Dateiname
mimeDie am Inhalt erkannte Art
bytesGröße in Byte
sha256SHA-256 des Inhalts, hexadezimal
lead_idKennung der Anfrage, an der der Anhang hängt, oder null
timeZeitpunkt des Hochladens, ISO 8601

Vom Dateinamen entfernt der Dienst Schrägstriche, umgekehrte Schrägstriche, Anführungszeichen und Steuerzeichen, behält nur den letzten Pfadteil und kürzt auf 120 Zeichen. Bleibt nichts übrig, heißt die Datei anhang.png, anhang.jpg, anhang.webp oder anhang.pdf.

Gibt es im Gespräch schon eine Anfrage, hängt der Anhang sofort an der jüngsten; lead_id trägt dann ihre Kennung. Entsteht die Anfrage erst später, übernimmt sie alle Anhänge des Gesprächs, deren lead_id noch leer ist. Das Hochladen wird in der Regel im Aktivitätsprotokoll mit Art und Größe festgehalten; kommt dieser Eintrag nicht zustande, bleibt der Anhang trotzdem gespeichert und die Antwort ist 201.

Die Prüfungen laufen in der Reihenfolge der Tabelle; die erste, die greift, bestimmt die Antwort. Die vier Abweisungen aus der Prüfung der Datei (upload_failed, too_large, too_many und type_not_allowed) tragen zusätzlich max_bytes, types und max_per_conversation, damit das Widget dem Besucher die Grenzen nennen kann.

StatuserrorBedeutung
429–Benannte Drossel widget-send erreicht.
429too_many_requestsDeckel für Aufrufe erreicht.
403attachments_disabledDer Assistent nimmt keine Dateien an.
404not_foundGespräch unbekannt.
422consent_revokedDie Einwilligung wurde widerrufen; das Gespräch nimmt nichts mehr auf.
403blockedDie IP-Adresse des Besuchers oder dieses Gespräch ist gesperrt.
422file_missingDie Anfrage enthält keine verwertbare Datei im Feld file.
422upload_failedDie Übertragung der Datei ist gescheitert.
413too_largeDatei größer als 5 MiB oder leer.
422too_manyDas Gespräch trägt schon 5 Anhänge.
415type_not_allowedInhalt ist weder PNG, JPEG, WebP noch PDF.

anhang.sh bash

curl -X POST \
  https://app.xicbot.de/api/v1/public/widget/0123456789abcdef0123456789abcdef/conversation/9d1f6c2a-3b4e-4f5a-8c7d-1e2f3a4b5c6d/attachment \
  -F 'file=@schaden.jpg'

Anhänge auflisten

GET /api/v1/public/widget/{key}/conversation/{conversation}/attachment

Liefert {"attachments": […]} mit allen Anhängen des Gesprächs, nach Zeitpunkt aufsteigend, je Eintrag mit denselben Feldern wie beim Hochladen. Zählt gegen den Deckel für Aufrufe; ist das Gespräch unbekannt, lautet die Antwort 404 mit not_found.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe

Anhang abrufen

GET /api/v1/public/widget/{key}/conversation/{conversation}/attachment/{attachment}

Liefert die Datei selbst als Download. Der Anhang muss zu diesem Gespräch gehören. Zählt gegen den Deckel für Aufrufe.

Anmeldung
Keine
Begrenzung
widget, 60 je Minute je Besucher, dazu die Deckel für Aufrufe
KopfzeileWert
Content-TypeDie erkannte Art, sonst application/octet-stream
Content-LengthGröße in Byte
Content-Dispositionattachment mit filename in ASCII und filename* in UTF-8
X-Content-Type-Optionsnosniff
Content-Security-Policydefault-src 'none'; sandbox
Cache-Controlprivate, no-store, max-age=0
Referrer-Policyno-referrer
StatuserrorBedeutung
429too_many_requestsDeckel für Aufrufe erreicht.
404not_foundGespräch unbekannt oder der Anhang gehört nicht zu diesem Gespräch.
410file_missingDer Eintrag besteht, die Datei fehlt; die Antwort trägt zusätzlich measured gleich false.

Häufige Fragen

Warum antwortet die Schnittstelle bei einem falschen Schlüssel mit 404 und nicht mit 403?

Ein unbekannter Schlüssel, ein abgeschaltetes Widget, ein inaktiver Assistent und ein inaktives Konto sehen von außen gleich aus: 404 mit unknown_widget. Wer einen Schlüssel rät, erfährt aus der Antwort nicht, ob er richtig geraten hat. Einzige Abweichung ist eine abgelaufene Demo, die demo_expired meldet.

Warum liefert das Senden einer Frage auch bei erschöpftem Kontingent den Status 200?

Der Antwortstrom hat zu diesem Zeitpunkt schon begonnen. Das Ereignis error mit code gleich quota_exhausted meldet die Lage, danach folgen die Notfallantwort und end mit blocked. Werten Sie darum die Ereignisse aus, nicht den Status.

Was geschieht mit einer laufenden Antwort, wenn der Besucher seine Einwilligung widerruft?

Der Lauf prüft während der Antwort und an ihrem Ende, ob widerrufen wurde. Dann verwirft er die Antwort und sendet revoked und end mit revoked. Weitere Fragen und Anhänge nimmt das Gespräch nicht mehr an.

Darf die Rückmeldung zur Formularhilfe mehrfach gesendet werden?

Ja, aber nur die erste Meldung je Aufruf wird gespeichert. Jede weitere erhält duplicate gleich true und den schon gespeicherten Bericht zurück.

Schützt die Liste der erlaubten Domains vor Aufrufen außerhalb des Browsers?

Nein. Die Liste hält das Widget von fremden Seiten fern, aber host ist eine Angabe des Aufrufers. Gegen Missbrauch wirken die Drosseln, die Deckel für Aufrufe und Fragen und das Sperren einzelner Besucher.

Eine Stelle ist unklar geblieben?

Schreiben Sie uns, welche Seite und welcher Schritt gemeint ist. Wir antworten persönlich.

Anfrage in drei Schritten

  1. 1. Anliegen
  2. 2. Ihr Fall
  3. 3. Kontakt

Worum geht es?

Ein Klick genügt, alles Weitere ist freiwillig.

Erzählen Sie kurz von Ihrem Fall

Alle Angaben in diesem Schritt sind freiwillig. Sie helfen uns, gleich mit etwas Konkretem zu antworten statt mit Rückfragen.

Anfragen im Monat, ungefähr (optional)
Wann soll es losgehen? (optional)
Wie erreichen wir Sie?

Name und E-Mail-Adresse genügen. Wir antworten persönlich.

Wir verwenden Ihre Angaben, um Ihre Anfrage zu bearbeiten. Mehr dazu in der Datenschutzerklärung.