Messaging-API
Nachricht senden (Send Message API)
Senden Sie einen WhatsApp-Text, ein Bild oder ein Dokument von Ihrer verbundenen WhatsApp-Nummer an eine Telefonnummer. Nutzen Sie die API für Bestellbestätigungen, Zahlungserinnerungen, Benachrichtigungen und Antworten im Support.
https://wbiztool.com/api/v1/send_msg/Body: JSON, Formularfelder oder multipart/form-data beim Hochladen einer Datei
Die Nachricht wird in die Warteschlange gestellt und innerhalb kurzer Zeit von Ihrer WhatsApp-Nummer gesendet. Die Antwort enthält eine msg_id, mit der Sie ihren Status prüfen können.
Kurzes Beispiel#
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"whatsapp_client": 678,
"msg_type": 0,
"country_code": "91",
"phone": "9876543210",
"msg": "Hi Aman, your order #4821 has shipped and will arrive on Thursday."
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/send_msg/",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"whatsapp_client": 678,
"msg_type": 0,
"country_code": "91",
"phone": "9876543210",
"msg": "Hi Aman, your order #4821 has shipped and will arrive on Thursday.",
},
timeout=60,
)
result = response.json() # read the body even when the HTTP code is 400
if result.get("status") == 1:
print("Queued with msg_id", result["msg_id"])
else:
print("Failed:", result.get("message"))// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/send_msg/", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({
whatsapp_client: 678,
msg_type: 0,
country_code: "91",
phone: "9876543210",
msg: "Hi Aman, your order #4821 has shipped and will arrive on Thursday.",
}),
});
const result = await response.json(); // read the body even when the HTTP code is 400
if (result.status === 1) {
console.log("Queued with msg_id", result.msg_id);
} else {
console.error("Failed:", result.message);
}<?php
$payload = [
'whatsapp_client' => 678,
'msg_type' => 0,
'country_code' => '91',
'phone' => '9876543210',
'msg' => 'Hi Aman, your order #4821 has shipped and will arrive on Thursday.',
];
$ch = curl_init('https://wbiztool.com/api/v1/send_msg/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
echo 'Queued with msg_id ' . $result['msg_id'];
} else {
echo 'Failed: ' . ($result['message'] ?? 'no response');
}Ersetzen Sie YOUR_API_KEY und 678 durch Ihren eigenen Schlüssel und Ihre Nummern-ID. Wo Sie diese finden, steht unter Authentifizierung. Der Schlüssel gehört in den Header Authorization: Bearer (empfohlen); client_id und api_key im Body, als JSON- oder Formularfelder, funktionieren ebenfalls – die Beispiele weiter unten verwenden sie.
Request-Parameter#
Authentifizierung
AuthorizationheaderEmpfohlenBearer YOUR_API_KEY: Ihr API-Schlüssel aus Einstellungen → API-Schlüssel. Mit dem Header könnenclient_idundapi_keyim Body entfallen; werden beide gesendet, wird ein gültiger Schlüssel im Header verwendet. Siehe Schlüssel im Header senden.client_idintegerOhne den Authorization-HeaderIhre API-Client-ID aus Einstellungen → API-Schlüssel. Mit dem Header optional; wenn Sie sie senden, muss sie zum Arbeitsbereich des Schlüssels gehören.
api_keystringOhne den Authorization-HeaderIhr API-Schlüssel von derselben Seite, wenn Sie ihn nicht im Header senden.
whatsapp_clientintegerErforderlich, wenn Sie mehr als eine Nummer habenID der WhatsApp-Nummer oder des Telegram-Kontos, von dem gesendet wird, aus den WhatsApp-Einstellungen. Wenn Sie den Parameter weglassen, wird die einzige verbundene Nummer verwendet, WhatsApp zuerst: Eine verbundene WhatsApp-Nummer wird verwendet, auch wenn zusätzlich ein Telegram-Konto verbunden ist, und ein Telegram-Konto nur, wenn keine WhatsApp-Nummer verbunden ist. Ein
@usernameverwendet das einzige verbundene Telegram-Konto.
Empfänger und Nachricht
phonestringerforderlichDie WhatsApp-Nummer des Empfängers. Leerzeichen,
+,-,., Klammern und eine führende00werden automatisch entfernt,+91 98765-43210funktioniert also. Tabellenwerte wie919876543210.0und9.19876543210E+11werden als ihre Ziffern gelesen, ein gerundeter Wert wie9.19877E+11wird dagegen abgelehnt, weil Ziffern fehlen. Senden Sie die Nummer entweder mit Ländervorwahl (919876543210) oder ohne (9876543210) zusammen mitcountry_code. Eine örtliche Nummer mit ihrer führenden0funktioniert auch:09876543210mitcountry_code91geht an919876543210, und0612345678mit39(Italien, wo die0zur Nummer gehört) geht an390612345678. Eine mit+oder00geschriebene Nummer enthält ihre Ländervorwahl bereits:country_codewird ihr nicht vorangestellt, und eine eingeklammerte(0)nach der Vorwahl wird entfernt,+44 (0)20 7946 0018geht also an442079460018. Von einem Telegram-Konto aus kannphoneauch ein@username, ein Linkt.me/usernameodertg:<id>sein.country_codestringoptionalInternationale Vorwahl ohne
+, zum Beispiel91für Indien oder1für die USA. Sie wird vorphonegesetzt, sofern die Nummer nicht bereits damit beginnt oder mit+oder00geschrieben ist. Ausnahme: Bei91erhält eine 10-stellige Nummer immer das Präfix. Bei anderen Vorwahlen erhält eine lokale Nummer, die mit denselben Ziffern beginnt, kein Präfix. Senden Sie sie daher mit enthaltener Ländervorwahl.msg_typeintegeroptional0Text (Standard),1Bild,2Datei oder Dokument.msgstringErforderlich, wenn msg_type 0 istNachrichtentext, bis zu 3.000 Zeichen. Bei Bildern und Dateien ist es die Bildunterschrift, die leer sein darf. WhatsApp-Formatierung funktioniert:
*bold*,_italic_,~strikethrough~.messagewird als Alias akzeptiert.
Bilder und Dateien
img_urlstringErforderlich, wenn msg_type 1 ist und keine Datei hochgeladen wirdÖffentliche
http- oderhttps-URL des Bildes.file_urlstringErforderlich, wenn msg_type 2 ist und keine Datei hochgeladen wirdÖffentliche
http- oderhttps-URL, von der die Datei direkt heruntergeladen werden kann.filefileoptionalLaden Sie das Bild oder die Datei hoch, statt eine URL anzugeben. Senden Sie den Request als
multipart/form-datamit einem Feld namensfile.file_namestringoptionalDateiname, den der Empfänger sieht, zum Beispiel
invoice-4821.pdf. Die Dateiendung bestimmt, wie die Datei gesendet wird, geben Sie also eine an. Er wird in Kleinbuchstaben gesendet, Zeichen wie& : ? * $ ;werden durch_ersetzt, und er wird auf 150 Zeichen gekürzt. Wenn Sie den Parameter weglassen, wird der Name aus der URL oder der hochgeladenen Datei übernommen.
Zustelloptionen
expire_after_secondsintegeroptionalMarkiert die Nachricht als abgelaufen (Status
4), wenn sie nicht innerhalb dieser Anzahl Sekunden gesendet wurde, zum Beispiel3600für eine Stunde. Nützlich für zeitkritische Nachrichten wie voraussichtliche Lieferzeiten. Ein Hintergrundjob erledigt das frühestens 30 Sekunden nach Fristablauf. Verlassen Sie sich daher bei Fristen unter einer Minute nicht darauf.webhookstringoptionalURL, die einen
POSTerhält, wenn die Nachricht gesendet wird, fehlschlägt, storniert wird oder abläuft. Siehe Webhook.
Bilder und Dateien senden#
Download-Limits für img_url und file_url:
- Die URL muss öffentlich sein:
httpoderhttps, aus dem Internet erreichbar. Bis zu 5 Weiterleitungen werden verfolgt, und jede muss ebenfalls zu einer öffentlichen Adresse führen. - Verlinkte Dateien dürfen bis zu 100 MB groß sein. Der Server muss innerhalb von 45 Sekunden zu antworten beginnen und darf nicht länger als diese Zeit ins Stocken geraten.
- Die Datei wird abgerufen, wenn Sie die API aufrufen. Ein defekter Link schlägt daher sofort mit
Invalid file urlfehl.
Dateien, die mit msg_type 2 gesendet werden, behalten diese Endungen:
| Kategorie | Endungen |
|---|---|
| Bilder | .jpg, .jpeg, .jpe, .png, .gif, .webp, .bmp |
| Dokumente | .pdf, .doc, .docx, .docm, .xls, .xlsx, .xlsm, .xlsb, .ppt, .pptx, .pptm, .txt, .csv |
| Audio | .mp3, .mpga, .m4a, .aac, .wav, .ogg, .oga |
| Video | .mp4, .mov, .avi, .webm |
| Archive | .zip, .rar |
Diese Prüfungen laufen beim Senden der Nachricht, nicht beim Aufruf der API. Die Fehler erscheinen daher nur in Nachrichtenstatus und im Webhook:
| Problem | error in Nachrichtenstatus |
|---|---|
Ein Bild (msg_type 1) über 16 MB | File exceeds WhatsApp size limit (16MB max) |
Ein Video (.mp4, .webm) über 64 MB, auch wenn es als Bild (msg_type 1) gesendet wird | File exceeds WhatsApp size limit (64MB max) |
Jede andere Datei (msg_type 2) über 100 MB | File exceeds WhatsApp size limit (100MB max) |
| Eine leere Datei (0 Byte) | The file is empty |
Eine als Bild (msg_type 1) gesendete .wav- oder .ogg-Datei | File type not supported |
WAV- und OGG-Audio können nicht als Bild (msg_type 1) gesendet werden. Als Datei (msg_type 2) gesendet, kommen sie als Dokument unter ihrem eigenen Namen an, z. B. recording.wav. .mp3-, .mpga-, .m4a- und .aac-Dateien kommen als Audio an, das im Chat abgespielt wird, und msg folgt als separate Textnachricht (Audio hat keine Bildunterschrift).
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 1,
"country_code": "91",
"phone": "9876543210",
"img_url": "https://example.com/offers/diwali-sale.jpg",
"msg": "Our Diwali sale starts today 🎉"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/send_msg/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 1,
"country_code": "91",
"phone": "9876543210",
"img_url": "https://example.com/offers/diwali-sale.jpg",
"msg": "Our Diwali sale starts today 🎉",
},
timeout=60,
)
print(response.json())// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/send_msg/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
msg_type: 1,
country_code: "91",
phone: "9876543210",
img_url: "https://example.com/offers/diwali-sale.jpg",
msg: "Our Diwali sale starts today 🎉",
}),
});
console.log(await response.json());<?php
$ch = curl_init('https://wbiztool.com/api/v1/send_msg/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'msg_type' => 1,
'country_code' => '91',
'phone' => '9876543210',
'img_url' => 'https://example.com/offers/diwali-sale.jpg',
'msg' => 'Our Diwali sale starts today 🎉',
]),
CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);
curl_close($ch);curl -X POST https://wbiztool.com/api/v1/send_msg/ \
-F client_id=12345 \
-F api_key=YOUR_API_KEY \
-F whatsapp_client=678 \
-F msg_type=2 \
-F country_code=91 \
-F phone=9876543210 \
-F "msg=Your invoice for order #4821 is attached." \
-F file_name=invoice-4821.pdf \
-F file=@./invoice-4821.pdfimport requests
with open("invoice-4821.pdf", "rb") as f:
response = requests.post(
"https://wbiztool.com/api/v1/send_msg/",
data={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 2,
"country_code": "91",
"phone": "9876543210",
"msg": "Your invoice for order #4821 is attached.",
"file_name": "invoice-4821.pdf",
},
files={"file": f},
timeout=120,
)
print(response.json())// Node.js 20+ (built-in fetch, FormData and fs.openAsBlob). Save as .mjs to use top-level await.
import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("client_id", "12345");
form.append("api_key", "YOUR_API_KEY");
form.append("whatsapp_client", "678");
form.append("msg_type", "2");
form.append("country_code", "91");
form.append("phone", "9876543210");
form.append("msg", "Your invoice for order #4821 is attached.");
form.append("file_name", "invoice-4821.pdf");
form.append("file", await openAsBlob("./invoice-4821.pdf"), "invoice-4821.pdf");
// Don't set Content-Type yourself; fetch adds the multipart boundary.
const response = await fetch("https://wbiztool.com/api/v1/send_msg/", { method: "POST", body: form });
console.log(await response.json());<?php
$ch = curl_init('https://wbiztool.com/api/v1/send_msg/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
// An array body (not json_encode) makes cURL send multipart/form-data.
CURLOPT_POSTFIELDS => [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'msg_type' => 2,
'country_code' => '91',
'phone' => '9876543210',
'msg' => 'Your invoice for order #4821 is attached.',
'file_name' => 'invoice-4821.pdf',
'file' => new CURLFile('/path/to/invoice-4821.pdf', 'application/pdf', 'invoice-4821.pdf'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
echo curl_exec($ch);
curl_close($ch);Offizielle Clients verwenden#
Die Clients für Python und Node.js rufen diesen Endpoint für Sie auf.
from wbiztool_client import WbizToolClient
client = WbizToolClient(api_key="YOUR_API_KEY", client_id="12345")
result = client.send_message(
phone="9876543210",
country_code="91",
msg="Hi Aman, your order #4821 has shipped.",
whatsapp_client=678,
)
print(result)Fehler lösen requests.HTTPError aus. Den Grund lesen Sie mit e.response.json()["message"].
const { WbizToolClient } = require("wbiztool-client");
const client = new WbizToolClient({
clientId: 12345,
apiKey: "YOUR_API_KEY",
whatsappClient: 678,
});
(async () => {
// Errors throw, with the API's response in the error message.
const result = await client.sendMessage({
phone: "9876543210",
countryCode: "91",
message: "Hi Aman, your order #4821 has shipped.",
});
console.log(result);
})().catch(console.error);Antwort#
Ein erfolgreicher Request gibt HTTP 200 zurück:
{
"status": 1,
"message": "Created",
"msg_id": 9817263
}
| Feld | Typ | Beschreibung |
|---|---|---|
status | integer | 1, wenn die Nachricht in die Warteschlange gestellt wurde, 0, wenn der Request fehlgeschlagen ist. |
message | string | Created bei Erfolg, andernfalls der Fehler. |
msg_id | integer | ID der Nachricht in der Warteschlange. Speichern Sie sie, um später den Status zu prüfen. Nur bei Erfolg vorhanden. |
"status": 1 bedeutet, dass die Nachricht in die Warteschlange gestellt wurde, nicht, dass sie den Empfänger bereits erreicht hat. Verwenden Sie einen Webhook oder Nachrichtenstatus, um den Versand zu bestätigen.
Fehler#
Fehler geben HTTP 400 mit status gleich 0 zurück (Account Disabled hat kein Feld status):
{ "status": 0, "message": "Msg cant be null" }
| Meldung | Lösung |
|---|---|
Auth Error - Please send correct API key and Client id | Senden Sie einen nicht leeren api_key. |
Invalid client id. | Senden Sie client_id als Zahl. |
Auth Error: invalid api key | Prüfen Sie, ob der Schlüssel existiert, nicht gelöscht wurde und zu dieser client_id gehört. |
Either phone or group_name parameter is required | Fügen Sie phone hinzu. |
Please provide either phone OR group_name, not both | Entfernen Sie einen der beiden Parameter. |
Invalid phone number | phone muss eine Nummer mit 6–17 Ziffern sein. Buchstaben und andere Zeichen sind nicht erlaubt, ebenso wenig ein gerundeter Tabellenwert wie 9.19877E+11. |
Invalid Contact Number "…" | Einschließlich Ländervorwahl muss die Nummer 7–15 Ziffern lang sein. |
Msg cant be null | Textnachrichten (msg_type 0) benötigen msg. |
Message length is too long | Begrenzen Sie msg auf höchstens 3.000 Zeichen. |
Image Url Can't be null | Senden Sie für msg_type 1 eine img_url oder laden Sie eine file hoch. |
File Url Can't be null | Senden Sie für msg_type 2 eine file_url oder laden Sie eine file hoch. |
Invalid file url, Can't download / Invalid file url | Die URL ist nicht öffentlich, das Zeitlimit wurde überschritten oder die Datei ist größer als 100 MB. |
Invalid whatsapp client | Diese whatsapp_client-ID gehört nicht zu Ihrem Arbeitsbereich. |
Invalid whatsapp client id. | Senden Sie whatsapp_client. Der Parameter ist erforderlich, wenn Ihr Arbeitsbereich mehr als eine verbundene Nummer hat. |
Telegram usernames can only be sent to from a Telegram account: pass its id as whatsapp_client | Ein @username, ein t.me-Link oder tg:<id> in phone braucht ein Telegram-Konto als whatsapp_client. |
Not enough credits | Der Arbeitsbereich ist im kostenlosen Plan und hat keine Nachrichten mehr: Kostenpflichtige Pläne senden unbegrenzt viele Nachrichten. Siehe Wenn Ihre Nachrichten aufgebraucht sind. |
Daily limit reached: a number can send 1,000 messages in 24 hours (fair use). Send the rest tomorrow. (HTTP 429, "code": "daily_limit_reached") | Diese Nummer hat in den letzten 24 Stunden 1.000 Nachrichten angenommen (Fair Use). Die Antwort enthält trotzdem die msg_id der abgelehnten Nachricht, die als fehlgeschlagen erscheint. Senden Sie den Rest später oder von einer anderen Nummer. |
Demo Account can not access apis | Verwenden Sie ein reguläres Konto. |
Account Disabled | Ihr Konto ist deaktiviert. Kontaktieren Sie den Support. |
Invalid JSON format: … | Der JSON-Body ist ungültig, oft wegen eines abschließenden Kommas oder eines nicht maskierten Zeilenumbruchs in msg. Verwenden Sie \n für neue Zeilen. |
Eine Nachricht in der Warteschlange kann beim Senden trotzdem noch fehlschlagen, zum Beispiel mit File exceeds WhatsApp size limit (…). Solche Fehler erscheinen nie in dieser Antwort. Siehe Bilder und Dateien senden und prüfen Sie Nachrichtenstatus.
Webhook#
Wenn Sie webhook übergeben, sendet WbizTool einen POST an diese URL, sobald die Nachricht gesendet wurde oder fehlgeschlagen ist, und auch dann, wenn sie vor dem Senden storniert wird oder abläuft. Der Body ist formularkodiert (application/x-www-form-urlencoded), nicht JSON:
msg_id=9817263&status=SENT
| Feld | Werte |
|---|---|
msg_id | Die msg_id, die Sie beim Senden der Nachricht erhalten haben. |
status | SENT, FAILED, CANCELLED (vor dem Senden storniert: mit Nachricht stornieren, im Dashboard oder weil die zugehörige WhatsApp-Nummer oder Kampagne entfernt wurde) oder EXPIRED (nicht gesendet, bevor expire_after_seconds abgelaufen war) |
Jeder Webhook ist signiert: Mit den Headern WbizTool-Timestamp und WbizTool-Signature (v1= und ein HMAC-SHA256 aus <timestamp>.<raw body> mit dem Signatur-Secret Ihres Arbeitsbereichs) können Sie prüfen, dass er von WbizTool stammt. Wie Sie das Secret bekommen und die Prüfung in Python und Node.js finden Sie unter Webhook-Signaturen; Empfänger, die die Header ignorieren, funktionieren weiter.
Antworten Sie mit einem beliebigen 2xx-Code; eine Weiterleitung wird höchstens 3-mal verfolgt. Wenn Ihr Endpoint nicht innerhalb von 10 Sekunden antwortet, nicht erreichbar ist oder 429 oder 5xx zurückgibt, versucht WbizTool es nach 30 Sekunden, 1 Minute und 2 Minuten erneut (insgesamt 4 Versuche). Andere 4xx-Antworten werden nicht wiederholt. Die URL muss eine öffentliche Internetadresse sein: Ein Webhook an eine private oder lokale Adresse (wie 192.168.x.x oder localhost) wird nicht gesendet.
Tipps#
- Telefonnummern: Speichern Sie Nummern im internationalen Format und senden Sie sie mit
country_code, um Mehrdeutigkeiten zu vermeiden. - Zeilenumbrüche in JSON: Schreiben Sie sie in
msgals\n. Ein echter Zeilenumbruch macht das JSON ungültig. - Halten Sie Ihre Nummer verbunden: Nachrichten werden von Ihrer WhatsApp-Nummer gesendet, daher muss sie in den WhatsApp-Einstellungen verbunden bleiben.
- Viele Empfänger: Um dieselbe Nachricht in einem Request an mehrere Nummern zu senden, verwenden Sie An mehrere Nummern senden. Für große Kampagnen laden Sie stattdessen eine Tabelle auf der Seite Kampagnen hoch.
