ChinqIT VerifyChinqIT Verify

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 bulk pour la rétrocompatibilité — les événements webhook bulk.completed et 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 .xlsx ou .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.

  1. 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).
  2. 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.
  3. À l'heure choisie, elle s'envoie automatiquement ; l'écran de résultats en direct montre son envoi et sa fin.
  4. 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 (raison cancelled) — 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,error de 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ètreTypeObligatoireDescription
recipientsarrayOuiTableau d'objets destinataires (max 50 000)
recipients[].phonestringOuiNuméro au format international
recipients[].messagestringOuiTexte 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ètreTypeObligatoireDescription
batchIdstringOuiID 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

StatutDescription
pendingLot créé, en attente de traitement
scheduledDiffusion créée avec un scheduledAt futur ; s'envoie automatiquement à cette heure
processingMessages en cours de mise en file et d'envoi
completedTous les messages envoyés avec succès
partialCertains messages réussis, d'autres échoués
failedTous les messages ont échoué

Statuts des messages

StatutDescription
pendingMessage en attente de traitement
queuedMessage en file d'attente
sentMessage 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

CodeDescription
NO_CREDITSolde insuffisant
BILLING_FAILEDÉchec de la transaction de facturation
INVALID_DESTINATIONFormat de numéro invalide
QUEUE_ERRORÉchec de la mise en file du message

Bonnes pratiques

  1. Validez les numéros avant l'envoi pour éviter des coûts inutiles
  2. Interrogez le statut pour suivre la livraison
  3. Gérez les échecs partiels — certains messages peuvent réussir et d'autres échouer
  4. Taille des lots — Gardez les lots sous 10 000 pour de meilleures performances
  5. Nouvelles tentatives — Les messages échoués sont automatiquement réessayés jusqu'à 4 fois

On this page