API v2 (Beta)
Nachrichten
Senden Sie eine Nachricht sofort oder zu einem festgelegten Zeitpunkt, an eine Telefonnummer, eine WhatsApp-Gruppe, einen gespeicherten Kontakt oder einen Telegram-Benutzernamen. Senden Sie dieselbe Nachricht mit einem Request an bis zu 1.000 Empfänger, lesen Sie den Verlauf, verfolgen Sie den Status einer Nachricht und stornieren Sie sie, solange sie wartet.
| Vorgang | Endpoint | Scope |
|---|---|---|
| Nachricht senden | POST /api/v2/messages | messages:send |
| An viele Empfänger senden | POST /api/v2/messages/batch | messages:send |
| Nachrichten auflisten | GET /api/v2/messages | messages:read |
| Nachricht abrufen | GET /api/v2/messages/{id} | messages:read |
| Nachricht stornieren | DELETE /api/v2/messages/{id} | messages:send |
Schlüssel, Fehler, Idempotency-Key und Limits funktionieren wie im Überblick über API v2 beschrieben. Um ohne Abfragen zu erfahren, wann eine Nachricht gesendet wird oder fehlschlägt, fügen Sie einen Webhook-Endpunkt hinzu.
Nachricht senden#
https://wbiztool.com/api/v2/messagesBody: JSON (application/json)
Die Nachricht wird in die Warteschlange gestellt, und die Antwort kommt, bevor sie gesendet wird: mit HTTP 202 und der Message im Status queued (oder scheduled bei einem zukünftigen send_at). Verfolgen Sie sie mit Nachricht abrufen oder einem Webhook.
curl -X POST https://wbiztool.com/api/v2/messages \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-ready" \
-d '{
"from": 101,
"to": { "phone": "+919876543210" },
"text": "Hi Asha, your order #1042 is ready."
}'import os
import requests
response = requests.post(
"https://wbiztool.com/api/v2/messages",
headers={
"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}",
"Idempotency-Key": "order-1042-ready",
},
json={
"from": 101,
"to": {"phone": "+919876543210"},
"text": "Hi Asha, your order #1042 is ready.",
},
timeout=30,
)
body = response.json()
if response.status_code == 202:
print("Queued:", body["id"], body["status"])
else:
print("Refused:", body["error"]["code"], body["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "order-1042-ready",
},
body: JSON.stringify({
from: 101,
to: { phone: "+919876543210" },
text: "Hi Asha, your order #1042 is ready.",
}),
});
const body = await response.json();
if (response.status === 202) {
console.log("Queued:", body.id, body.status);
} else {
console.error("Refused:", body.error.code, body.error.message);
}<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: order-1042-ready',
],
CURLOPT_POSTFIELDS => json_encode([
'from' => 101,
'to' => ['phone' => '+919876543210'],
'text' => 'Hi Asha, your order #1042 is ready.',
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 202) {
echo 'Queued: ' . $body['id'] . ' ' . $body['status'];
} else {
echo 'Refused: ' . $body['error']['code'] . ' ' . $body['error']['message'];
}Antwort (202):
{
"id": 9817263,
"status": "queued",
"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": null,
"error": null
}
Body
toobjecterforderlichWer sie erhält: genau eines von
phone,group,contact_idoderusername. Siehe Empfänger.frominteger or nullErforderlich, außer der Arbeitsbereich hat genau eine verbundene NummerDie
idder Nummer, die sie sendet, aus Nummern auflisten. Wenn Sie das Feld weglassen, sendet die einzige verbundene Nummer: 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. Eine abgemeldete Nummer wird akzeptiert: Ihre Nachrichten warten, bis sie wieder verbunden ist.textstringErforderlich, außer es werden Medien gesendetDie Nachricht, bis zu 3.000 Zeichen. Mit
mediaist es die Bildunterschrift und kann weggelassen werden. WhatsApp-Formatierung funktioniert:*bold*,_italic_,~strikethrough~. Schreiben Sie Zeilenumbrüche in JSON als\n.mediaobject or nulloptionalEin Bild oder eine Datei zum Senden. Siehe Medien.
send_atstring or nulloptionalZu diesem Zeitpunkt statt sofort senden: ISO 8601 mit Offset, zum Beispiel
2026-10-20T09:30:00+05:30. Der Zeitpunkt muss in der Zukunft liegen. Siehe Planung und Ablauf.expires_atstring or nulloptionalNach diesem Zeitpunkt nicht mehr senden: Die Nachricht wird stattdessen
expired. ISO 8601 mit Offset, in der Zukunft und nachsend_at.
Header
AuthorizationheadererforderlichBearer wbz_live_…, ein Schlüssel mit dem Scopemessages:send.Idempotency-KeyheaderoptionalEine beliebige eindeutige Zeichenfolge, damit eine Wiederholung nie eine zweite Nachricht sendet. Siehe Idempotency-Key.
Fehler beim Senden#
| HTTP | Code | Wann |
|---|---|---|
400 | validation_failed | Ein Feld fehlt, hat den falschen Typ oder ist unbekannt; to enthält keines oder mehrere seiner Felder; media enthält beide oder keines von url und media_id; expires_at liegt nicht nach send_at |
400 | text_required | Weder text noch media |
400 | text_too_long | text ist länger als 3.000 Zeichen |
400 | invalid_datetime | send_at oder expires_at ist nicht ISO 8601 mit Offset |
402 | no_credits | Der Arbeitsbereich hat in seinem Plan keine Nachrichten mehr übrig |
403 | number_not_allowed | Der Schlüssel ist auf andere Nummern beschränkt |
403 | account_disabled | Das Konto des Inhabers des Arbeitsbereichs ist deaktiviert |
422 | invalid_phone | to.phone ist keine Telefonnummer im internationalen Format mit + |
422 | invalid_username | to.username ist kein Telegram-Benutzername, Link oder keine tg:-ID |
422 | username_needs_telegram | to.username mit einer WhatsApp-Nummer als from |
422 | contact_not_found | Kein Kontakt mit dieser to.contact_id |
422 | media_not_found | Keine Datei mit dieser media.media_id |
422 | invalid_media_url | media.url ist kein öffentlicher http(s)-Link |
422 | time_in_past | send_at oder expires_at liegt bereits in der Vergangenheit |
422 | number_not_found | from ist keine Nummer dieses Arbeitsbereichs |
422 | from_required | Kein from, und der Arbeitsbereich hat keine oder mehrere verbundene Nummern |
422 | message_rejected | Die Nachricht konnte nicht in die Warteschlange gestellt werden; message nennt den Grund |
429 | number_daily_cap_reached | Die Nummer hat in den letzten 24 Stunden 1.000 Nachrichten gesendet |
Ein abgelehntes Senden hinterlässt nichts: Es wird keine Nachricht gespeichert, es gibt also nichts zu stornieren. Fehler, die bei jedem Request auftreten können (Schlüssel, Scopes, Rate-Limits, Idempotency-Key), stehen auf der Fehlerseite.
An viele Empfänger senden#
https://wbiztool.com/api/v2/messages/batchBody: JSON (application/json)
Sendet dieselbe Nachricht an bis zu 1.000 Empfänger. Der Body ist derselbe wie bei Nachricht senden, nur dass to eine Liste von Empfängern ist.
- Alles oder nichts. Jeder Empfänger wird geprüft, bevor etwas in die Warteschlange kommt, und die gesamte Liste muss in die verbleibenden Nachrichten des Plans und in das Kontingent der sendenden Nummer für die nächsten 24 Stunden passen. Ist ein Empfänger fehlerhaft, wird nichts in die Warteschlange gestellt, und
fieldnennt ihn, zum Beispielto[3].phone. - Derselbe Empfänger doppelt erhält eine Nachricht.
- Die Antwort ist
202mitdata: eine Message pro Empfänger, in der Reihenfolge vonto.
curl -X POST https://wbiztool.com/api/v2/messages/batch \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: opening-hours-2026-10-20" \
-d '{
"from": 101,
"to": [
{ "phone": "+919876543210" },
{ "phone": "+447700900123" },
{ "group": "Bakery staff" }
],
"text": "We open at 10 tomorrow."
}'import os
import requests
recipients = ["+919876543210", "+447700900123"]
response = requests.post(
"https://wbiztool.com/api/v2/messages/batch",
headers={
"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}",
"Idempotency-Key": "opening-hours-2026-10-20",
},
json={
"from": 101,
"to": [{"phone": p} for p in recipients] + [{"group": "Bakery staff"}],
"text": "We open at 10 tomorrow.",
},
timeout=60,
)
body = response.json()
if response.status_code == 202:
for message in body["data"]:
print(message["id"], message["to"], message["status"])
else:
print("Refused:", body["error"]["code"], body["error"]["field"], body["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const recipients = ["+919876543210", "+447700900123"];
const response = await fetch("https://wbiztool.com/api/v2/messages/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "opening-hours-2026-10-20",
},
body: JSON.stringify({
from: 101,
to: [...recipients.map((phone) => ({ phone })), { group: "Bakery staff" }],
text: "We open at 10 tomorrow.",
}),
});
const body = await response.json();
if (response.status === 202) {
for (const message of body.data) console.log(message.id, message.to, message.status);
} else {
console.error("Refused:", body.error.code, body.error.field, body.error.message);
}<?php
$recipients = ['+919876543210', '+447700900123'];
$to = array_map(fn ($phone) => ['phone' => $phone], $recipients);
$to[] = ['group' => 'Bakery staff'];
$ch = curl_init('https://wbiztool.com/api/v2/messages/batch');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: opening-hours-2026-10-20',
],
CURLOPT_POSTFIELDS => json_encode(['from' => 101, 'to' => $to, 'text' => 'We open at 10 tomorrow.']),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 202) {
foreach ($body['data'] as $message) {
echo $message['id'] . ' ' . $message['status'] . "\n";
}
} else {
echo 'Refused: ' . $body['error']['code'] . ' ' . $body['error']['field'];
}Antwort (202), eine Message pro Empfänger; die zweite und dritte sehen aus wie die erste, mit to gleich {"phone": "+447700900123", …} und {"group": "Bakery staff", …}:
{
"data": [
{
"id": 9817264,
"status": "queued",
"from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
"to": { "phone": "+919876543210", "contact_id": 991 },
"text": "We open at 10 tomorrow.",
"media": null,
"send_at": null,
"expires_at": null,
"created_at": "2026-10-19T16:02:40.118Z",
"sent_at": null,
"error": null
}
]
}
Fehler beim Senden eines Batches#
Dieselben wie beim Senden einer Nachricht, mit der Position des Empfängers in field (to[0].phone), und zusätzlich:
| HTTP | Code | Wann |
|---|---|---|
400 | too_many_recipients | to hat mehr als 1.000 Einträge |
400 | validation_failed | to ist leer oder keine Liste |
402 | no_credits | Die Liste passt nicht in die verbleibenden Nachrichten: requested und remaining nennen die Differenz |
429 | number_daily_cap_reached | Die Liste passt nicht in das Kontingent der Nummer für die nächsten 24 Stunden: requested und room nennen die Anzahl |
Nachrichten auflisten#
https://wbiztool.com/api/v2/messagesDie Nachrichten des Arbeitsbereichs aus den letzten 90 Tagen, die neuesten zuerst, in Seiten. Dazu gehören auch Nachrichten aus dem Dashboard, aus Kampagnen, Erinnerungen, Integrationen und API v1, nicht nur die von API v2. Ein auf einige Nummern beschränkter Schlüssel sieht nur deren Nachrichten.
Query-Parameter
numberintegeroptionalNur Nachrichten von dieser Nummern-
id.statusstringoptionalNur Nachrichten mit diesem Status:
queued,scheduled,sent,delivered,read,failed,cancelledoderexpired.sincestringoptionalNur Nachrichten, die zu oder nach diesem Zeitpunkt erstellt wurden (ISO 8601 mit Offset).
untilstringoptionalNur Nachrichten, die vor diesem Zeitpunkt erstellt wurden (ISO 8601 mit Offset).
limitintegeroptionalNachrichten pro Seite, 1 bis 100 (Standard 25).
cursorstringoptionalDer
next_cursorder letzten Seite, mit denselben Filtern.
Filter lassen sich kombinieren. Schreiben Sie in einem Query-String das + eines Offsets als %2B (ein einfaches + kommt als Leerzeichen an, das ebenfalls als + gelesen wird), oder verwenden Sie Z.
curl -G https://wbiztool.com/api/v2/messages \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
--data-urlencode "status=failed" \
--data-urlencode "since=2026-10-01T00:00:00+05:30" \
--data-urlencode "limit=100"import os
import requests
headers = {"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"}
params = {"status": "failed", "since": "2026-10-01T00:00:00+05:30", "limit": 100}
failed = []
while True:
page = requests.get("https://wbiztool.com/api/v2/messages",
headers=headers, params=params, timeout=30).json()
failed += page["data"]
if not page["next_cursor"]:
break
params["cursor"] = page["next_cursor"] # same filters, next page
for message in failed:
print(message["id"], message["to"], message["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const params = new URLSearchParams({ status: "failed", since: "2026-10-01T00:00:00+05:30", limit: "100" });
const failed = [];
while (true) {
const response = await fetch(`https://wbiztool.com/api/v2/messages?${params}`, {
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const page = await response.json();
failed.push(...page.data);
if (!page.next_cursor) break;
params.set("cursor", page.next_cursor); // same filters, next page
}
for (const message of failed) console.log(message.id, message.to, message.error.message);<?php
$params = ['status' => 'failed', 'since' => '2026-10-01T00:00:00+05:30', 'limit' => 100];
$failed = [];
do {
$ch = curl_init('https://wbiztool.com/api/v2/messages?' . http_build_query($params));
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$page = json_decode(curl_exec($ch), true);
curl_close($ch);
$failed = array_merge($failed, $page['data']);
$params['cursor'] = $page['next_cursor']; // same filters, next page
} while ($page['next_cursor']);
foreach ($failed as $message) {
echo $message['id'] . ' ' . $message['error']['message'] . "\n";
}Die Antwort ist {"data": [Message, …], "next_cursor": "…" or null}.
Fehler beim Auflisten#
| HTTP | Code | Wann |
|---|---|---|
400 | validation_failed | number ist keine Nummern-ID, status ist keiner der Status, oder limit liegt nicht zwischen 1 und 100 |
400 | invalid_datetime | since oder until ist nicht ISO 8601 mit Offset |
400 | invalid_cursor | Der Cursor ist beschädigt oder wurde mit anderen Filtern erzeugt |
Nachricht abrufen#
https://wbiztool.com/api/v2/messages/{id}Eine Nachricht und ihr aktueller Status.
curl https://wbiztool.com/api/v2/messages/9817263 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"import os
import requests
response = requests.get(
"https://wbiztool.com/api/v2/messages/9817263",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
timeout=30,
)
message = response.json()
print(message["status"], message["sent_at"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages/9817263", {
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const message = await response.json();
console.log(message.status, message.sent_at);<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages/9817263');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$message = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $message['status'];Antwort (200), eine zugestellte Nachricht:
{
"id": 9817263,
"status": "delivered",
"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
}
Eine Nachricht, die es nicht gibt, die zu einem anderen Arbeitsbereich gehört oder (bei einem auf einige Nummern beschränkten Schlüssel) von einer anderen Nummer gesendet wurde, antwortet mit 404 message_not_found.
Nachricht stornieren#
https://wbiztool.com/api/v2/messages/{id}Storniert eine Nachricht, die noch wartet (queued oder scheduled), egal wer sie erstellt hat. Die Antwort ist 200 mit der Message, jetzt im Status cancelled. Ein Webhook-Endpunkt erhält message.cancelled.
Eine bereits gesendete Nachricht lässt sich nicht zurückholen. Eine Nachricht, die die sendende Nummer gerade in diesem Moment übernimmt, kann trotzdem noch gesendet werden. Prüfen Sie daher anschließend ihren Status, wenn es darauf ankommt.
curl -X DELETE https://wbiztool.com/api/v2/messages/9817263 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"import os
import requests
response = requests.delete(
"https://wbiztool.com/api/v2/messages/9817263",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
timeout=30,
)
body = response.json()
if response.status_code == 200:
print("Cancelled")
elif body["error"]["code"] == "not_cancellable":
print("Too late, it is", body["error"]["status"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages/9817263", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const body = await response.json();
if (response.ok) console.log("Cancelled");
else if (body.error.code === "not_cancellable") console.log("Too late, it is", body.error.status);<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages/9817263');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status === 200 ? 'Cancelled' : $body['error']['code'];Fehler beim Stornieren#
| HTTP | Code | Wann |
|---|---|---|
404 | message_not_found | Keine solche Nachricht für diesen Schlüssel |
409 | not_cancellable | Sie wartet nicht mehr; status im Fehler nennt ihren aktuellen Status, zum Beispiel sent |
Das Message-Objekt#
Jeder Vorgang auf dieser Seite antwortet mit Message-Objekten, und Webhook-Ereignisse enthalten eines in data.message.
| Feld | Typ | Beschreibung |
|---|---|---|
id | integer | Die ID der Nachricht. Damit rufen Sie die Nachricht ab oder stornieren sie. |
status | string | Wo sie gerade steht. Siehe Status. |
from | object | Die sendende Nummer: id, phone (ihre Ziffern mit Ländervorwahl, ohne +) und platform (whatsapp oder telegram). |
to | object | Der Empfänger: phone (mit +), group oder username sowie contact_id, der gespeicherte Kontakt, an den sie ging. Eine Telefonnummer oder Gruppe, an die zum ersten Mal gesendet wird, wird als Kontakt gespeichert. (contact_id ist nur bei einer Testnachricht an eine nicht gespeicherte Nummer null.) |
text | string | Der Text oder die Bildunterschrift; "", wenn es keinen gibt. |
media | object or null | type (image oder file), url und file_name (null bei Bildern). Die url kann ein Link sein, der nur begrenzte Zeit funktioniert; speichern Sie ihn nicht. |
send_at | string or null | Der geplante Zeitpunkt oder null für „sofort“. |
expires_at | string or null | Der Zeitpunkt, nach dem sie nicht mehr gesendet wird, oder null. |
created_at | string | Wann sie erstellt wurde. |
sent_at | string or null | Wann sie gesendet wurde, sobald das geschehen ist (sent, delivered oder read). |
error | object or null | Bei einer failed- oder expired-Nachricht nennt message den Grund, zum Beispiel File exceeds WhatsApp size limit (16MB max). Sonst null. |
Status#
| Status | Bedeutung |
|---|---|
queued | Wartet auf den Versand. |
scheduled | Wartet auf ihr send_at. |
sent | Von Ihrer Nummer gesendet (ein Haken in WhatsApp). |
delivered | Auf dem Telefon des Empfängers zugestellt (zwei Haken). |
read | Vom Empfänger gelesen (blaue Haken). |
failed | Sie konnte nicht gesendet werden; error.message nennt den Grund. |
cancelled | Vor dem Versand storniert: mit Nachricht stornieren, im Dashboard oder weil ihre Nummer oder Kampagne entfernt wurde. |
expired | Nicht vor ihrem expires_at gesendet. |
queued und scheduled können storniert werden. sent kann noch zu delivered und dann zu read werden. failed, cancelled, expired und read sind endgültig. Webhooks melden sent, failed, cancelled und expired; um delivered und read zu sehen, rufen Sie die Nachricht ab.
Empfänger#
to nimmt genau eines dieser Felder an:
| Feld | Beispiel | Wer sie erhält |
|---|---|---|
phone | {"phone": "+919876543210"} | Eine Telefonnummer im internationalen Format mit + (E.164). Leerzeichen und Bindestriche sind erlaubt. |
group | {"group": "Bakery staff"} | Eine WhatsApp-Gruppe, in der die sendende Nummer Mitglied ist, über ihren exakten Namen (bis zu 200 Zeichen). |
contact_id | {"contact_id": 991} | Ein im Arbeitsbereich gespeicherter Kontakt, über seine ID (etwa die contact_id einer früheren Nachricht). Sie geht an die Nummer oder Gruppe dieses Kontakts. |
username | {"username": "@asha_bakes"} | Ein Telegram-Benutzer: @name, ein Link t.me/name oder tg: und eine Benutzer-ID. Nur von einem Telegram-Konto aus, geben Sie also eines als from an (oder haben Sie genau eines verbunden). |
Für das Senden an Gruppen und über Telegram muss die sendende Nummer in dieser Gruppe sein bzw. diesen Benutzer erreichen können; Probleme dabei zeigen sich als failed-Nachricht, nicht als Fehler beim Senden.
Medien#
media sendet ein Bild oder eine Datei, mit text als Bildunterschrift. Geben Sie genau eines von url oder media_id an:
media.urlstringEntweder url oder media_idEin öffentlicher
http- oderhttps-Link zur Datei, bis zu 1.000 Zeichen. Links zu privaten oder lokalen Adressen werden mitinvalid_media_urlabgelehnt.media.media_idintegerEntweder url oder media_idEine Datei im Medienverzeichnis des Arbeitsbereichs, aus Datei hochladen. Laden Sie eine Datei einmal hoch und senden Sie sie so oft Sie möchten.
media.typestringoptionalimageoderfile. Ohne Angabe wird ein Link, der auf.jpg,.jpeg,.png,.gifoder.webpendet, als Bild gesendet und alles andere als Datei; einemedia_idverwendet den Typ, mit dem die Datei hochgeladen wurde.media.file_namestringoptionalFür eine
file: der Name, den der Empfänger sieht, zum Beispielinvoice-1042.pdf(bis zu 100 Zeichen). Ohne Angabe wird der Name aus dem Link oder der hochgeladenen Datei übernommen. Die Dateiendung bestimmt, wie die Datei gesendet wird, geben Sie also eine an. Bei Bildern ignoriert.
{
"to": { "phone": "+919876543210" },
"text": "Your invoice for order #1042",
"media": { "url": "https://example.com/invoices/1042.pdf", "type": "file", "file_name": "invoice-1042.pdf" }
}
Die Datei wird beim Senden der Nachricht abgerufen, nicht beim Aufruf der API. Ein defekter Link oder eine zu große Datei zeigt sich daher als failed-Nachricht mit dem Grund in error.message. Es gelten die Größen- und Typregeln von v1: siehe Bilder und Dateien senden.
Planung und Ablauf#
send_atplant die Nachricht. Sie bleibt bis dahinscheduledund kann storniert werden, bis sie gesendet wird. Schreiben Sie die Zeit mit Offset,2026-10-20T09:30:00+05:30bedeutet also 09:30 Uhr in Indien. Für wiederkehrende Nachrichten verwenden Sie Erinnerungen.expires_atist eine Frist: Wurde die Nachricht bis dahin nicht gesendet (etwa weil die Nummer abgemeldet war), wird sieexpired, statt verspätet gesendet zu werden. Nutzen Sie das für Einmalcodes, Lieferzeiten und Angebote. Ein Hintergrundjob markiert sie frühestens 30 Sekunden nach Fristablauf als abgelaufen. Verlassen Sie sich daher nicht auf Fristen unter einer Minute.- Beide müssen in der Zukunft liegen, und
expires_atmuss nachsend_atliegen.
