API de messagerie
API d'envoi de messages
Envoyez un texte, une image ou un document WhatsApp à un numéro de téléphone depuis votre numéro WhatsApp connecté. Utilisez-la pour les confirmations de commande, les rappels de paiement, les alertes et les réponses du support.
https://wbiztool.com/api/v1/send_msg/Corps: JSON, champs de formulaire, ou multipart/form-data pour téléverser un fichier
Le message est mis en file d'attente et envoyé depuis votre numéro WhatsApp en quelques instants. La réponse vous fournit un msg_id que vous pouvez utiliser pour vérifier son statut.
Exemple rapide#
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": 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/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"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: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
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 = [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'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 => ['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');
}Remplacez 12345, YOUR_API_KEY et 678 par vos propres valeurs. Consultez Authentification pour savoir où les trouver.
Paramètres de la requête#
Authentification
client_idintegerobligatoireVotre ID client API, dans Paramètres → Clés API.
api_keystringobligatoireVotre clé API, sur cette même page.
whatsapp_clientintegerObligatoire si vous avez plusieurs numérosID du numéro WhatsApp depuis lequel envoyer, dans les paramètres WhatsApp. Si vous l'omettez et que votre espace de travail possède exactement un numéro connecté, c'est ce numéro qui est utilisé.
Destinataire et message
phonestringobligatoireLe numéro WhatsApp du destinataire, chiffres uniquement. Les espaces,
+,-,.et les parenthèses sont supprimés automatiquement. Envoyez le numéro soit avec son indicatif pays (919876543210), soit sans celui-ci (9876543210) accompagné decountry_code. Avec des champs de formulaire, n'incluez pas de0initial de préfixe national (09876543210) : il n'est pas supprimé avant l'ajout decountry_code, et le message part donc vers le mauvais numéro. Les requêtes JSON le suppriment pour vous.country_codestringfacultatifIndicatif téléphonique du pays sans
+, par exemple91pour l'Inde ou1pour les États-Unis. Il est ajouté devantphone, sauf si le numéro commence déjà par celui-ci. Exception : avec91, un numéro à 10 chiffres reçoit toujours le préfixe. Avec les autres indicatifs, un numéro local qui commence par les mêmes chiffres ne reçoit pas de préfixe : envoyez-le donc avec l'indicatif pays inclus.msg_typeintegerfacultatif0texte (par défaut),1image,2fichier ou document.msgstringObligatoire lorsque msg_type vaut 0Texte du message, jusqu'à 3 000 caractères. Pour les images et les fichiers, il s'agit de la légende, qui peut être vide. La mise en forme WhatsApp fonctionne :
*bold*,_italic_,~strikethrough~.messageest accepté comme alias.
Images et fichiers
img_urlstringObligatoire lorsque msg_type vaut 1 et qu'aucun fichier n'est téléverséURL publique
httpouhttpsde l'image.file_urlstringObligatoire lorsque msg_type vaut 2 et qu'aucun fichier n'est téléverséURL publique
httpouhttpsà partir de laquelle le fichier peut être téléchargé directement.filefilefacultatifTéléversez l'image ou le fichier au lieu de fournir une URL. Envoyez la requête en
multipart/form-dataavec le champ nomméfile.file_namestringfacultatifNom du fichier affiché au destinataire, par exemple
invoice-4821.pdf. Son extension détermine la façon dont le fichier est envoyé : incluez-en donc une. Il est envoyé en minuscules, les caractères comme& : ? * $ ;sont remplacés par_, et il est tronqué à 150 caractères. Si vous l'omettez, le nom est tiré de l'URL ou du fichier téléversé.
Options d'envoi
expire_after_secondsintegerfacultatifMarque le message comme expiré (statut
4) s'il n'a pas été envoyé dans ce nombre de secondes, par exemple3600pour une heure. Utile pour les messages urgents comme les heures de livraison estimées. Une tâche en arrière-plan s'en charge au moins 30 secondes après l'échéance : ne comptez donc pas dessus pour des délais inférieurs à une minute.webhookstringfacultatifURL qui reçoit un
POSTlorsque le message est envoyé ou échoue. Consultez Webhook.
Envoyer des images et des fichiers#
Limites de téléchargement pour img_url et file_url :
- L'URL doit être publique :
httpouhttps, accessible depuis Internet. Jusqu'à 5 redirections sont suivies, et chacune doit aussi mener à une adresse publique. - Les fichiers liés peuvent peser jusqu'à 100 Mo. Le serveur doit commencer à répondre dans les 45 secondes et ne pas rester bloqué plus longtemps.
- Le fichier est récupéré au moment où vous appelez l'API : un lien cassé échoue donc immédiatement avec
Invalid file url.
Extensions prises en charge : .pdf, .xlsx, .xls, .txt, .docx, .png, .jpg, .jpeg, .webp, .mp3, .mpga, .m4a, .mp4, .webm.
Ces vérifications ont lieu au moment de l'envoi du message, et non lors de l'appel à l'API : ces échecs n'apparaissent donc que dans Statut du message et dans le webhook :
| Problème | error dans Statut du message |
|---|---|
Une image (msg_type 1) de plus de 16 Mo | File exceeds WhatsApp size limit (16MB max) |
Une vidéo (.mp4, .webm) de plus de 64 Mo, ou un fichier vide | File exceeds WhatsApp size limit (…) |
Un fichier .ogg, ou un fichier .wav envoyé comme image (msg_type 1) | File type not supported |
L'audio WAV et OGG n'est pas pris en charge. Un fichier .wav envoyé comme fichier (msg_type 2) n'est pas rejeté, mais arrive sous le nom recording.wav.pdf. Convertissez d'abord l'audio en .mp3 ou .m4a.
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);Utiliser les clients officiels#
Les clients Python et Node.js appellent cet endpoint pour vous.
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)Les erreurs lèvent requests.HTTPError. Lisez la raison avec 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);Réponse#
Une requête réussie renvoie le code HTTP 200 :
{
"status": 1,
"message": "Created",
"msg_id": 9817263
}
| Champ | Type | Description |
|---|---|---|
status | integer | 1 si le message a été mis en file d'attente, 0 si la requête a échoué. |
message | string | Created en cas de succès, sinon l'erreur. |
msg_id | integer | ID du message en file d'attente. Enregistrez-le pour vérifier son statut plus tard. Présent uniquement en cas de succès. |
"status": 1 signifie que le message a été mis en file d'attente, pas qu'il a déjà atteint le destinataire. Utilisez un webhook ou Statut du message pour confirmer qu'il a été envoyé.
Erreurs#
Les erreurs renvoient le code HTTP 400 avec status à 0 (Account Disabled n'a pas de champ status) :
{ "status": 0, "message": "Msg cant be null" }
| Message | Comment corriger |
|---|---|
Auth Error - Please send correct API key and Client id | Envoyez une api_key non vide. |
Invalid client id. | Envoyez client_id sous forme de nombre. |
Auth Error: invalid api key | Vérifiez que la clé existe, n'a pas été supprimée et appartient à ce client_id. |
Either phone or group_name parameter is required | Ajoutez phone. |
Please provide either phone OR group_name, not both | Supprimez l'un des deux. |
Invalid phone number | phone ne doit contenir que des chiffres (de 6 à 17), éventuellement précédés de +. |
Invalid Contact Number "…" | Une fois l'indicatif pays ajouté, le numéro doit comporter de 6 à 15 chiffres. |
Msg cant be null | Les messages texte (msg_type 0) nécessitent msg. |
Message length is too long | Limitez msg à 3 000 caractères maximum. |
Image Url Can't be null | Pour msg_type 1, envoyez img_url ou téléversez un file. |
File Url Can't be null | Pour msg_type 2, envoyez file_url ou téléversez un file. |
Invalid file url, Can't download / Invalid file url | L'URL n'est pas publique, le délai a expiré ou le fichier dépasse 100 Mo. |
Invalid whatsapp client | Cet ID whatsapp_client ne fait pas partie de votre espace de travail. |
Invalid whatsapp client id. | Envoyez whatsapp_client. Il est obligatoire lorsque votre espace de travail possède plusieurs numéros connectés. |
Not enough credits | Votre forfait n'a plus de messages disponibles. |
Demo Account can not access apis | Utilisez un compte standard. |
Account Disabled | Votre compte est désactivé. Contactez le support. |
Invalid JSON format: … | Le corps JSON n'est pas valide, souvent à cause d'une virgule finale ou d'un saut de ligne non échappé dans msg. Utilisez \n pour les retours à la ligne. |
Un message mis en file d'attente peut encore échouer au moment de son envoi, par exemple avec File exceeds WhatsApp size limit (…). Ces erreurs n'apparaissent jamais dans cette réponse. Consultez Envoyer des images et des fichiers et vérifiez le statut du message.
Webhook#
Si vous transmettez webhook, Wbiztool envoie un POST à cette URL lorsque le message est envoyé ou échoue. Le corps est encodé comme un formulaire (application/x-www-form-urlencoded), et non en JSON :
msg_id=9817263&status=SENT
| Champ | Valeurs |
|---|---|
msg_id | Le msg_id renvoyé lors de l'envoi du message. |
status | SENT ou FAILED |
Répondez avec n'importe quel code 2xx. Si votre endpoint dépasse le délai (au bout de 3 secondes) ou renvoie un code 5xx, l'appel est retenté jusqu'à 3 fois au total. Une réponse 4xx n'est pas retentée. Aucun webhook n'est envoyé lorsqu'un message est annulé ou expire ; utilisez Statut du message dans ces cas.
Conseils#
- Numéros de téléphone : stockez les numéros au format international et envoyez-les avec
country_codepour éviter toute ambiguïté. - Retours à la ligne en JSON : écrivez-les sous la forme
\ndansmsg. Un saut de ligne brut rend le JSON invalide. - Gardez votre numéro connecté : les messages sont envoyés depuis votre numéro WhatsApp, qui doit donc rester connecté dans les paramètres WhatsApp.
- Nombreux destinataires : pour envoyer le même message à plusieurs numéros en une seule requête, utilisez Envoyer à plusieurs numéros. Pour les campagnes importantes, téléversez plutôt un tableur depuis la page Campagnes.
