Entwickler-Dokumentation

Verbinden Sie Ihre eigene Software mit Ihrem SyBox-Postfach

Senden Sie WhatsApp-Nachrichten von Ihrer eigenen Nummer, zeigen Sie die Daten Ihrer Kunden neben jedem Chat an, legen Sie Fälle an, empfangen Sie jedes Ereignis auf Ihrem eigenen Server und binden Sie einen Live-Chat in Ihre Website ein. Die Senderoute verwendet das Format der WhatsApp Cloud API: Code, der für Meta geschrieben wurde, braucht nur eine neue Basis-URL und einen SyBox-Schlüssel.

Basis-URLhttps://api.sybox.io

Erste Schritte

Schnellstart

Drei Dinge und Ihre erste Nachricht ist unterwegs: die Basis-URL, ein Geräteschlüssel und der Nachrichten-Endpunkt.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>

Das Versionssegment wird in jeder v<n>-Form akzeptiert (v26.0, v1.0, …) — behalten Sie die bei, die Ihr bisheriger Code verwendet. Die {phone-number-id} ist die ID Ihrer WhatsApp-Nummer, genau wie bei Meta.

Die {phone-number-id} steht nach id auf der Karte der Nummer unter Einstellungen › Messaging › Kanäle. Ein Sendeschlüssel ist an eine Nummer gebunden und sendet nur von ihr.

cURL
curl -X POST https://api.sybox.io/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

Die Karte jedes Schlüssels unter Einstellungen › Integrationen › API-Schlüssel zeigt, wann er zuletzt verwendet wurde – so sehen Sie am schnellsten, ob Ihre Aufrufe ankommen.

Erste Schritte

Authentifizierung und Schlüssel

Jeder Aufruf enthält einen Schlüssel im Header Authorization als Bearer-Token. Jeder Schlüssel hat genau eine Aufgabe: Ein Schlüssel zum Senden kann keinen Fall anlegen, und ein Schlüssel zum Anlegen von Fällen kann nicht senden. Bewahren Sie jeden Schlüssel auf Ihrem Server auf – die einzige Ausnahme ist der öffentliche Live-Chat-Schlüssel, der für Ihre Seiten gedacht ist.

HTTP
Authorization: Bearer YOUR_KEY
Content-Type: application/json
SchlüsselVerwendungszweck
Über WhatsApp sendenPOST /v{n}/{phone-number-id}/messages
Fall anlegenPOST /v1/case
Automatisierung startenPOST /v1/automation
Kontakte lesen und aktualisierenPOST /v1/contacts/…
Von einem Programm empfangenPOST /v1/inbound
Öffentlicher Schlüssel · lcpk_<script … data-key="lcpk_…">
Signaturschlüssel für angemeldete Benutzer · lcid_Angemeldete Benutzer: der Signaturschlüssel
Serverschlüssel (für Ihren eigenen Chat-Bildschirm) · lcsk_/v1/livechat/*
Signaturschlüssel für Antworten · lcwh_x-sybox-signature
SignaturschlüsselX-Hub-Signature-256

Erste Schritte

Geräteschlüssel erhalten

Schlüssel werden in Ihrem Arbeitsbereich erstellt.

  1. Öffnen Sie Ihren Arbeitsbereich → Einstellungen → API-Schlüssel.
  2. Jeder Schlüssel ist an eine Nummer gebunden und kann jederzeit widerrufen werden.
  3. Ihr reales WhatsApp-Token verlässt niemals unseren Server.
  4. Das Gateway ist standardmäßig deaktiviert.

WhatsApp API

Senden Sie Ihre erste Nachricht

Eine reine Textnachricht. Der Body entspricht der Standard-Cloud-API.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>
curl -X POST https://api.sybox.io/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

Die Antwort

Sie erhalten genau das zurück, was Meta zurückgibt, mit demselben HTTP-Status.

200 OK · application/json
{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "15551234567", "wa_id": "15551234567" }],
  "messages": [{ "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgARGBI…" }]
}

WhatsApp API

Jeder Nachrichtentyp funktioniert

Da der Body unverändert weitergeleitet wird, werden alle Cloud-API-Nachrichtentypen unterstützt.

{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "name": "order_shipped",
    "language": { "code": "en_US" },
    "components": [{
      "type": "body",
      "parameters": [{ "type": "text", "text": "#10432" }]
    }]
  }
}

Freier Text erreicht einen Kunden nur innerhalb von 24 Stunden nach seiner letzten Nachricht. Außerhalb dieses Zeitfensters senden Sie eine genehmigte Vorlage: SyBox lehnt freien Text dort mit dem Code 131047 ab, bevor er Meta erreicht.

WhatsApp API

Schlüsselregeln und Limits

Jeder Sendeschlüssel hat eigene Regeln, die Sie beim Erstellen festlegen: freier Text, Vorlagen oder beides; Medien oder nicht; welche Vorlagen; welche Empfängerländer; zu welchen Uhrzeiten er senden darf; und ein Tageslimit. Verstößt ein Sendevorgang gegen eine davon, lehnt SyBox ihn ab, bevor er Meta erreicht.

StatusWann
404Eine leere Antwort: Das API-Gateway ist ausgeschaltet, oder der Schlüssel gehört zu keinem Workspace. Prüfen Sie den Schalter oben unter Einstellungen › Integrationen › API-Schlüssel.
401Der Schlüssel fehlt oder ist unbekannt.
403Der Schlüssel ist kein Sendeschlüssel oder sendet von einer Nummer, an die er nicht gebunden ist.
403Die Nachricht verstößt gegen eine Regel des Schlüssels: freier Text, Vorlagen, Medien, der Name der Vorlage, das Land oder die Uhrzeiten.
403Meta hat die Vorlage pausiert oder wegen ihrer Qualitätsbewertung eingeschränkt.
400Das 24-Stunden-Fenster ist geschlossen (Code 131047): Senden Sie stattdessen eine Vorlage.
400Der Body ist kein gültiges JSON, oder die WhatsApp-Nummer des Schlüssels ist nicht mehr verbunden.
409Meta hat das Senden von dieser Nummer vorübergehend gestoppt.
429Das Tageslimit des Schlüssels oder das WhatsApp-Messaging-Limit der Nummer ist erreicht.
502Meta war nicht erreichbar. Versuchen Sie es erneut.

Die Tageszählung beginnt um Mitternacht UTC neu, und ein fehlgeschlagener Sendevorgang wird nicht gezählt.

WhatsApp API

Fehler

Fehler kommen aus zwei Quellen, und beide verwenden das Fehlerformat von Meta, sodass ein bestehender Cloud API-Client sie unverändert lesen kann. Ein Fehler von Meta kommt genau so zurück, wie Meta ihn gesendet hat, mit dem Statuscode von Meta. Ein Fehler aus einer der eigenen Regeln von SyBox hat den type SyBoxGatewayError, und seine message nennt die Regel, die den Aufruf abgelehnt hat.

{
  "error": {
    "message": "(#131030) Recipient phone number not in allowed list",
    "type": "OAuthException",
    "code": 131030
  }
}

Ihr System in SyBox

Zeigen Sie Ihre Daten neben dem Chat an

Wenn ein Mitarbeiter einen Chat öffnet, ruft SyBox IHREN Endpunkt auf und zeigt die Daten direkt neben dem Chat an.

Fügen Sie Ihren Endpunkt unter Einstellungen › Integrationen › ERP APIs hinzu. Jeder Aufruf ist ein POST mit Ihrem Schlüssel in Authorization und der Anfrage in einem einzigen Feld, data, das einen JSON-String enthält – so kann jede Seite später Felder hinzufügen, ohne die andere zu beeinträchtigen. Antworten Sie innerhalb von 15 Sekunden.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: lookup
X-Sybox-Lang: en
X-Sybox-Theme: light
X-Sybox-Agent: 6f1c…
X-Sybox-Number: 104857600000000
Content-Type: application/json

{ "data": "{\"phone\":\"15551234567\",\"email\":\"customer@example.com\",\"ref\":\"\"}" }

Jeder Aufruf gibt außerdem an, wer fragt: X-Sybox-Lang (die Sprache des Benutzers – antworten Sie in dieser Sprache), X-Sybox-Theme (light oder dark, für eine html-Antwort), X-Sybox-Agent (die ID des Benutzers) und X-Sybox-Number (die Leitung, auf der die Konversation läuft).

Wir senden Telefon und E-Mail — antworten Sie mit { renderAs, content }.

renderAs

Legen Sie renderAs fest, um SyBox mitzuteilen, wie Ihr Inhalt dargestellt werden soll:

renderAsBeschreibung
tableZeilen und Spalten. content ist ein Array flacher Objekte (oder { rows: [ … ] }); ihre Schlüssel werden zu den Spaltenüberschriften.
cards · kpiKleine Kacheln, etwa ein Kontostand oder eine Anzahl von Bestellungen. content ist ein Array von { label, value } (oder { cards: [ … ] }).
feed · list · threadEine Zeitleiste aus Karten. content ist ein Array von { title, text, date, tags, media: [{ type, url, name }] }.
messageEin einzelner Datensatz, dargestellt als eine Karte im Stil einer Nachricht.
htmlIhr eigenes HTML, als String in content. Nur für Markup, das Sie selbst erzeugen.
sectionsMehrere Blöcke in einer Antwort: content ist { sections: [ { title, renderAs, content } ] }.
jsonDie Standardeinstellung, wenn renderAs fehlt: SyBox zeigt Ihren content als formatiertes JSON an.

Fügen Sie sybox_ref zu jeder Tabellenzeile hinzu, um sie anklickbar zu machen.

Produktsuche (X-Sybox-Action: products)

Derselbe Endpunkt kann auch Produktsuchen beantworten. Der Benutzer gibt ein, wonach der Kunde fragt, SyBox sendet dies als "q", und Ihre Antwort wird als Produktkarten neben dem Chat dargestellt – mit einem Ein-Klick-Senden, das den Produktlink in das Eingabefeld einfügt.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: products

# the decoded "data":
{ "q": "wireless keyboard", "phone": "15551234567", "email": "customer@example.com", "ref": "" }
FeldBeschreibung
nameerforderlichDas einzige Pflichtfeld. Ein Produkt mit nur einem Namen ergibt trotzdem eine saubere Karte.
price · oldPrice · currencyZahlen, keine formatierten Zeichenketten. Senden Sie oldPrice nur, wenn es einen echten früheren Preis gibt — der Rabatt wird aus beiden berechnet.
available · stockavailable ist true/false; stock ist eine optionale Anzahl daneben. Lassen Sie beide weg, wenn Sie keinen Bestand führen — ein fehlendes Feld zeichnet nichts und wird nie als «nicht verfügbar» gelesen.
imageEine direkte https-Bild-URL. Was nicht lädt, weicht einem neutralen Hintergrund.
linkDie URL der Produktseite. Ohne sie ist die Karte nur lesbar — Senden erscheint nur, wenn es etwas zu senden gibt.
noteEine kurze freie Zeile unter dem Preis — Lieferzeit, Variante, Bedingung.

Nichts außer dem Endpunkt, den Sie bereits haben: dieselbe URL, derselbe Schlüssel, dieselbe { "data": "…" }-Hülle. Unterscheiden Sie über X-Sybox-Action zwischen Produktsuche und Kundenabfrage. Antworten Sie mit content als einfachem Array (oder { items: [ … ] }).

Ihr System in SyBox

Erstellen Sie ein Ticket aus Ihrem eigenen System

Verwenden Sie diese Route für ERP- oder Buchhaltungssysteme zur Erstellung zentraler Support-Tickets.

POST/v1/caseAuthorization: Bearer <CASE_KEY>
curl -X POST https://api.sybox.io/v1/case \
  -H "Authorization: Bearer $SYBOX_CASE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_unique_id": "CUST-10432",
    "header": "Screen replacement not delivered",
    "description": "Paid on 12 Aug, promised in 3 days, still nothing.",
    "department_id": 5,
    "ext_ref": "TICKET-99817"
  }'

Die Felder

FeldBeschreibung
customer_unique_idIhre eigene ID für den Kunden – derselbe Schlüssel, den die Kundensynchronisierung verwendet. Senden Sie stattdessen phone, wenn Sie keine ID haben.
phoneDie Telefonnummer des Kunden, wenn Sie keine ID haben.
header · descriptionMindestens eine Angabe ist erforderlich. Die Kopfzeile ist die Zeile, die Benutzer in der Liste sehen.
department_iderforderlichintegerErforderlich. Die Abteilung, der der Fall zugeordnet ist: die daneben angezeigte Nummer in Einstellungen › Abteilungen (zum Beispiel #5).
ext_refIhre Ticketnummer.
sectioninteger1 bis 4: in welchen Tab der Fälle er kommt. Standard: 1.
deadlinestringEin Fälligkeitsdatum, YYYY-MM-DD.
notifybooleanStandard: true – in der Konversation des Kunden in SyBox erscheint eine Notiz mit der Fallnummer. An den Kunden wird nichts gesendet. false lässt die Notiz weg.
sourcestringDer Name des Programms, der auf dieser Notiz angezeigt wird. Standard: ERP.

Die Antwort enthält die Nummer des Falls – die Nummer, die Ihre Mitarbeiter dem Kunden nennen. Ein erneuter Versuch mit derselben ext_ref antwortet mit "duplicate": true und dem bereits vorhandenen Fall, ohne customer_id.

Der Kunde muss bereits in SyBox vorhanden sein. Wird die ID nicht gefunden, führt SyBox einmal die Kundensynchronisierung mit Ihrem System aus und sucht erneut; wird sie dann immer noch nicht gefunden, lautet die Antwort 404 – nie ein Fall für einen erfundenen Kunden.

Verwenden Sie einen Schlüssel vom Typ 'case'.

Ihr System in SyBox

Nachrichten aus anderen Programmen übertragen

Für externe Systeme (Kassensysteme, Gerätealarme, Altsysteme).

POST/v1/inboundAuthorization: Bearer <INBOUND_KEY>

Schlüssel dieser Art werden nicht mehr erstellt: Ein vorhandener Schlüssel vom Typ Von einem Programm empfangen funktioniert weiterhin. Legen Sie für eine neue Integration einen Fall an – SyBox schreibt die Notiz für Sie in die Konversation.

cURL
curl -X POST https://api.sybox.io/v1/inbound \
  -H "Authorization: Bearer $SYBOX_INBOUND_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "15551234567",
    "text": "Order 4821 has left the warehouse.",
    "source": "Warehouse"
  }'
FeldBeschreibung
phoneerforderlichstringDie Telefonnummer des Kunden, mit Ländervorwahl.
texterforderlichstringDie Nachricht.
sourcestringDer Name des Programms, der auf der Nachricht angezeigt wird.

Die Antwort ist {"ok": 1, "id": …}, die ID der Notiz in der Konversation.

Nur für eingehende Daten im Chat-Verlauf.

Ihr System in SyBox

Kontakte: lesen und aktualisieren

Mit einem Schlüssel vom Typ Kontakte lesen und aktualisieren kann ein Programm einen Kontakt suchen, lesen sowie dessen Namen, E-Mail-Adresse, Kontaktfelder und Labels ändern. Jeder Aufruf ist ein POST mit einem JSON-Body.

Der Schlüssel handelt im Namen der Person, die ihn erstellt hat: Er findet nur die Kontakte, die diese Person sehen darf, und nur dann, wenn sie die Kontaktliste öffnen und Telefonnummern einsehen darf. Um etwas zu ändern, muss diese Person berechtigt sein, Kontakte zu bearbeiten. Ein Schlüssel, dessen Ersteller deaktiviert wurde, funktioniert nicht mehr.

POST/v1/contacts/searchAuthorization: Bearer <CONTACTS_KEY>

Findet Kontakte, deren Name, Telefonnummer oder E-Mail-Adresse q enthält. limit ist standardmäßig 20, höchstens 50.

POST/v1/contacts/get

Ein einzelner Kontakt, über phone oder über key (derselbe contact.key, den ein Webhook sendet).

POST/v1/contacts/update

Ändert nur das, was Sie senden: name, email und fields (Kontaktfelder nach ID oder Name mit ihren Werten; ein leerer Wert löscht das Feld).

POST/v1/contacts/labels

Fügt Labels nach ID oder Name hinzu und entfernt sie: add und remove sind Listen.

curl -X POST https://api.sybox.io/v1/contacts/update \
  -H "Authorization: Bearer $SYBOX_CONTACTS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "201112223344",
    "name": "Sara Ali",
    "fields": { "city": "Alexandria" }
  }'

# Find:   POST /v1/contacts/search  {"q": "sara", "limit": 20}
# Read:   POST /v1/contacts/get     {"phone": "201112223344"}
# Labels: POST /v1/contacts/labels  {"phone": "201112223344", "add": ["VIP"], "remove": [7]}

Jeder Aufruf antwortet mit dem Kontakt (search: einer Liste davon): key, name, phone, email, channel, labels und fields.

Ereignisse

Webhooks: Ereignisse auf Ihrem Server

Fügen Sie Ihren Endpunkt unter Einstellungen › Integrationen › Webhooks hinzu, wählen Sie die Ereignisse und die Nummern aus, und SyBox sendet jedes Ereignis per POST an ihn, sobald es eintritt. Ein WhatsApp-Ereignis kommt im Webhook-Format von Meta an, sodass ein für Meta geschriebener Handler unverändert funktioniert.

EreignisBeschreibung
messageEingehende NachrichtEine Nachricht eines Kunden.
statusNachrichtenstatusGesendet, zugestellt, gelesen oder fehlgeschlagen – für eine Nachricht, die Sie gesendet haben.
reactionReaktionEin Kunde hat auf eine Nachricht reagiert.
doneUnterhaltung als erledigt markiertEine Unterhaltung wurde als erledigt markiert: von einer Person, durch eine Automatisierung oder automatisch nach Schweigen des Kunden.
labelLabel hinzugefügt oder entferntEin Label wurde zu einer Unterhaltung hinzugefügt oder daraus entfernt.
contactKontakt erstellt oder aktualisiertEin Kontakt wurde erstellt oder sein Name, seine E-Mail-Adresse oder seine Kontaktfelder wurden geändert.
dealDeal abgeschlossenIn einer Unterhaltung wurde ein abgeschlossener Deal erfasst.
caseCRM-Fall geöffnet oder geschlossenEin CRM-Fall wurde geöffnet oder geschlossen (gelöst, nicht gelöst oder abgebrochen).
Anfrage · SyBox → Sie
POST YOUR_WEBHOOK_URL
Content-Type: application/json
X-Hub-Signature-256: sha256=5d1f0c…
x-sybox-signature: sha256=5d1f0c…
x-sybox-event: message
x-sybox-timestamp: 1761400000

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WABA_ID",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "display_phone_number": "15550001111", "phone_number_id": "PHONE_NUMBER_ID" },
        "contacts": [{ "profile": { "name": "Sara" }, "wa_id": "15551234567" }],
        "messages": [{
          "from": "15551234567",
          "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgASGBQ…",
          "timestamp": "1761400000",
          "type": "text",
          "text": { "body": "Is my order shipped?" }
        }]
      }
    }]
  }]
}

Medien. Der Link von Meta lässt sich nur mit einem Meta-Token öffnen. Deshalb ersetzt SyBox ihn durch einen signierten Link zu seiner eigenen Kopie der Datei, gültig für 24 Stunden. Eine Sprachnachricht kann außerdem ihren Text in sybox.transcription mitliefern, wenn der Webhook ihn anfordert.

Andere Kanäle – Messenger, Instagram, Telegram und Live-Chat – kommen im eigenen Format von SyBox an, nur für das Nachrichtenereignis:

JSON
{
  "object": "sybox",
  "event": "message",
  "channel": "telegram",
  "line": "8123456789",
  "workspace": "yourworkspace",
  "contact": { "key": "tg:6423115118", "name": "Sara" },
  "message": {
    "id": "812345",
    "timestamp": 1761400000,
    "type": "image",
    "text": "",
    "caption": "The broken part",
    "media": { "url": "https://api.sybox.io/…", "mime": "image/jpeg" }
  }
}

Unterhaltungsereignisse kommen für jeden Kanal im eigenen Format von SyBox an. event gibt genau an, was passiert ist:

Ereignis<code>event</code>
Unterhaltung als erledigt markiertconversation.done
Label hinzugefügt oder entferntlabel.added · label.removed
Kontakt erstellt oder aktualisiertcontact.created · contact.updated
Deal abgeschlossendeal.closed
CRM-Fall geöffnet oder geschlossencase.opened · case.closed
Testereignistest
{
  "object": "sybox",
  "event": "conversation.done",
  "channel": "whatsapp",
  "line": "201001234567",
  "workspace": "yourworkspace",
  "timestamp": 1761400000,
  "contact": {
    "key": "201112223344",
    "name": "Sara",
    "phone": "201112223344",
    "email": "",
    "channel": "whatsapp",
    "labels": [{ "id": 3, "name": "VIP" }],
    "fields": [{ "id": 2, "key": "city", "name": "City", "value": "Cairo" }]
  },
  "data": { "by": "Omar", "note": "Refund sent" }
}

Signaturschlüssel

HeaderBeschreibung
X-Hub-Signature-256sha256= und der hexadezimale HMAC-SHA256 des unveränderten Bodys, berechnet mit dem Signatur-Secret des Webhooks – derselbe Header und dieselbe Methode wie bei Meta.
x-sybox-signatureDerselbe Wert, damit ein Endpunkt, der auch Aufrufe direkt von Meta empfängt, unsere davon unterscheiden kann.
x-sybox-eventWas passiert ist: message, status, reaction, eines der unten aufgeführten Unterhaltungsereignisse (conversation.done, label.added…) oder test.
x-sybox-timestampWann es gesendet wurde, in Unix-Sekunden.
x-sybox-signature-rsaEine zweite Signatur: rsa-sha256= und die Base64-codierte RSA-SHA256-Signatur (PKCS#1 v1.5) von x-sybox-timestamp, einem Punkt und dem unveränderten Body.
x-sybox-key-idWelcher unserer Schlüssel sie erstellt hat. Der öffentliche Schlüssel liegt unter https://api.sybox.io/.well-known/sybox-webhook-key.

Prüfen Sie die Signatur anhand der unveränderten Bytes, bevor Sie sie parsen, und vergleichen Sie in konstanter Zeit:

const crypto = require('crypto');

// express.raw: the signature is over the bytes as sent, so read them before any JSON parser.
app.post('/sybox/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sent = Buffer.from(req.get('X-Hub-Signature-256') || '');
  const want = Buffer.from('sha256=' + crypto
    .createHmac('sha256', process.env.SYBOX_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex'));
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);                       // answer first, then do the work
  const event = JSON.parse(req.body);
  const kind = req.get('x-sybox-event');     // message | status | reaction
});

Sie möchten kein gemeinsames Secret auf Ihrem Server speichern? Prüfen Sie stattdessen x-sybox-signature-rsa mit unserem öffentlichen Schlüssel. Lehnen Sie in beiden Fällen einen Zeitstempel ab, der älter als fünf Minuten ist.

Antworten Sie innerhalb von 15 Sekunden mit einem beliebigen 2xx-Code. Alles andere – ein Fehler, eine Zeitüberschreitung, eine Weiterleitung – wird nach 1, 2, 4, 8, 16 und 32 Minuten erneut versucht und dann verworfen. Ein Ereignis kann mehr als einmal ankommen: Verwenden Sie die ID der Nachricht, um eine Wiederholung zu ignorieren. Die Adresse muss öffentlich sein und https verwenden.

Ein Webhook, der über mehr als eine Stunde 20-mal in Folge fehlschlägt, wird automatisch ausgeschaltet und der Workspace-Administrator wird benachrichtigt. Seine wartenden Ereignisse werden 24 Stunden lang aufbewahrt: Schalten Sie ihn wieder ein, um sie zu senden.

Klicken Sie zum Testen auf der Karte des Webhooks auf Testereignis senden. Unter Zustellungen auf derselben Karte werden die letzten 50 Zustellungen samt der Antwort Ihres Servers aufgelistet, und Sie können eine Zustellung erneut senden.

Live-Chat

Live-Chat

Binden Sie einen Chat in Ihre Website ein: Besucher schreiben dort, Ihr Team antwortet in SyBox. Fügen Sie die Website unter Einstellungen › Messaging › Kanäle auf der Karte Live-Chat hinzu; das Fenster, das sich öffnet, Code für Ihre Website, enthält den Code und die unten beschriebenen Schlüssel. Die drei geheimen Schlüssel werden nur einmal angezeigt.

SchlüsselBeginnt mitVerwendungszweck
Öffentlicher Schlüssellcpk_Kommt in Ihre Seiten. Kann bedenkenlos veröffentlicht werden: Er benennt nur die Website, und der Chat erscheint nur auf Ihren Website-Adressen.
Signaturschlüssel für angemeldete Benutzerlcid_Nur auf Ihrem Server. Signiert jeden angemeldeten Benutzer, damit niemand im Namen eines anderen schreiben kann.
Serverschlüssel (für Ihren eigenen Chat-Bildschirm)lcsk_Nur auf Ihrem Server. Nur für eine Website, die statt des fertigen Chats einen eigenen Chat-Bildschirm baut.
Signaturschlüssel für Antwortenlcwh_Nur auf Ihrem Server. Belegt, dass eine an Ihren Server gesendete Antwort von SyBox stammt.

Der fertige Chat braucht nur den Code. Der Signaturschlüssel ist für eine Website mit Benutzerkonten; der Serverschlüssel und der Signaturschlüssel für Antworten nur für eine Website mit eigenem Chat-Bildschirm.

Wenn Sie eine Website ausschalten, wird der Chat sofort ausgeblendet. Die Aufrufe Ihres Servers werden weiterhin angenommen und gespeichert.

Den Chat in Ihre Website einbinden

Fügen Sie den Code einmal in jede Seite ein, direkt vor dem schließenden body-Tag. Der Chat erscheint nur auf den Adressen unter Website-Adressen, und Farbe, Position, Titel und Begrüßung legen Sie in SyBox fest, nicht im Code.

HTML
<script async src="https://api.sybox.io/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

WordPress: Laden Sie unser Plugin im selben Fenster herunter. Shopify: Aktivieren Sie in der Shopify-App von SyBox Live-Chat in diesem Shop und danach SyBox Live Chat unter App-Einbettungen – ein angemeldeter Kunde wird erkannt, ohne dass Sie etwas weiter tun müssen.

Angemeldete Benutzer: der Signaturschlüssel

Wenn ein Benutzer auf Ihrer Website angemeldet ist, teilt Ihr Server dem Chat mit einem kurzen Token – einem JWT, HS256 –, das mit dem Signaturschlüssel signiert ist, mit, wer er ist. Der Benutzer hat dann eine Konversation unter seinem Namen, auf jedem Gerät, und niemand kann sie öffnen, indem er die ID eines anderen eingibt.

  1. Nach der Anmeldung erstellt Ihr Server das Token aus den unten aufgeführten Claims.
  2. Die Seite übergibt es dem Chat als identity, vor dem Code des Chats.
  3. Nach einer Anmeldung ohne Neuladen der Seite rufen Sie stattdessen SyBoxChat('identify', token) auf.
FeldBeschreibung
suberforderlichstringDie ID Ihres Benutzers, bis zu 120 Zeichen. Sie darf nicht mit v_ beginnen.
experforderlichnumberAblaufzeit in Unix-Sekunden – höchstens einen Tag im Voraus. Zehn Minuten sind passend: Das Token wird nur beim Öffnen des Chats gelesen.
namestringDer Name, den die Konversation anzeigt.
emailstringDie E-Mail-Adresse des Benutzers.
phonestringDie Telefonnummer des Benutzers.
picturestringEine https-Adresse des Fotos des Benutzers, bis zu 500 Zeichen. SyBox speichert eine eigene Kopie und lädt das Foto bei der nächsten Anmeldung erneut, wenn sich die Adresse geändert hat.
function b64url(string $s): string { return rtrim(strtr(base64_encode($s), '+/', '-_'), '='); }

$header  = b64url(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
$payload = b64url(json_encode([
    'sub'   => (string) $user->id,
    'name'  => $user->name,
    'email' => $user->email,
    'exp'   => time() + 600,          // ten minutes
]));
$signature = b64url(hash_hmac('sha256', "$header.$payload", getenv('SYBOX_LC_SIGNING_KEY'), true));
$token = "$header.$payload.$signature";
HTML
<script>
  window.SyBoxChatConfig = { identity: "TOKEN_FROM_YOUR_SERVER", locale: "en" };
</script>
<script async src="https://api.sybox.io/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

Erstellen Sie das Token nur auf Ihrem Server. Ein Signaturschlüssel in einer Webseite ermöglicht es jedem, im Namen jedes Ihrer Benutzer zu schreiben. Und setzen Sie nie eine bloße Benutzer-ID anstelle des Tokens in die Seite: Damit könnte jeder wählen, wessen Konversation er liest.

Wenn Nur angemeldete Benutzer meiner Website aktiviert ist, sieht ein Besucher ohne Token den Chat nicht.

Ein Besucher, der vor der Anmeldung gechattet hat, wird einmal im selben Browser gefragt, ob er diese Konversation mit seinem Konto fortsetzen möchte. Dafür müssen Sie nichts tun.

Den Chat von Ihrer Seite aus steuern

Der Code des Chats fügt Ihrer Seite eine Funktion hinzu, SyBoxChat:

JavaScript
SyBoxChat('open');                       // open the chat
SyBoxChat('close');                      // close it
SyBoxChat('identify', token);            // after a sign-in without a page reload
SyBoxChat('locale', 'fr');               // the chat's language
SyBoxChat('on', 'message', function (m) {
  // a reply arrived
});
SyBoxChat('on', 'open', function () { /* the chat opened */ });
SyBoxChat('on', 'close', function () { /* the chat closed */ });

// Before the chat's code, every setting is optional:
window.SyBoxChatConfig = {
  identity: 'TOKEN_FROM_YOUR_SERVER',    // a signed-in user (see above)
  name: 'Sara', email: 'sara@example.com', // a visitor without an account: fills the form for them
  locale: 'ar',
  serviceWorker: 'auto'                   // 'auto' | '/your-sw.js' | 'site' | 'off'
};

Benachrichtigungen, nachdem Ihre Website geschlossen wurde

Solange eine Seite Ihrer Website geöffnet ist, erscheint eine Antwort von selbst als Benachrichtigung. Um einen Besucher zu erreichen, nachdem Ihre Website geschlossen wurde, verlangen Browser einen Service Worker auf Ihrer eigenen Domain: Stellen Sie diese eine Zeile als /sybox-lc-sw.js im Stammverzeichnis Ihrer Website bereit, als application/javascript.

/sybox-lc-sw.js
try { importScripts('https://api.sybox.io/lc/sw.js'); } catch (e) {}

Wählen Sie den Modus in SyBox (Benachrichtigungen bei geschlossener Website) oder in der Seite mit serviceWorker: "auto" (die Datei oben, die Standardeinstellung), ein eigener Pfad, "site" (dieselbe Zeile ganz oben in Ihren eigenen Service Worker setzen) oder "off".

Der Chat ersetzt nie einen Service Worker, den Ihre Website bereits hat, und die Datei hat keinen Fetch-Handler, sieht also nie eine Anfrage Ihrer Website. Das WordPress-Plugin stellt die Datei für Sie bereit. Safari auf dem iPhone zeigt für eine normale Website keine Benachrichtigungen an.

Ihr eigener Chat-Bildschirm: der Serverschlüssel

Eine Website oder App mit eigenem Chat-Bildschirm kommuniziert von ihrem Server aus mit SyBox, statt den fertigen Chat zu verwenden. Jeder Aufruf enthält Authorization: Bearer lcsk_…. Ihr Server benennt den Benutzer mit Ihrer eigenen ID, und ihm wird dabei vertraut, weil er den Schlüssel besitzt.

AufrufBeschreibung
POST /v1/livechat/messagesIhr Benutzer schreibt. client_id macht einen erneuten Versuch sicher: Dieselbe ID wird nur einmal gespeichert ("duplicate": 1).
POST /v1/livechat/uploadEine Datei, als Multipart-Formulardaten: file, user_id, client_id. Bis zu 16 MB: Bilder, Sprachnachrichten, Videos, PDF, Text und Office-Dokumente.
GET /v1/livechat/messages?user_id=&since=&before=&limit=Die Konversation: die Nachrichten nach since und agents_read_id, die neueste Nachricht Ihres Benutzers, die ein Agent gelesen hat.
POST /v1/livechat/readIhr Benutzer hat die Antworten bis up_to gelesen.
POST /v1/livechat/editIhr Benutzer bearbeitet seine eigene Nachricht, innerhalb von 15 Minuten.
POST /v1/livechat/deleteIhr Benutzer löscht seine eigene Nachricht für alle, innerhalb von 24 Stunden.
POST /v1/livechat/reactEine Reaktion auf eine beliebige Nachricht; ein leeres emoji entfernt sie.
POST /v1/livechat/typingIhr Benutzer tippt: Senden Sie alle paar Sekunden on: 1 und on: 0, wenn er aufhört.
curl -X POST https://api.sybox.io/v1/livechat/messages \
  -H "Authorization: Bearer $SYBOX_LC_SERVER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user":    { "id": "u42", "name": "Sara Ali", "email": "sara@example.com", "locale": "ar" },
    "message": { "client_id": "a1b2c3", "text": "Hi, is my order on its way?", "reply_to": "" }
  }'

Eine Nachricht, im Verlauf und in Antworten:

JSON
{
  "id": 990,
  "guid": "b81d…",
  "dir": "out",                       // "in" = your user wrote it, "out" = your team
  "type": "image",                    // text | image | audio | video | file
  "text": "Here is the tracking page",
  "media": { "url": "https://api.sybox.io/…", "mime": "image/png", "name": "tracking.png", "w": 1080, "h": 720 },
                                       // a voice note or a video also has "secs"
  "status": 3,                         // on your user's messages: 1 received, 3 read by an agent
  "reply_to": "7c9e…",
  "client": "a1b2c3",                  // on your user's messages: the client_id you sent
  "react_us": "",                      // your team's reaction on it
  "react_me": "👍",                    // your user's reaction on it
  "at": "2026-10-25T09:41:07Z",
  "edited": 0
}

Der Verlauf eines Benutzers, der noch nie geschrieben hat, antwortet mit 404 unknown_user: Zeigen Sie eine leere Konversation an.

Medienlinks sind signiert und eine Stunde lang gültig; fordern Sie danach einen neuen an. SyBox lädt nie eine Datei von einer Adresse, die Sie senden: Laden Sie sie hoch. Bis zu 120 Aufrufe pro Minute und Website.

Antworten auf Ihrem Server: der Signaturschlüssel für Antworten

Tragen Sie bei der Website die Serveradresse für Antworten ein. Wenn Ihr Team antwortet, bearbeitet, löscht oder liest, sendet SyBox das Ereignis per POST dorthin, signiert mit dem Signaturschlüssel für Antworten.

HeaderBeschreibung
x-sybox-signaturet=TIMESTAMP,v1=SIGNATURE – TIMESTAMP in Unix-Sekunden, SIGNATURE der hexadezimale HMAC-SHA256 von TIMESTAMP.BODY (dem unveränderten Body), berechnet mit dem Signaturschlüssel für Antworten.
x-sybox-eventmessage.created, message.updated, message.deleted oder messages.read.
x-sybox-deliveryBei jedem erneuten Versuch desselben Ereignisses gleich: Verwenden Sie ihn, um eine Wiederholung zu ignorieren.

Der Body enthält event, line_id, user_id und message – oder message_id bei einer Löschung und read_id bei messages.read: Die Nachrichten Ihres Benutzers sind bis zu dieser ID gelesen.

const crypto = require('crypto');

app.post('/sybox/livechat', express.raw({ type: 'application/json' }), (req, res) => {
  const parts = Object.fromEntries((req.get('x-sybox-signature') || '').split(',').map(p => p.split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(401);   // older than five minutes

  const want = Buffer.from(crypto.createHmac('sha256', process.env.SYBOX_LC_REPLY_KEY)
    .update(t + '.').update(req.body).digest('hex'));
  const sent = Buffer.from(parts.v1 || '');
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);
  const delivery = req.get('x-sybox-delivery');   // seen it already? ignore
  const evt = JSON.parse(req.body);               // { event, line_id, user_id, message | message_id | read_id }
});

Prüfen Sie die Signatur anhand des unveränderten Bodys, lehnen Sie ein t ab, das älter als fünf Minuten ist, und antworten Sie schnell mit 2xx. Alles andere wird nach 10 s, 30 s, 2 min, 10 min und 30 min erneut versucht und dann verworfen. SyBox ruft nur öffentliche Adressen auf und folgt nie einer Weiterleitung.

Fehlercodes

Jede Antwort des Live-Chats ist JSON – {"ok": 1, …} oder {"ok": 0, "error": "CODE"} mit einem Code statt eines Satzes:

CodeStatusBeschreibung
unauthorized401Der Serverschlüssel ist falsch oder wurde ersetzt.
invalid_json invalid_payload invalid_user_id400Die Anfrage hat nicht das erwartete Format.
empty_message no_file empty_file400Kein Text und keine Datei.
too_long400Der bearbeitete Text ist länger als 4.096 Zeichen.
not_an_emoji400emoji ist kein Emoji.
not_found404Diese Nachricht gibt es nicht, oder sie gehört nicht zu diesem Benutzer.
too_late409Die Zeit zum Bearbeiten oder Löschen ist abgelaufen.
file_type_not_allowed400Dieser Dateityp wird nicht akzeptiert.
file_too_large413Die Datei ist größer als 16 MB.
blocked403Ihr Team hat diesen Benutzer blockiert.
unknown_user404Für diese Benutzer-ID gibt es noch keine Konversation.
rate_limited429Zu viele Aufrufe: Verlangsamen Sie und versuchen Sie es erneut.
maintenance503SyBox wird gerade aktualisiert: Versuchen Sie es nach Retry-After Sekunden erneut.
server_error500Auf unserer Seite ist ein Fehler aufgetreten.

Einen Schlüssel ersetzen

Einen Schlüssel verloren oder vermuten Sie, dass er öffentlich geworden ist? Klicken Sie auf der Karte der Website auf Neuer Signaturschlüssel, Neuer Serverschlüssel oder Neuer Signaturschlüssel für Antworten. Bei einem neuen Serverschlüssel funktioniert der alte noch einen Tag lang, sodass Sie ohne Unterbrechung umstellen können; die anderen Schlüssel werden sofort ungültig.