Documentation API Wazzap AI - Envoi de Messages WhatsApp
Table des matières
- Introduction
- Prérequis et obtention de la clé API
- Authentification
- Envoi de messages
- Format des numéros de téléphone
- Envoi immédiat ou en attente (waitForSend)
- Désactivation de la réponse automatique de l'IA
- Tracking et Statistiques
- Rate Limiting et Queue
- Exemples de code
- Gestion des erreurs
- Bonnes pratiques
Introduction
Cette API permet d'envoyer des messages WhatsApp de manière programmatique en utilisant une clé API.
Caractéristiques principales
- Authentification sécurisée par clé API
- Envoi de messages texte
- Rate limiting : 100 requêtes/minute par clé (par défaut)
- Détection automatique du compte WhatsApp
- Vérification et correction automatique des numéros (voir Format des numéros)
Prérequis et obtention de la clé API
Étape 1 : Avoir un compte Premium Wazzap AI
Vous ou vos utilisateurs devez disposer d'un abonnement Premium actif sur Wazzap AI.
Étape 2 : Créer un agent IA
- Connectez-vous à votre compte Wazzap AI
- Créez un nouvel agent IA depuis votre dashboard
- Configurez votre agent selon vos besoins
Étape 3 : Connecter votre numéro WhatsApp
- Depuis la page de votre agent, connectez votre numéro WhatsApp
- Scannez le QR Code avec WhatsApp
- Attendez que la connexion soit établie
Étape 4 : Générer votre clé API
- Rendez-vous dans Paramètres de votre compte
- Accédez à la section API Keys
- Cliquez sur Générer une nouvelle clé
- Donnez un nom à votre clé (ex: "Intégration Maketou")
- Sélectionnez l'agent WhatsApp à associer
- Copiez immédiatement la clé (elle ne sera plus affichée)
⚠️ Important : Conservez cette clé en lieu sûr, elle ne sera affichée qu'une seule fois !
Authentification
Toutes les requêtes nécessitent un header Authorization avec le format Bearer :
Authorization: Bearer wz_votre_cle_api_complète
Format de la clé : wz_xxxxxxxxxxxxxxxxxxxxxx (32 caractères après le préfixe)
Langue des réponses
Les messages de l'API (champ message, et errorMessage dans /stats) sont en français par défaut. Pour les recevoir en anglais, ajoutez l'en-tête Accept-Language: en à vos requêtes. Les codes (errorCode, status) ne changent jamais selon la langue : testez-les dans votre code plutôt que le texte du message.
Envoi de messages
Endpoint
POST https://api21.wazzap.ai/api/wazzap/send-message
Headers requis
Authorization: Bearer wz_votre_cle_api
Content-Type: application/json
Body de la requête
{
"phoneNumber": "+33612345678",
"message": "Votre message ici",
"disableAiResponse": false
}
Paramètres
| Paramètre | Type | Requis | Description | Exemple |
|---|---|---|---|---|
phoneNumber |
string |
Oui | Numéro du destinataire, au format international avec l'indicatif pays (voir Format des numéros) | "+33612345678" |
message |
string |
Oui | Message texte à envoyer | "Bonjour !" |
disableAiResponse |
boolean |
Non | Désactive la réponse automatique de l'IA pour ce contact (défaut : false) |
true |
waitForSend |
boolean |
Non | Attendre l'envoi réel avant de répondre, pour obtenir le messageId ou l'erreur exacte (défaut : false) |
true |
simulateTyping |
boolean |
Non | Affiche « écrit… » chez le destinataire avant l'envoi, durée proportionnelle au message (défaut : true) |
false |
delayMs |
number |
Non | Délai avant l'envoi, en millisecondes (défaut : 0) |
2000 |
Réponse en cas de succès (200)
Par défaut, l'API répond immédiatement : le numéro a été vérifié et le message est accepté, puis envoyé en arrière-plan (après delayMs et la simulation de frappe). Le messageId n'est donc pas encore connu :
{
"success": true,
"code": 200,
"message": "Message accepté — envoi en cours (simulation de frappe)",
"data": {
"status": "queued",
"messageId": null,
"phoneNumber": "+33612345678",
"formattedPhoneNumber": "33612345678",
"provider": "v2.5",
"agentId": "agent_123",
"organizationId": "org_456",
"aiResponseDisabled": false
}
}
Avec "waitForSend": true, la réponse arrive une fois le message réellement envoyé, avec son messageId :
{
"success": true,
"code": 200,
"message": "Message envoyé avec succès",
"data": {
"status": "sent",
"messageId": "3EB0XXXXXXXXXXXX",
"phoneNumber": "+33612345678",
"formattedPhoneNumber": "33612345678",
"provider": "v2.5"
}
}
Réponse en cas d'erreur (4xx/5xx)
{
"success": false,
"code": 400,
"errorCode": "MISSING_PHONE_NUMBER",
"message": "Le paramètre 'phoneNumber' est requis"
}
Format des numéros de téléphone
Le bon format
Envoyez toujours le numéro complet au format international, avec l'indicatif pays :
| Pays | ✅ Format attendu | ❌ À éviter |
|---|---|---|
| France | +33612345678 ou 33612345678 |
0612345678 |
| Côte d'Ivoire | +2250701020304 |
0701020304 |
| Sénégal | +221771234567 |
771234567 |
| Mexique | +5213112345678 |
3112345678 |
Les espaces, tirets, parenthèses et le + sont acceptés et retirés automatiquement : "+33 6 12 34 56 78" fonctionne.
Vérification et correction automatiques
Avant chaque envoi, Wazzap vérifie auprès de WhatsApp que le numéro existe, puis envoie au numéro WhatsApp réel :
- Le numéro tel quel est vérifié en premier. WhatsApp reconnaît les variantes connues : au Mexique,
523112345678est enregistré sous5213112345678, le message part au bon numéro. - Préfixe international
00:0033612345678est lu comme33612345678. - Indicatif pays manquant ou format national : si le numéro n'existe pas tel quel, il est relu dans le pays du numéro WhatsApp connecté à votre agent. Avec un agent connecté sur un numéro français,
0612345678devient33612345678.
⚠️ La correction du point 3 ne fonctionne que si le destinataire est du même pays que le numéro WhatsApp de votre agent. Pour un contact à l'étranger, l'indicatif pays est indispensable.
Le champ formattedPhoneNumber de la réponse indique le numéro réellement utilisé.
Numéro absent de WhatsApp
Si aucune variante du numéro n'existe sur WhatsApp, rien n'est envoyé et l'API répond :
{
"success": false,
"code": 400,
"errorCode": "NUMBER_NOT_ON_WHATSAPP",
"message": "Ce numéro n'est pas sur WhatsApp. Vérifiez-le et indiquez le numéro complet avec l'indicatif pays (ex. 33612345678)."
}
Vérifiez le numéro dans votre base (indicatif pays, chiffre manquant) avant de réessayer.
Envoi immédiat ou en attente (waitForSend)
waitForSend: false (défaut) |
waitForSend: true |
|
|---|---|---|
| Réponse | Immédiate, status: "queued" |
Après l'envoi réel, status: "sent" |
messageId |
null |
Identifiant WhatsApp du message |
| Numéro absent de WhatsApp | Erreur 400 immédiate |
Erreur 400 immédiate |
| Échec de l'envoi après acceptation | Visible ensuite dans /stats (FAILED) |
Erreur directement dans la réponse |
| Usage conseillé | Notifications en volume | Intégrations CRM qui doivent savoir si chaque message est parti |
{
"phoneNumber": "+33612345678",
"message": "Votre commande est prête",
"waitForSend": true
}
Temps de réponse et timeout conseillé
| Mode | Temps de réponse habituel | Timeout conseillé côté client |
|---|---|---|
waitForSend: false (défaut) |
1 à 3 secondes | 15 secondes |
waitForSend: true |
Quelques secondes de plus (simulation de frappe proportionnelle au message, puis envoi) | 30 secondes, ou "simulateTyping": false |
Une erreur de session (SESSION_NOT_CONNECTED) ou de restriction WhatsApp (WHATSAPP_RESTRICTED) est renvoyée immédiatement : inutile de réessayer en boucle.
Désactivation de la réponse automatique de l'IA
Qu'est-ce que disableAiResponse ?
Le paramètre disableAiResponse permet de désactiver la prise en charge de la conversation automatiquement par l'agent IA qui est connecter a votre compte whatsapp pour un contact spécifique. Lorsqu'il est activé (true), le contact passe en mode humain, ce qui signifie que :
- Votre message sera envoyé normalement
- Le contact sera créé et lié à votre agent
- L'IA ne répondra PAS automatiquement aux messages de ce contact
- Vous pourrez répondre manuellement depuis votre dashboard Wazzap AI ou depuis votre WhatsApp depuis votre smartphone.
Cas d'usage typiques
1. Support VIP ou escalade
// Client important qui nécessite une attention humaine
await envoyerMessage(
'+3300000000',
'Bonjour M. Dupont, un conseiller va vous répondre sous peu.',
{ disableAiResponse: true }
);
2. Notifications one-way sans attendre de réponse
// Notification de livraison sans nécessiter de réponse IA
await envoyerMessage(
'+33698765432',
'Votre colis est arrivé au point relais.',
{ disableAiResponse: true }
);
3. Campagnes marketing personnalisées
// Envoyer une offre spéciale sans activer l'IA
const clients = ['+33601...', '+33602...'];
for (const client of clients) {
await envoyerMessage(
client,
'Offre exclusive : -20% ce weekend !',
{ disableAiResponse: true }
);
}
Exemple complet
const response = await fetch('https://api21.wazzap.ai/api/wazzap/send-message', {
method: 'POST',
headers: {
'Authorization': 'Bearer wz_votre_cle_api',
'Content-Type': 'application/json'
},
body: JSON.stringify({
phoneNumber: '+3300000000',
message: 'Bonjour, un humain va vous répondre rapidement.',
disableAiResponse: true // L'IA ne répondra pas automatiquement
})
});
const data = await response.json();
console.log('AI Response Disabled:', data.data.aiResponseDisabled); // true
Comment réactiver l'IA pour un contact ?
Pour réactiver la réponse automatique de l'IA pour un contact :
- Connectez-vous à votre dashboard Wazzap AI
- Accédez à la conversation du contact
- Cliquez sur le bouton "Réactiver l'IA" ou similaire
Ou envoyez simplement un nouveau message sans le paramètre disableAiResponse (ou avec false) :
await envoyerMessage(
'+3300000000',
'L\'IA est maintenant réactivée',
{ disableAiResponse: false } // L'IA va répondre normalement
);
Important à savoir
- Le paramètre s'applique par contact et persiste jusqu'à réactivation
- Un contact avec
disableAiResponse: truesera marqué comme "Mode humain" dans votre dashboard - Vous pouvez toujours répondre manuellement via le dashboard
- L'IA reste active pour tous les autres contacts
Tracking et Statistiques
Endpoint de statistiques
Consultez en temps réel les performances de votre clé API :
GET https://api21.wazzap.ai/api/wazzap/stats
Authorization: Bearer wz_votre_cle_api
Réponse
{
"success": true,
"data": {
"apiKey": {
"id": "cm9xxx...",
"name": "Production API",
"agentId": "cm9yyy..."
},
"stats": {
"totalRequests": 1250,
"successRequests": 1200,
"failedRequests": 50,
"successRate": 96.0
},
"queue": {
"processing": 2,
"pending": 5,
"maxConcurrent": 4
},
"rateLimit": {
"limit": 100,
"current": 45,
"remaining": 55,
"resetAt": "2025-10-15T15:30:00.000Z"
},
"recentRequests": [
{
"id": "req_xxx",
"status": "COMPLETED",
"statusCode": 200,
"duration": 234,
"provider": "v2.5",
"errorMessage": null,
"startedAt": "2025-10-15T15:25:00.000Z",
"completedAt": "2025-10-15T15:25:00.234Z"
}
// ... 9 autres requêtes récentes
]
}
}
Métriques disponibles
| Métrique | Description |
|---|---|
totalRequests |
Nombre total de requêtes effectuées |
successRequests |
Nombre de requêtes réussies |
failedRequests |
Nombre de requêtes échouées |
successRate |
Taux de succès en pourcentage |
queue.processing |
Nombre de requêtes en cours de traitement |
queue.pending |
Nombre de requêtes en attente |
rateLimit.current |
Nombre de requêtes dans la fenêtre actuelle |
rateLimit.remaining |
Nombre de requêtes restantes avant limite |
recentRequests[].status |
COMPLETED = message envoyé, FAILED = message non envoyé |
recentRequests[].errorMessage |
Raison de l'échec quand status vaut FAILED (ex. numéro absent de WhatsApp) |
ℹ️ Avec un envoi
queued(par défaut), la requête est d'abord enregistrée comme acceptée. Si l'envoi en arrière-plan échoue ensuite, elle passe enFAILEDdans/statsavec sa raison danserrorMessage.
Exemple de monitoring
async function surveillerAPI() {
const response = await fetch('https://api21.wazzap.ai/api/wazzap/stats', {
headers: {
'Authorization': 'Bearer wz_votre_cle_api'
}
});
const { data } = await response.json();
console.log(`Taux de succès: ${data.stats.successRate}%`);
console.log(`Queue: ${data.queue.processing}/${data.queue.maxConcurrent} en cours, ${data.queue.pending} en attente`);
console.log(`Rate limit: ${data.rateLimit.remaining}/${data.rateLimit.limit} restantes`);
// Alerte si problème détecté
if (data.stats.successRate < 90) {
console.warn('Taux de succès faible - vérifier la connexion WhatsApp');
}
}
// Surveiller toutes les 30 secondes
setInterval(surveillerAPI, 30000);
Rate Limiting et Queue
Système de Queue Automatique
Pour garantir la stabilité, chaque clé API dispose d'une queue intelligente qui traite maximum 4 requêtes en parallèle.
Comment ça fonctionne ?
Vos requêtes → [Queue] → [4 slots de traitement] → Envoi WhatsApp
↑
Maximum 4 simultanées
Les autres attendent
Rate Limiting
Chaque clé API a des limites configurables :
| Paramètre | Défaut | Description |
|---|---|---|
rateLimit |
100 | Requêtes par fenêtre |
rateLimitWindow |
60s | Durée de la fenêtre |
Par défaut : 100 requêtes par minute
Gestion du dépassement
Si vous dépassez la limite :
{
"success": false,
"code": 429,
"errorCode": "RATE_LIMIT_EXCEEDED",
"message": "Trop de requêtes. Veuillez patienter.",
"rateLimit": {
"limit": 100,
"remaining": 0,
"reset": "2025-10-15T15:30:00.000Z"
}
}
Bonnes pratiques pour éviter le rate limiting
// 1. Vérifier avant d'envoyer en masse
async function envoyerSiPossible(phoneNumber, message) {
const stats = await obtenirStats();
if (stats.data.rateLimit.remaining < 5) {
const resetTime = new Date(stats.data.rateLimit.resetAt);
const waitTime = resetTime.getTime() - Date.now();
console.log(`Attente de ${Math.ceil(waitTime/1000)}s...`);
await new Promise(r => setTimeout(r, waitTime));
}
return await envoyerMessage(phoneNumber, message);
}
// 2. Espacer les envois automatiquement
async function envoyerAvecEspacement(contacts, intervalMs = 700) {
for (const contact of contacts) {
await envoyerMessage(contact.phone, contact.message);
await new Promise(r => setTimeout(r, intervalMs));
}
}
Augmenter votre rate limit
Pour augmenter votre rate limit, contactez votre administrateur ou passez à un plan supérieur.
Exemples de code
Envoi de message simple
Gestion des erreurs
Codes d'erreur
| Code HTTP | Code erreur | Description | Solution |
|---|---|---|---|
200 |
- | Succès | - |
400 |
MISSING_PHONE_NUMBER |
Numéro manquant | Ajouter phoneNumber |
400 |
MISSING_MESSAGE |
Message manquant | Ajouter message |
400 |
NUMBER_NOT_ON_WHATSAPP |
Le numéro n'existe pas sur WhatsApp, même après correction | Vérifier le numéro et son indicatif pays |
400 |
INVALID_DELAY |
delayMs n'est pas un nombre positif |
Corriger delayMs |
400 |
NO_WHATSAPP_PROVIDER |
Aucun WhatsApp connecté | Connecter WhatsApp |
401 |
API_KEY_MISSING |
Clé manquante | Ajouter le header Authorization |
401 |
API_KEY_INVALID_FORMAT / API_KEY_INVALID_PREFIX |
Clé mal formée | Copier la clé complète (wz_…) |
401 |
API_KEY_INVALID_OR_EXPIRED |
Clé invalide | Vérifier la clé |
403 |
NO_WHATSAPP_ACCOUNT_CONNECTED |
WhatsApp non connecté | Reconnecter WhatsApp |
403 |
WHATSAPP_RESTRICTED |
WhatsApp a temporairement restreint le numéro (protection anti-spam) | Attendre quelques heures, éviter les envois en masse vers de nouveaux contacts |
409 |
SESSION_NOT_CONNECTED |
La session WhatsApp de l'agent s'est déconnectée | Rescanner le QR code dans Wazzap AI |
404 |
AGENT_NOT_FOUND |
Agent non trouvé | Vérifier l'agent |
429 |
RATE_LIMIT_EXCEEDED |
Trop de requêtes | Attendre la fin de la fenêtre (rateLimit.reset) |
500 |
MESSAGE_SEND_ERROR |
Erreur serveur | Réessayer |
Exemples d'erreurs
Clé API manquante
{
"success": false,
"code": 401,
"errorCode": "API_KEY_MISSING",
"message": "Clé API manquante. Utilisez le header 'Authorization: Bearer YOUR_API_KEY'"
}
Numéro de téléphone manquant
{
"success": false,
"code": 400,
"errorCode": "MISSING_PHONE_NUMBER",
"message": "Le paramètre 'phoneNumber' est requis"
}
Numéro absent de WhatsApp
{
"success": false,
"code": 400,
"errorCode": "NUMBER_NOT_ON_WHATSAPP",
"message": "Ce numéro n'est pas sur WhatsApp. Vérifiez-le et indiquez le numéro complet avec l'indicatif pays (ex. 33612345678)."
}
Compte WhatsApp non connecté
{
"success": false,
"code": 403,
"errorCode": "NO_WHATSAPP_ACCOUNT_CONNECTED",
"message": "Aucun compte WhatsApp connecté pour cet agent"
}
Bonnes pratiques
1. Sécurité
À faire :
- Stocker la clé dans des variables d'environnement
- Ne jamais exposer la clé côté client
- Utiliser HTTPS uniquement
- Régénérer la clé si compromise
À ne pas faire :
- Hardcoder la clé dans le code
- Committer la clé dans Git
- Partager la clé publiquement
Exemple sécurisé :
// .env
WAZZAP_API_KEY=wz_votre_cle_api
WAZZAP_API_URL=https://api21.wazzap.ai
// config.js
require('dotenv').config();
module.exports = {
apiKey: process.env.WAZZAP_API_KEY,
apiUrl: process.env.WAZZAP_API_URL
};
2. Rate limiting
- Par défaut : 100 requêtes par minute et par clé API
- Implémenter une queue pour les envois en masse
3. Validation des données
// Normaliser le numéro au format international (E.164)
function validerNumero(phoneNumber) {
let cleaned = phoneNumber.replace(/[^\d+]/g, '');
if (cleaned.startsWith('00')) cleaned = '+' + cleaned.slice(2);
if (!/^\+?\d{8,15}$/.test(cleaned)) {
throw new Error('Numéro invalide');
}
// Un numéro commençant par 0 est au format national : ajoutez l'indicatif pays
if (/^0\d/.test(cleaned)) {
throw new Error('Indicatif pays manquant (ex. +33 pour la France)');
}
return cleaned.startsWith('+') ? cleaned : '+' + cleaned;
}
// Gérer le cas « numéro absent de WhatsApp »
const result = await envoyerMessage(numero, message);
if (result.errorCode === 'NUMBER_NOT_ON_WHATSAPP') {
// Marquer le contact comme « pas de WhatsApp » dans votre CRM
}
// Valider le message
function validerMessage(message) {
if (!message || typeof message !== 'string') {
throw new Error('Message invalide');
}
if (message.length > 4096) {
throw new Error('Message trop long (max 4096 caractères)');
}
return message.trim();
}
📚 Cas d'usage
Envoi de notifications personnalisées
const clients = [
{ nom: 'Jean Dupont', phone: '+3300000000', commande: '#12345' },
{ nom: 'Marie Martin', phone: '+33698765432', commande: '#12346' }
];
async function envoyerNotifications(clients) {
for (const client of clients) {
const message = `
Bonjour ${client.nom},
Votre commande ${client.commande} a été confirmée.
Merci !
`.trim();
await envoyerMessage(client.phone, message);
await new Promise(r => setTimeout(r, 3000)); // Attendre 3s
}
}
Support
Problèmes courants
Le message n'arrive pas :
- Vérifier que le numéro est au format international avec l'indicatif pays (voir Format des numéros)
- Consulter
/stats: une requête enFAILEDindique la raison danserrorMessage - Utiliser
"waitForSend": truepour obtenir le résultat de l'envoi directement dans la réponse - Vérifier que le numéro WhatsApp de votre agent est bien connecté (version 2.5) dans Wazzap AI
"Rate limit exceeded" :
- Réduire la fréquence d'envoi
- Attendre 1 minute
- Implémenter une queue
Clé API invalide :
- Vérifier que vous avez bien copié la clé complète
- Vérifier que la clé n'a pas expiré
- Régénérer une nouvelle clé si nécessaire
Contact
Pour toute question :
- Consultez d'abord cette documentation
- Contactez nous à l'adresse contact@Wazzap.ai
