Zum Inhalt springen
WbizTool

API v2 (Beta)

Webhooks

Ein Webhook-Endpunkt ist eine URL auf Ihrem Server, die WbizTool aufruft, wenn mit einer Nachricht etwas passiert: Sie wurde gesendet, ist fehlgeschlagen, wurde storniert oder ist abgelaufen. Sie erfahren es sofort, statt regelmäßig abzufragen, und jeder Request ist signiert, damit Sie prüfen können, dass er von WbizTool kommt.

VorgangEndpointScope
Endpunkt hinzufügenPOST /api/v2/webhooksmessages:read
Endpunkte auflistenGET /api/v2/webhooksmessages:read
Einen Endpunkt abrufenGET /api/v2/webhooks/{id}messages:read
Endpunkt entfernenDELETE /api/v2/webhooks/{id}messages:read
Signatur-Secret ersetzenPOST /api/v2/webhooks/{id}/rotate-secretmessages:read
Testereignis sendenPOST /api/v2/webhooks/{id}/testmessages:read

Endpunkte gehören zum Arbeitsbereich und erhalten Ereignisse für alle seine Nachrichten, egal was sie gesendet hat: die API, das Dashboard, Kampagnen, Erinnerungen oder Integrationen. Deshalb kann ein auf einige Nummern beschränkter Schlüssel sie nicht verwalten: Jeder Aufruf antwortet mit 403 number_not_allowed.

Ereignisse#

TypWann
message.sentEine Nachricht ist von Ihrer Nummer rausgegangen.
message.failedEine Nachricht konnte nicht gesendet werden; error.message nennt den Grund.
message.cancelledEine wartende Nachricht wurde storniert: über die API, im Dashboard oder weil ihre Nummer oder Kampagne entfernt wurde.
message.expiredEine Nachricht wurde nicht vor ihrem expires_at gesendet.
pingEin von Ihnen angefordertes Testereignis.

Ereignisse für Nummern (verbunden, abgemeldet) und für eingehende Nachrichten folgen später. Zugestellt- und Gelesen-Häkchen lösen keine Ereignisse aus; rufen Sie die Nachricht ab, um sie zu sehen.

Endpunkt hinzufügen#

POSThttps://wbiztool.com/api/v2/webhooks

Body: JSON (application/json)

Body

urlstringerforderlich

Ihr Endpunkt: eine öffentliche https://-Adresse, bis zu 500 Zeichen. http://, private und lokale Adressen (zum Beispiel localhost oder 192.168.x.x) werden abgelehnt.

eventsarray of stringsoptional

Die Ereignistypen, die er erhält: beliebige von message.sent, message.failed, message.cancelled und message.expired. Standard: alle vier. ping kommt immer an, wenn Sie eines anfordern.

descriptionstringoptional

Eine Notiz für Sie selbst, bis zu 100 Zeichen, zum Beispiel Order system.

Ein Arbeitsbereich kann bis zu 5 Endpunkte haben. Die Antwort ist 201 mit dem Endpunkt und seinem Signatur-secret, das nur dieses eine Mal angezeigt wird. Speichern Sie es dort, wo Ihr Empfänger es lesen kann, zum Beispiel in einer Umgebungsvariablen. Spätere Antworten zeigen nur secret_last4; wenn Sie das Secret verlieren, ersetzen Sie es.

curl -X POST https://wbiztool.com/api/v2/webhooks \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/wbiztool/events",
    "events": ["message.sent", "message.failed"],
    "description": "Order system"
  }'

Antwort (201):

{
  "id": 41,
  "url": "https://example.com/wbiztool/events",
  "description": "Order system",
  "events": ["message.sent", "message.failed"],
  "secret_last4": "9c1e",
  "active": true,
  "disabled_reason": null,
  "created_at": "2026-10-18T11:20:05.733Z",
  "last_delivery": null,
  "secret": "3f0b…9c1e"
}

Das echte secret besteht aus 64 Hexadezimalzeichen. Eine Wiederholung dieses Requests mit demselben Idempotency-Key fügt keinen zweiten Endpunkt hinzu, und ihre Antwort lässt das Secret weg.

Fehler beim Hinzufügen eines Endpunkts#

HTTPCodeWann
400validation_failedurl fehlt oder ist zu lang, events ist leer oder enthält einen unbekannten Typ, oder ein Feld ist unbekannt
403webhook_limit_reachedDer Arbeitsbereich hat bereits 5 Endpunkte
403number_not_allowedDer Schlüssel ist auf einige Nummern beschränkt
422invalid_webhook_urlurl ist keine öffentliche https://-Adresse

Endpunkte auflisten#

GEThttps://wbiztool.com/api/v2/webhooks

Die Endpunkte des Arbeitsbereichs, die Ereignisse erhalten, der älteste zuerst, in einer einzigen data-Liste.

curl https://wbiztool.com/api/v2/webhooks \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

Die Liste lässt Endpunkte weg, die gestoppt wurden. Inhaber sehen die Endpunkte auch unter Einstellungen → API-Schlüssel bei Webhook-Endpunkte und können sie dort entfernen.

Einen Endpunkt abrufen#

GEThttps://wbiztool.com/api/v2/webhooks/{id}

Ein einzelner Endpunkt. last_delivery zeigt, wie seine letzte Zustellung verlaufen ist. Ein Endpunkt, der nicht existiert oder entfernt wurde, antwortet mit 404 webhook_not_found; ein gestoppter wird mit active: false angezeigt.

Endpunkt entfernen#

DELETEhttps://wbiztool.com/api/v2/webhooks/{id}

An ihn wird nichts mehr gesendet, auch keine noch wartenden Wiederholungen. Die Antwort ist {"id": 41, "deleted": true}.

Signatur-Secret ersetzen#

POSThttps://wbiztool.com/api/v2/webhooks/{id}/rotate-secret

Erstellt ein neues Secret für den Endpunkt. Die Antwort ist 200 mit dem Endpunkt und seinem neuen secret, das nur dieses eine Mal angezeigt wird. Das alte Secret funktioniert sofort nicht mehr: Danach gesendete Ereignisse werden mit dem neuen signiert, auch Wiederholungen früherer Ereignisse. Aktualisieren Sie Ihren Empfänger sofort.

curl -X POST https://wbiztool.com/api/v2/webhooks/41/rotate-secret \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

Testereignis senden#

POSThttps://wbiztool.com/api/v2/webhooks/{id}/test

Stellt ein ping-Ereignis an diesen Endpunkt in die Warteschlange, signiert wie jedes Ereignis, damit Sie Ihren Empfänger testen können. Die Antwort ist 202:

{ "event_id": "evt_8a2f4c1d9b7e6a5f4c3b2a19", "type": "ping", "queued": true }

Ihr Endpunkt erhält:

{
  "id": "evt_8a2f4c1d9b7e6a5f4c3b2a19",
  "type": "ping",
  "created_at": "2026-10-18T11:21:40.002Z",
  "data": { "webhook_id": 41 }
}

Die Ereignis-Payload#

Jedes Ereignis ist ein POST mit einem JSON-Body:

{
  "id": "evt_c41d7e2a9f3b8c6d5e4f3a21",
  "type": "message.sent",
  "created_at": "2026-10-18T10:15:09.912Z",
  "data": {
    "message": {
      "id": 9817263,
      "status": "sent",
      "from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
      "to": { "phone": "+919876543210", "contact_id": 991 },
      "text": "Hi Asha, your order #1042 is ready.",
      "media": null,
      "send_at": null,
      "expires_at": null,
      "created_at": "2026-10-18T10:15:02.311Z",
      "sent_at": "2026-10-18T10:15:09.870Z",
      "error": null
    }
  }
}
FeldBeschreibung
idDie ID des Ereignisses, evt_ und 24 Zeichen. Dasselbe Ereignis behält seine ID bei jeder Wiederholung.
typeEiner der Ereignistypen.
created_atWann das Ereignis passiert ist.
data.messageBei message.*-Ereignissen: die Nachricht in ihrem damaligen Zustand. Eine darin enthaltene media.url funktioniert mindestens 26 Stunden.
data.webhook_idBei ping: die ID des Endpunkts.

Header:

HeaderWert
Content-Typeapplication/json
User-AgentWbizTool-Webhooks/2
WbizTool-Event-IdDie id des Ereignisses, bei jeder Wiederholung dieselbe
WbizTool-TimestampWann dieser Versuch gesendet wurde, in Unix-Sekunden, zum Beispiel 1792310409
WbizTool-Signaturev1= und der hexadezimale HMAC-SHA256 von <timestamp>.<raw body>, erstellt mit dem Secret des Endpunkts

Signatur prüfen#

Prüfen Sie jeden Request, bevor Sie ihm vertrauen: Berechnen Sie die Signatur aus dem unveränderten Body (bevor Ihr Framework das JSON parst), vergleichen Sie sie in konstanter Zeit mit dem Header und lehnen Sie Zeitstempel ab, die mehr als 5 Minuten abweichen, damit ein alter Request nicht erneut eingespielt werden kann. Es ist dasselbe Verfahren wie bei den Webhook-Signaturen der API v1, mit dem eigenen Secret des Endpunkts.

Verwenden Sie dann WbizTool-Event-Id, um Wiederholungen zu verwerfen: Dasselbe Ereignis kann mehr als einmal ankommen, zum Beispiel wenn Ihre Antwort verloren ging und wir es erneut versucht haben.

import hashlib, hmac, json, os, time

SECRET = os.environ["WBIZTOOL_WEBHOOK_SECRET"]

def verify(secret: str, body: bytes, headers) -> bool:
    ts, sig = headers.get("WbizTool-Timestamp", ""), headers.get("WbizTool-Signature", "")
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        return False
    mac = "v1=" + hmac.new(secret.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(mac, sig)

# Flask
from flask import Flask, request

app = Flask(__name__)
seen = set()  # use your database in production

@app.post("/wbiztool/events")
def events():
    body = request.get_data()  # the raw bytes
    if not verify(SECRET, body, request.headers):
        return "", 401
    event_id = request.headers["WbizTool-Event-Id"]
    if event_id in seen:
        return "", 200  # a repeat: already handled
    seen.add(event_id)
    event = json.loads(body)
    if event["type"] == "message.failed":
        message = event["data"]["message"]
        print("Failed:", message["id"], message["error"]["message"])
    return "", 200

In Django übergeben Sie request.body und request.headers.

Antworten Sie schnell mit 2xx und erledigen Sie langsame Arbeit danach (zum Beispiel in einer Warteschlange).

Wiederholungen#

  • Antworten Sie innerhalb von 10 Sekunden mit einem beliebigen 2xx. Alles andere ist ein Fehlschlag: ein anderer Statuscode (4xx eingeschlossen), keine Antwort innerhalb von 10 Sekunden oder keine Verbindung innerhalb von 3. Weiterleitungen werden verfolgt, höchstens 3, und jede muss zu einer öffentlichen Adresse führen.
  • Eine fehlgeschlagene Zustellung wird erneut versucht, nach 1, 5 und 15 Minuten, dann nach 1, 2, 4, 8 und 8 Stunden: 9 Versuche über etwa 23 Stunden. Nach dem letzten wird das Ereignis verworfen.
  • Die Wiederholung hat denselben Body und dieselbe WbizTool-Event-Id, mit einem neuen WbizTool-Timestamp und einer neuen Signatur.
  • Die Reihenfolge ist nicht garantiert. Ein wiederholtes message.sent kann nach einem späteren Ereignis ankommen. Verwenden Sie den status der Nachricht oder rufen Sie die Nachricht ab, wenn die Reihenfolge wichtig ist.

last_delivery am Endpunkt zeigt, wie die letzte Zustellung verlaufen ist: state (pending, delivered oder failed), der status_code, mit dem Ihr Server geantwortet hat, und wann das Ereignis erstellt wurde.

Wann Endpunkte gestoppt werden#

Ein Endpunkt erhält keine Ereignisse mehr, wenn einer dieser Fälle eintritt. Er bleibt in GET /webhooks mit active: false und einem disabled_reason, damit Sie den Grund sehen; er kann weiterhin gelesen und entfernt, aber nicht getestet werden und kein neues Secret erhalten (404).

  • Er schlägt seit 24 Stunden fehl. Wurde 24 Stunden lang nichts an ihn zugestellt, während seine Zustellungen weiter fehlschlugen, wird er abgeschaltet, und seine wartenden Wiederholungen werden verworfen. Einstellungen → API-Schlüssel zeigt ihn dann als Aus. Beheben Sie das Problem auf Ihrem Server und fügen Sie den Endpunkt dann erneut hinzu.
  • Der Schlüssel, der ihn erstellt hat, wird widerrufen oder läuft ab. Wird ein Schlüssel widerrufen, stoppt alles, was er eingerichtet hat. Fügen Sie den Endpunkt mit einem anderen Schlüssel erneut hinzu.
  • Er wird entfernt, mit Endpunkt entfernen oder unter Einstellungen → API-Schlüssel.

Gestoppte Endpunkte zählen nicht zu den 5.

Das Webhook-endpoint-Objekt#

FeldTypBeschreibung
idintegerDie ID des Endpunkts.
urlstringWohin Ereignisse gesendet werden.
descriptionstringIhre Notiz; "", wenn es keine gibt.
eventsarrayDie Ereignistypen, die er erhält.
secretstringDas Signatur-Secret: nur in den Antworten auf Endpunkt hinzufügen und Signatur-Secret ersetzen.
secret_last4stringDie letzten 4 Zeichen des Secrets, damit Sie erkennen, welches Sie haben.
activebooleanfalse, wenn er keine Ereignisse mehr erhält – siehe Wann Endpunkte gestoppt werden.
disabled_reasonstring or nullWarum er gestoppt wurde (24 Stunden lang fehlgeschlagen, oder der Schlüssel, der ihn erstellt hat, wurde widerrufen oder ist abgelaufen); null, solange er aktiv ist.
created_atstringWann er hinzugefügt wurde.
last_deliveryobject or nullDie letzte versuchte Zustellung: state, status_code (oder null, wenn Ihr Server nicht geantwortet hat) und created_at. null vor der ersten.

Verwandte Themen#