Skava Skava / Wiki

Diese Seite richtet sich an Entwickler, die das Backend einer Firma an Skava anbinden. Wie ein API-Element angelegt und freigegeben wird, steht auf der Seite Custom Elements: API-Schnittstellen; hier geht es um alles, was auf der anderen Seite der Leitung passieren muss.

Der Grundgedanke in einem Satz: Skava kennt deine Domäne nicht. Es kennt genau ein Format, die Karte. Du bestimmst, was darin steht, wir prüfen nur Form, Größe und Sicherheit. Eine Warenbestellung ist ein Beispiel, die nächste Firma fragt Nutzerfeedback ab, die übernächste schiebt ein Baustellenfoto in ihre eigene Akte.

Der Ablauf im Überblick

  1. Ein Firmen-Admin legt in Skava ein API-Element an: ein Formular plus die Adresse deines Backends, Methode und Token.
  2. Jemand im Chat füllt das Formular aus und sendet.
  3. Skava ruft dein Backend auf und schickt die ausgefüllten Werte als JSON.
  4. Deine Antwort wird zur Karte im Chat.
  5. Optional meldest du später neue Stände über den Rückkanal. Jede Meldung wird eine weitere Karte, die vorige bleibt stehen.

Anforderungen an dein Backend

  • HTTPS. Nur https://, kein http, keine Zugangsdaten in der Adresse, höchstens 2000 Zeichen.
  • Öffentlich erreichbar. Der Name muss ausschließlich auf öffentliche IPs auflösen. Localhost, private Netze, Link-Local und Cloud-Metadaten werden abgelehnt, und zwar bei jedem Aufruf neu.
  • Feste Adresse. Skava löst den Namen einmal auf und bindet die Verbindung an diese IP. Ein DNS-Wechsel mitten im Aufruf greift nicht.
  • Keine Weiterleitungen. Ein 301 auf die „richtige" Adresse gilt als Fehlschlag. Trag gleich die Zieladresse ein.
  • Antwortzeit. Das Zeitlimit ist im Element einstellbar und hart auf 30 Sekunden gedeckelt. Wer länger braucht, antwortet sofort und meldet das Ergebnis später über den Rückkanal.
  • Antwortgröße. Skava liest höchstens 256 KiB.
  • Content-Type. Nur mit application/json wird die Antwort ausgewertet.

Die Anfrage, die bei dir ankommt

Methode ist GET, POST, PUT oder PATCH, je nach Element. Bei POST, PUT und PATCH kommen die Werte als JSON-Body, bei GET als Query-Parameter.

Die Authentifizierung ist ein Header, dessen Name und Wert-Präfix im Element stehen, üblicherweise Authorization mit Präfix Bearer . Das Token liegt bei uns verschlüsselt. Nicht setzbar sind die Header host, content-length, content-type, cookie und accept-encoding.

Der Body ist ein flaches Objekt. Die Schlüssel bestimmt der Ersteller des Elements, verschachtelt wird nur, was er selbst als Tabelle oder Produktauswahl angelegt hat:

{"artikelnummer": "5100110", "menge": 20, "bemerkung": "Bitte morgens liefern", "besteller": "Jonas Berger", "firma": "Sanitär Berger GmbH", "projekt": "Spitalstraße 11", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/…", "callback_token": "…"}

Drei Schlüssel kommen immer von uns, benutze sie nicht selbst:

  • locale: Sprachcode des Nutzers. Antworte in dieser Sprache, wir übersetzen deine Texte nicht.
  • callback_url und callback_token: der Rückkanal für diesen einen Vorgang, siehe unten. Sie sind nur vorhanden, wenn der Aufruf aus einem Chat kommt.

Kontextfelder wie Name, Firma, Projekt oder Subchat füllt der Server selbst, und zwar aus dem Kanal, aus dem heraus ausgelöst wurde. Ein manipulierter Client kann dort keinen fremden Projektnamen behaupten.

Die Antwort: das Kartenformat

Antworte mit 2xx und einem Objekt card. Genau daraus entsteht die Karte im Chat:

{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "pending", "status_text": "Bestellung eingegangen", "icon": "package", "fields": [{"label": "Bestellnummer", "value": "BST-10001"}, {"label": "Voraussichtlich", "value": "14.08.2026"}]}}

  • v (Pflicht): die Ganzzahl 1. Als Text ("1") wird sie abgelehnt. Fehlt sie, gilt die Antwort nicht als Karte, und es greift die im Element hinterlegte Antwort-Zuordnung.
  • title: Überschrift der Karte.
  • state: nur Farbe und Symbolton, eine von vier Stufen ok, pending, warn, error. Ein unbekannter Wert fällt auf ok zurück und du bekommst einen Hinweis.
  • status_text: freier Text, den wir nicht bewerten. Er steht oben in der Karte und ist zugleich das, was in der Chat-Liste und in einer Push-Nachricht erscheint.
  • fields: Liste aus label und value. Höchstens 20 Einträge, label 80 Zeichen, value 200, title und status_text je 120. Zu lange Werte werden gekürzt, nicht abgelehnt: eine Bestellung soll nicht an einer Kleinigkeit scheitern.
  • icon: siehe unten.

Was Skava mit deinen Texten macht, bevor sie im Chat landen: Zeilenumbrüche und Steuerzeichen fliegen raus (ein Rechts-nach-links-Zeichen könnte sonst die Anzeige eines Betrags umdrehen), Backticks werden ersetzt, und alles, was mit [SKAVA: beginnt, wird entschärft. Letzteres verhindert, dass ein Kartenwert als anderes Chat-Element gelesen wird, etwa als Zahlungsanforderung.

Nicht setzbar sind Links in Feldern, HTML und Bilder. Ein Chat ist eine Vertrauensumgebung, und eine anklickbare Adresse aus einem fremden Backend wäre eine Einladung zum Nachbauen einer Anmeldeseite.

Die Eingaben des Nutzers gehören dem Server: sie stehen auf der ersten Karte und lassen sich von dir nicht überschreiben. Sie sind im Chat der Beleg dafür, was tatsächlich abgeschickt wurde.

Symbole

Mit icon bekommt die Karte ein eigenes Zeichen im Kopf. Zwei Wege:

Ein Name aus dem mitgelieferten Satz: package, package-check, package-open, box, boxes, truck, forklift, warehouse, settings, cog, gauge, wrench, hammer, drill, hard-hat, ruler, paint-roller, construction, clipboard-check, receipt, file-text, camera, clock, calendar-clock, circle-check, circle-alert, triangle-alert, send, mail-check, shopping-cart, credit-card, map-pin.

Oder ein eigenes SVG als Zeichenkette. Davon übernimmt Skava ausschließlich die Geometrie (path, circle, ellipse, rect, line, polyline, polygon mit ihren Zahlen-Attributen) und baut daraus ein eigenes Bild. Skript, Stil, Fremdverweise, foreignObject und Ereignis-Attribute werden verworfen, ein Dokumenttyp oder eine Entität führt zur Ablehnung, die Datei darf höchstens 8 KiB groß sein und höchstens 16 Formen enthalten. Farbe, Strichstärke und Größe bestimmt Skava, damit sich ein Symbol nicht als Bedienelement tarnen kann. Rechne mit einem 24×24-Raster.

Ohne icon bleibt es beim Standardzeichen.

Der Rückkanal: Stände nachmelden

Im Aufruf stehen callback_url und callback_token. Damit meldest du später neue Stände:

POST <callback_url> mit Authorization: Bearer <callback_token> und Content-Type: application/json, Body höchstens 32 KiB:

{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "pending", "status_text": "Versandt", "icon": "truck", "fields": [{"label": "Sendungsnummer", "value": "DPD123456789"}]}, "seq": 3, "final": false}

Neben der Karte gibt es drei optionale Werte:

  • seq: dein eigener Zähler. Eine Meldung mit kleinerem oder gleichem Wert wird verworfen, damit zwei Meldungen sich nicht überholen können. Ohne seq gewinnt die zuletzt eingetroffene.
  • final: schließt den Vorgang. Danach ist das Token ungültig und es kommen keine weiteren Karten mehr. Auch in der ersten Antwort erlaubt, für Abläufe ohne Nachmeldung.
  • notify: mit false wird die Karte still eingestellt, ohne Ungelesen-Zähler und ohne Benachrichtigung. Für Zwischenschritte, die niemanden aufwecken sollen. Ohne die Angabe ist es eine ganz normale Nachricht.

Jede Meldung wird eine eigene Karte im Chat, die vorige bleibt stehen. So ist ablesbar, wann welcher Stand gemeldet wurde. Daraus folgt eine Empfehlung: schick in einer Meldung nur, was sich geändert hat. Eine Karte, die zum vierten Mal Bestellnummer, Positionen und Summe wiederholt, ist für den Leser nur Rauschen.

Zwei Grenzen: dieselbe Meldung zweimal erzeugt keine zweite Karte, und ein Vorgang darf höchstens 50 Karten stellen. Ein Vorgang nimmt 90 Tage lang Meldungen an.

Antworten, auf die du reagieren solltest

  • 200 mit {"result": "success", "updated": true, "seq": 3, "closed": false, "hints": []}. Lies die hints: dort steht, was gekürzt oder verworfen wurde.
  • 401: Token oder Vorgangs-ID falsch. Nicht wiederholen.
  • 410: Vorgang geschlossen oder abgelaufen. Nicht wiederholen.
  • 422: Karte unbrauchbar, mit hints als Begründung. Erst korrigieren.
  • 400 kaputtes JSON, 413 zu groß, 429 zu viele Anfragen (mit Wartezeit erneut versuchen), 500 unser Fehler, später erneut versuchen.

Beispiel 1: Bestellung mit Statusverlauf

Schritt 1, die Anfrage an dein Backend:

POST https://api.example.com/v1/orders
Authorization: Bearer <dein Token>
{"artikelnummer": "5100110", "menge": 20, "besteller": "Jonas Berger", "firma": "Sanitär Berger GmbH", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/1111…", "callback_token": "geheim"}

Schritt 2, deine sofortige Antwort:

{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "pending", "status_text": "Bestellung eingegangen", "icon": "package", "fields": [{"label": "Bestellnummer", "value": "BST-10001"}, {"label": "Voraussichtlich", "value": "14.08.2026"}]}}

Im Chat steht jetzt eine Karte mit Paket-Symbol, dem Status und den Eingaben des Nutzers.

Schritt 3, später beim Kommissionieren:

POST <callback_url>{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "pending", "status_text": "Wird kommissioniert", "icon": "cog", "fields": []}, "seq": 2, "notify": false}

Eine stille zweite Karte, ohne Felder: es hat sich nur der Status geändert.

Schritt 4, beim Versand:

POST <callback_url>{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "pending", "status_text": "Versandt", "icon": "truck", "fields": [{"label": "Sendungsnummer", "value": "DPD123456789"}, {"label": "Frachtführer", "value": "DPD"}]}, "seq": 3}

Diese Karte darf ruhig aufwecken, deshalb ohne notify: false.

Schritt 5, bei der Zustellung:

POST <callback_url>{"card": {"v": 1, "title": "Bestellung BST-10001", "state": "ok", "status_text": "Zugestellt", "icon": "package-check", "fields": []}, "seq": 4, "final": true}

Mit final ist der Vorgang zu, das Token gilt nicht mehr.

Beispiel 2: eine Aktion ohne Nachmeldung

Nicht jeder Ablauf hat einen Verlauf. Ein Element mit einem einzigen Feld, das etwas an dein System übergibt, braucht nur eine Antwort:

{"card": {"v": 1, "title": "In der Akte abgelegt", "state": "ok", "status_text": "Gespeichert unter Projekt 4711", "icon": "clipboard-check", "fields": [{"label": "Vorgang", "value": "4711"}]}, "final": true}

final: true ist hier wichtig: sonst bliebe der Vorgang 90 Tage mit gültigem Token offen, obwohl du nie wieder etwas meldest.

Produktauswahl aus dem Katalog

Hat die Firma ihren Artikelkatalog hochgeladen, kann das Element den Baustein Produktauswahl enthalten. Der Nutzer stellt sich daraus einen Warenkorb zusammen, und du bekommst ihn als Liste unter dem Schlüssel, den der Ersteller vergeben hat:

{"positionen": [{"artikelnummer": "5100110", "menge": 20}, {"artikelnummer": "5100111", "menge": 2}], "bemerkung": "…"}

Weil der Schlüssel frei wählbar ist, suchst du am besten nach der ersten Liste, die so aussieht, statt nach einem festen Namen. Skava prüft vor dem Absenden, dass jede Nummer wirklich im Katalog dieser Firma steht, höchstens 50 Positionen. In der Karte erscheinen die Positionen als Liste mit Produktbild, Bezeichnung und Menge.

Testen

  • Ping im Element-Editor schickt ein reines HEAD ohne Token und ohne Daten. Antworte darauf mit irgendetwas, jede HTTP-Antwort zählt als erreichbar.
  • Test-Request feuert einen echten Aufruf mit Beispielwerten, auch solange das Element noch Entwurf ist, und zeigt Anfrage, Antwort und die Meldungen des Kartenprüfers.
  • Vorschau im Reiter daneben: Antwort-JSON einfügen, prüfen, und du siehst die fertige Karte plus die Hinweise. Geprüft wird auf dem Server mit demselben Code wie im Betrieb.
  • Beispielserver: unter api.skava.io läuft ein vollständiger Beispiel-Lieferant, der alles oben Beschriebene benutzt. Der Quelltext liegt im Repository unter example_order_server/, gut 600 Zeilen reine Standardbibliothek, gedacht zum Abschreiben.

Was du sonst wissen solltest

  • Die Karte ist eine ganz normale Chat-Nachricht. Sie taucht in der Suche auf, lässt sich zitieren und bleibt im Verlauf.
  • Abgesendet wird sie vom Systemabsender, nicht von einem Konto deiner Firma. Im Chat erscheint sie trotzdem auf der Seite dessen, der ausgelöst hat, und wessen System schreibt, steht im Titel.
  • Wer auslösen darf, steht am Element: nur Mitarbeiter der Firma, oder auch Externe, die mit ihr im selben Chat sitzen. Verlässt deine Firma den Chat, endet die Freigabe von selbst.
  • Ein API-Element mit abgelaufenem Token ist stillgelegt und erscheint gar nicht erst im Menü, bis ein Admin ein neues hinterlegt.

Verwandt

Einrichten und freigeben: Custom Elements: API-Schnittstellen. Ausfüllbare Dokumente statt Schnittstellen: Custom Elements: Dokumente.

Häufige Fragen

Welche Anforderungen hat Skava an meinen Server?

Eine öffentlich erreichbare https://-Adresse ohne Weiterleitung, Antwort in höchstens 30 Sekunden, höchstens 256 KiB, und Content-Type: application/json, damit die Antwort ausgewertet wird.

Muss ich das Kartenformat benutzen?

Nein, aber es ist der einfache Weg. Ohne card in der Antwort greift die im Element hinterlegte Antwort-Zuordnung, bei der ein Admin Pfade in deine JSON eintragen muss.

Wie melde ich einen späteren Stand?

Per POST auf die callback_url aus dem Aufruf, mit dem callback_token als Bearer. Jede Meldung wird eine neue Karte im Chat; die vorige bleibt stehen.

Wie lange gilt der Rückkanal?

90 Tage, oder bis du final: true schickst. Danach antwortet Skava mit 410.

Darf ich ein eigenes SVG als Symbol schicken?

Ja. Skava übernimmt daraus ausschließlich die Geometrie und baut das Bild selbst; Skript, Stil und Fremdverweise werden verworfen. Farbe und Größe bestimmt Skava.

Warum kommt meine Karte nicht an?

Sieh in die Antwort des Rückkanals: 422 nennt in hints den Grund, 401 heißt falsches Token, 410 heißt Vorgang geschlossen. Auch eine 200 trägt Hinweise, wenn etwas gekürzt wurde.