Diffusions (API Bulk SMS)
Envoyez des SMS à plusieurs destinataires en un seul appel API.
Remarque : La fonctionnalité du tableau de bord s'appelle Diffusions (Broadcasts / البث). L'API sous-jacente conserve l'ancien chemin
bulkpour la rétrocompatibilité — les événements webhookbulk.completedet les endpoints/api/v2/bulk/*sont inchangés.
L'authentification et l'URL de base sont documentées dans la Référence API.
Composer (tableau de bord)
Le compositeur de diffusions du tableau de bord suit un parcours guidé en trois étapes :
- 1 · Destinataires — téléversez un tableur
.xlsxou.xls, ou collez des numéros. Ce sont les deux parcours principaux. Une audience enregistrée est accessible via un raccourci secondaire. Vérifiez les compteurs valides, invalides et doublons avant de continuer. - 2 · Message — rédigez un message commun, utilisé par défaut pour chaque destinataire envoyable. Si le tableur contient une colonne
message, ouvrez Messages du tableur (avancé) pour activer ses messages par ligne en lecture seule. Les jetons de personnalisation peuvent utiliser les autres colonnes du tableur. Un aperçu téléphone neutre et en direct se met à jour pendant la saisie. - 3 · Vérifier et envoyer — confirmez les destinataires et les compteurs, le message et son aperçu, le coût estimé, le solde actuel, le solde après envoi et l'heure. L'envoi immédiat est sélectionné par défaut ; la programmation est une option secondaire sous Plus d'options.
Les audiences enregistrées sont stockées par compte (jusqu'à 50 000 destinataires chacune) et peuvent être réutilisées entre les diffusions. L'API publique est inchangée — voir la référence API pour /api/v2/bulk/*.
Modèles et personnalisation (tableau de bord)
Le compositeur peut démarrer à partir d'un modèle enregistré (⚡ Démarrer à partir d'un modèle). Les modèles sont propres à chaque compte : créez-les à partir d'un message composé ou rédigez-les dans le gestionnaire de modèles, et organisez-les par catégorie (rappel, annonce, promotion, autre).
Les messages peuvent inclure des jetons de personnalisation : tout {mot} dans le message est remplacé par la valeur de la colonne correspondante de votre fichier de destinataires. Par exemple, une colonne first_name vous permet d'envoyer « Bonjour {first_name}, votre rendez-vous est confirmé ». Les jetons courants comme {first_name}, {amount} ou {link} peuvent être insérés en un clic. Lorsqu'une ligne de destinataire manque de valeur, le jeton reste tel quel dans le message envoyé et le compositeur vous avertit avant l'envoi.
Programmation (tableau de bord)
Les diffusions programmées sont une option secondaire du tableau de bord, sous Plus d'options — l'API publique envoie toujours immédiatement.
- Dans le composeur, ouvrez Plus d'options, passez Quand de Envoyer maintenant à Programmer, puis choisissez une date et une heure (entre 1 minute et 30 jours à l'avance).
- La diffusion est prépayée au moment de la programmation — même coût et même contrôle de solde qu'un envoi immédiat — et passe à l'état
scheduled. - À l'heure choisie, elle s'envoie automatiquement ; l'écran de résultats en direct montre son envoi et sa fin.
- Tant qu'elle n'est pas partie, vous pouvez l'annuler depuis l'écran de résultats en direct. L'annulation rembourse la totalité du prépaiement et marque la diffusion
failed(raisoncancelled) — voir Facturation.
Résultats en direct et historique
Dès qu'une diffusion démarre, sa page de détail devient un écran de résultats en direct :
- Taux de livraison — la part des destinataires valides dont le message a été écrit chez l'opérateur (ex. 97,4 %). « Envoyé » signifie accepté par l'opérateur, pas que le téléphone du destinataire a confirmé la réception (les accusés SMPP ne sont pas agrégés aux diffusions).
- Compteurs — Envoyés / En file d'attente / Échecs / Invalides, mis à jour toutes les 2 secondes pendant l'envoi.
- Envois par minute — un graphique des messages envoyés chaque minute, dérivé côté client pendant que la page est ouverte.
- Message envoyé — un aperçu du contenu du message, capturé à la création de la diffusion.
- Durée — temps écoulé pendant l'envoi, temps total une fois terminé.
- Télécharger le CSV — un rapport
phone,status,errorde chaque destinataire, conforme à ce que l'écran affiche au moment du téléchargement.
La page d'historique (« Vos diffusions ») affiche quatre cartes de synthèse — diffusions, messages envoyés, taux de livraison, MRU dépensés — limitées au filtre de statut actif, suivies d'un tableau de diffusions nommées (nom, type de modèle, taille de l'audience, taux de livraison, coût, statut, date). Cliquez sur une diffusion pour ouvrir ses résultats en direct.
Suivi administrateur (tableau de bord)
L'équipe support dispose d'une page Diffusions dans l'administration qui reprend les métriques de l'historique client :
- Quatre cartes de synthèse — diffusions, messages envoyés, taux de livraison, MRU dépensés — limitées aux filtres actifs (statut, période, client) et toujours cohérentes avec le tableau.
- Filtre de période — aujourd'hui, 7 derniers jours, 30 derniers jours, mois en cours — appliqué au tableau et aux cartes (bornes calculées dans le fuseau horaire du serveur).
- Tableau des diffusions — nom (ou ID de lot), client, audience, taux de livraison, coût, statut, date (la date d'envoi programmé pour les diffusions
scheduled). Recherche par nom, ID de lot ou client.
L'écran administrateur ne permet pas d'ouvrir le détail d'une diffusion : les écrans de résultats en direct restent réservés au compte client propriétaire.
Vue d'ensemble
L'API Bulk SMS permet d'envoyer des messages à plusieurs destinataires efficacement. Chaque destinataire peut recevoir un message personnalisé.
Envoyer des messages en masse
POST /api/v2/bulk/send
Envoyer des SMS à plusieurs destinataires en une seule requête.
Corps de la requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
recipients | array | Oui | Tableau d'objets destinataires (max 50 000) |
recipients[].phone | string | Oui | Numéro au format international |
recipients[].message | string | Oui | Texte du message pour ce destinataire |
Exemple de requête
{
"recipients": [
{
"phone": "+22238089336",
"message": "Bonjour Jean, votre commande est prête !"
},
{
"phone": "+22238089337",
"message": "Bonjour Sarah, votre commande est prête !"
}
]
}Réponse de succès (202 Accepted)
{
"success": true,
"message": "Bulk batch created successfully",
"batchId": "550e8400-e29b-41d4-a716-446655440000",
"totalValid": 2,
"totalInvalid": 0,
"cost": 0.04,
"totalParts": 2,
"pricePerMessage": 0.02,
"status": "processing"
}Réponses d'erreur
400 Bad Request — Erreur de validation
{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["recipients"],
"message": "Array must contain at least 1 element(s)"
}
]
}402 Payment Required — Solde insuffisant
{
"success": false,
"message": "Insufficient balance",
"details": {
"requiredAmount": 0.04,
"validRecipients": 2,
"invalidRecipients": 0
}
}400 Bad Request — Aucun destinataire valide
{
"success": false,
"message": "No valid recipients found",
"invalidRecipients": [
{
"phone": "invalid",
"reason": "Invalid phone number format"
}
]
}Statut d'un lot
GET /api/v2/bulk/status/
Récupérer le statut d'un envoi en masse.
Paramètres URL
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
batchId | string | Oui | ID du lot retourné par la requête d'envoi |
Exemple de réponse
{
"success": true,
"batch": {
"batchId": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"totalMessages": 100,
"validMessages": 98,
"invalidCount": 2,
"successfulCount": 45,
"failedCount": 5,
"totalCost": 1.96,
"totalParts": 100,
"progress": 51,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:31:30.000Z",
"messages": [
{
"messageId": "msg-123",
"phone": "+22238089336",
"status": "sent",
"cost": 0.02,
"parts": 1
},
{
"messageId": "msg-124",
"phone": "+22238089337",
"status": "failed",
"error": "Invalid destination address"
}
]
}
}Valeurs de statut
| Statut | Description |
|---|---|
pending | Lot créé, en attente de traitement |
scheduled | Diffusion créée avec un scheduledAt futur ; s'envoie automatiquement à cette heure |
processing | Messages en cours de mise en file et d'envoi |
completed | Tous les messages envoyés avec succès |
partial | Certains messages réussis, d'autres échoués |
failed | Tous les messages ont échoué |
Statuts des messages
| Statut | Description |
|---|---|
pending | Message en attente de traitement |
queued | Message en file d'attente |
sent | Message envoyé avec succès |
failed | Échec de l'envoi |
Limites de débit
- Maximum 50 000 destinataires par lot pour des messages d'une seule partie SMS (~160 caractères ASCII / ~70 caractères UCS-2)
- Les limites de débit par seconde de l'API standard ne s'appliquent pas aux endpoints bulk (voir Référence API)
- Les messages sont mis en file et traités de façon asynchrone
Le corps de la requête est également limité à 20 Mo, si bien que les messages
multi-parties ou de longueur maximale réduisent la capacité effective du lot. En
règle générale, le corps doit respecter
destinataires × (octets du message encodé + ~40 octets de surcharge JSON par destinataire) ≤ 20 Mo,
soit environ destinataires ≈ (20 Mo − surcharge) / (longueur du message encodé + ~40 octets) :
- 50 000 destinataires avec des messages ASCII d'une partie de 160 caractères tiennent confortablement (~10 Mo)
- Les messages de longueur maximale (jusqu'à 2 000 octets encodés) ne laissent place qu'à ~10 000 destinataires
Format des numéros
Voir la Référence API (SMS / Mauritanie) pour les formats de numéros acceptés.
Facturation
Chaque message que nous soumettons à l'opérateur vous est facturé. L'opérateur nous facture à la réception, et non à l'acceptation : un message qu'il reçoit puis refuse reste facturé.
- Envoyé — l'opérateur a accepté la soumission. Facturé.
- Rejeté — l'opérateur a refusé la soumission, par exemple parce que le numéro n'est pas une destination valide. Facturé, car l'opérateur nous l'a facturé.
- Échoué — le message n'a jamais été soumis : notre passerelle n'a pas pu joindre l'opérateur, ou votre solde était insuffisant. Non facturé ; tout montant déjà débité est remboursé.
Le coût est par message, selon sa longueur et son encodage : un corps plus long, ou du texte hors GSM-7 comme l'arabe ou les emojis, se divise en plusieurs parties, et un SMS multi-parties est facturé par partie. Les fonds de l'ensemble du lot sont débités d'avance à la création du lot.
Les messages destinés à un numéro que l'opérateur a rejeté comme invalide au cours de la dernière heure ne sont pas resoumis, et ne sont pas facturés.
Exemples de code
JavaScript/Node.js
const response = await fetch('https://sms.chinqit.com/api/v2/bulk/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key_here'
},
body: JSON.stringify({
recipients: [
{ phone: '+22238089336', message: 'Bonjour !' },
{ phone: '+22238089337', message: 'Salut !' }
]
})
});
const result = await response.json();
console.log(result.batchId);Python
import requests
response = requests.post(
'https://sms.chinqit.com/api/v2/bulk/send',
headers={
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key_here'
},
json={
'recipients': [
{'phone': '+22238089336', 'message': 'Bonjour !'},
{'phone': '+22238089337', 'message': 'Salut !'}
]
}
)
result = response.json()
print(result['batchId'])PHP
<?php
$ch = curl_init('https://sms.chinqit.com/api/v2/bulk/send');
$data = [
'recipients' => [
['phone' => '+22238089336', 'message' => 'Bonjour !'],
['phone' => '+22238089337', 'message' => 'Salut !']
]
];
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-API-Key: your_api_key_here'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo $result['batchId'];cURL
curl -X POST https://sms.chinqit.com/api/v2/bulk/send \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"recipients": [
{"phone": "+22238089336", "message": "Bonjour !"},
{"phone": "+22238089337", "message": "Salut !"}
]
}'Interrogation du statut
Après l'envoi d'un lot, interrogez le endpoint de statut toutes les 2 à 5 secondes jusqu'à la fin du traitement :
const checkStatus = async (batchId) => {
const response = await fetch(`https://sms.chinqit.com/api/v2/bulk/status/${batchId}`, {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const result = await response.json();
if (['completed', 'failed', 'partial'].includes(result.batch.status)) {
console.log('Lot terminé !', result.batch);
return result.batch;
}
console.log(`Progression : ${result.batch.progress}%`);
setTimeout(() => checkStatus(batchId), 2000);
};Codes d'erreur
| Code | Description |
|---|---|
NO_CREDIT | Solde insuffisant |
BILLING_FAILED | Échec de la transaction de facturation |
INVALID_DESTINATION | Format de numéro invalide |
QUEUE_ERROR | Échec de la mise en file du message |
Bonnes pratiques
- Validez les numéros avant l'envoi pour éviter des coûts inutiles
- Interrogez le statut pour suivre la livraison
- Gérez les échecs partiels — certains messages peuvent réussir et d'autres échouer
- Taille des lots — Gardez les lots sous 10 000 pour de meilleures performances
- Nouvelles tentatives — Les messages échoués sont automatiquement réessayés jusqu'à 4 fois