API v2 (Beta)
Von v1 zu v2 wechseln
API v2 kann alles, was v1 kann, mit sichereren Schlüsseln, einem einheitlichen URL-Stil, echten HTTP-Statuscodes und signierten JSON-Webhooks. Diese Seite ordnet jedem v1-Endpoint und jedem Feld sein Gegenstück in v2 zu. Was in v2 selbst neu ist, steht im Überblick.
Was sich überall ändert#
- Schlüssel: Aus
client_id+api_keyin v1 wird ein einziger Header,Authorization: Bearer wbz_live_…. Erstellen Sie unter Einstellungen → API-Schlüssel in der Karte API-v2-Schlüssel einen v2-Schlüssel, nur mit den Scopes, die die App braucht. v1-Schlüssel funktionieren nicht mit v2, und v2-Schlüssel nicht mit v1. - Nur JSON: keine Formularfelder. Datei-Uploads gehen an
POST /media(Multipart) und werden permedia_idgesendet. - Methoden und URLs:
GETzum Lesen,POSTzum Erstellen,PATCHzum Ändern,DELETEzum Stornieren oder Löschen, unterhttps://wbiztool.com/api/v2. - HTTP-Statuscodes statt
"status": 0oder1(siehe Antworten und Fehler). - Telefonnummern im internationalen Format mit
+, ohnecountry_code. - Zeiten in ISO 8601 mit Offset statt getrennter Felder für Datum, Uhrzeit und Zeitzone.
- Webhooks sind Endpunkte, die Sie einmal für den Arbeitsbereich hinzufügen, mit signierten JSON-Ereignissen, statt einer
webhook-URL bei jeder Nachricht.
Endpoint für Endpoint#
v2-Pfade sind relativ zu https://wbiztool.com/api/v2.
Senden, Feld für Feld#
| v1 | v2 | Hinweise |
|---|---|---|
client_id + api_key (Body oder Authorization: Bearer) | Authorization: Bearer wbz_live_… | Ein neuer v2-Schlüssel; keine client_id |
phone + country_code | to.phone | Eine Nummer in E.164 mit +: "9876543210" mit "country_code": "91" wird zu {"phone": "+919876543210"}. Es wird keine Ländervorwahl für Sie ergänzt |
phone mit einem @username (Telegram) | to.username | @name, t.me/name oder tg: mit einer ID, von einem Telegram-Konto |
group_name | to.group | Der genaue Name der Gruppe |
| (nicht in v1) | to.contact_id | Ein gespeicherter Kontakt |
whatsapp_client | from | Die id der Nummer; optional, wenn eine Nummer verbunden ist, wie bisher |
msg (oder message) | text | Bis zu 3.000 Zeichen, wie bisher |
msg_type 0, 1, 2 | entfällt | Eine Nachricht mit media ist eine Mediennachricht; media.type (image oder file), wenn der Link es nicht erkennen lässt |
img_url / file_url | media.url | Ein öffentlicher http(s)-Link |
file (Upload im selben Request) | media.media_id | Zuerst hochladen, dann die ID so oft senden, wie Sie möchten |
file_name | media.file_name | Für Dateien |
date + time + timezone von schedule_msg/ | send_at | Eine Zeit mit Offset: 24/12/2026, 10:30 und Asia/Kolkata werden zu "2026-12-24T10:30:00+05:30" |
expire_after_seconds | expires_at | Ein Zeitpunkt, keine Dauer: jetzt plus die Sekunden, mit Offset |
webhook | Webhook-Endpunkte | Einmal mit POST /webhooks hinzugefügt, für jede Nachricht des Arbeitsbereichs |
msg_id in der Antwort | id | Die Nachricht selbst kommt zurück, mit ihrem status |
Derselbe Versand in v1 und v2:
# v1
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
-H "Authorization: Bearer YOUR_V1_KEY" \
-H "Content-Type: application/json" \
-d '{"whatsapp_client": 101, "msg_type": 1, "country_code": "91", "phone": "9876543210",
"img_url": "https://example.com/offers/diwali-sale.jpg", "msg": "Our Diwali sale starts today",
"expire_after_seconds": 3600}'
# v2
curl -X POST https://wbiztool.com/api/v2/messages \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: diwali-9876543210" \
-d '{"from": 101, "to": {"phone": "+919876543210"},
"media": {"url": "https://example.com/offers/diwali-sale.jpg"}, "text": "Our Diwali sale starts today",
"expires_at": "2026-10-20T11:30:00+05:30"}'
Einige Verhaltensweisen von v1 gibt es bewusst nicht mehr:
- Kein Raten von Ländervorwahlen. v1 hat
country_codevor eine Nummer gesetzt (bei91immer vor eine 10-stellige). v2 übernimmt die Nummer genau so, wie sie mit+geschrieben ist. - Kein Datei-Download beim Aufruf. v1 hat
img_urlundfile_urlwährend des Requests abgerufen. v2 prüft, ob der Link öffentlich ist, und ruft die Datei beim Senden der Nachricht ab; ein defekter Link zeigt sich als Nachricht mit Statusfailed. - Kein fehlgeschlagener Eintrag bei Ablehnung. Wenn v1 einen Versand über dem Tageslimit von 1.000 ablehnt, speichert es die Nachricht trotzdem als fehlgeschlagen. v2 speichert nichts, wenn es einen Versand ablehnt.
- Unbekannte Felder werden abgelehnt, statt ignoriert zu werden.
Status#
Die Zahlen und Wörter von v1 werden zu einem einzigen Feld status:
| v1 | v2 status |
|---|---|
0 Erstellt / Ausstehend | queued, oder scheduled, solange sein send_at noch bevorsteht |
1 Gesendet | sent, delivered oder read (die WhatsApp-Häkchen) |
2 Fehlgeschlagen | failed |
3 Storniert | cancelled |
4 Abgelaufen | expired |
Webhook-Ereignisse sind message.sent, message.failed, message.cancelled und message.expired, passend zu SENT, FAILED, CANCELLED und EXPIRED in v1.
Antworten und Fehler#
v1 beantwortet viele Fehler mit HTTP 200 oder 400 und "status": 0, und Erfolg mit "status": 1. v2 verwendet den HTTP-Statuscode:
- Erfolg ist
200,201(erstellt) oder202(in der Warteschlange), und der Body ist das Objekt selbst, zum Beispiel die Nachricht. Es gibt keine Hülle mitstatus: 1. - Fehler sind
4xxoder5xxmit einer einheitlichen Struktur:{"error": {"code", "message", "field", "docs", "request_id"}}. Verzweigen Sie nachcode, nicht nach der englischenmessage. Jeder Code steht auf der Fehlerseite.
# v1
result = response.json()
if result.get("status") == 1:
msg_id = result["msg_id"]
# v2
if response.status_code == 202:
message_id = response.json()["id"]
else:
error = response.json()["error"]
if error["code"] == "number_daily_cap_reached":
... # try again tomorrow
Einige Meldungen von v1 und ihre Codes in v2:
| v1-Meldung | v2-Code |
|---|---|
Auth Error: invalid api key | 401 invalid_api_key, api_key_revoked oder api_key_expired |
Invalid phone number / Invalid Contact Number "…" | 422 invalid_phone |
Msg cant be null | 400 text_required |
Message length is too long | 400 text_too_long |
Invalid whatsapp client | 422 number_not_found |
Invalid whatsapp client id. | 422 from_required |
Not enough credits | 402 no_credits |
Daily limit reached: … | 429 number_daily_cap_reached |
Demo Account can not access apis | 403 demo_account |
Account Disabled | 403 account_disabled |
Invalid JSON format: … | 400 invalid_json |
Webhooks#
In v1 kann jede Nachricht eine webhook-URL mitbringen, die formularcodiert msg_id=…&status=SENT erhält. In v2:
- Fügen Sie einmal einen Endpunkt mit
POST /webhookshinzu und speichern Sie seinsecret. - Er erhält JSON-Ereignisse für jede Nachricht des Arbeitsbereichs, mit der vollständigen Nachricht in
data.message. Ordnen Sie sie Ihren Datensätzen überdata.message.idzu. - Prüfen Sie die Signatur: dasselbe Schema wie in v1 (
WbizTool-Timestamp,WbizTool-Signature: v1=…), aber mit dem eigenen Secret des Endpunkts statt dem des Arbeitsbereichs. - Verwerfen Sie Wiederholungen anhand von
WbizTool-Event-Id. Neue Versuche laufen etwa 23 Stunden lang, nicht 4 Versuche über wenige Minuten wie in v1, und auch4xx-Antworten werden erneut versucht.
Für die Verbindungsereignisse von v1 (webhook_url bei whatsapp/connect/) gibt es in v2 noch kein Ereignis: Fragen Sie stattdessen GET /numbers/{id} regelmäßig ab.
Eine Checkliste#
Einen v2-Schlüssel pro App erstellen
Unter Einstellungen → API-Schlüssel, nur mit den Scopes, die die App braucht. Probieren Sie es zuerst mit einem Testschlüssel aus, der alles prüft und nichts sendet.
Die Requests ändern
Neue URLs und Methoden, JSON-Bodys,
to/from/text/media, Telefonnummern mit+, Zeiten mit Offset. Fügen Sie jedem Versand einenIdempotency-Keyhinzu.Die Fehlerbehandlung ändern
Prüfen Sie den HTTP-Status, dann
error.code. Behandeln Sie429, indem SieRetry-Afterabwarten.Webhooks umziehen
Fügen Sie einen Endpunkt hinzu, prüfen Sie Signaturen mit seinem Secret und verwerfen Sie Wiederholungen anhand der Ereignis-ID.
Umstellen und widerrufen
Sobald die App mit v2 läuft, löschen Sie ihren v1-Schlüssel unter Einstellungen → API-Schlüssel.
