Cookies et mesure d'audience
Nous utilisons des cookies de mesure d'audience et marketing pour améliorer le site. Ils ne sont déposés qu'avec votre accord. Politique de cookies.
L'API vous permet d'envoyer et de vérifier des codes OTP via WhatsApp, ainsi que des messages marketing ou utilitaires à partir de vos templates. Chaque projet possède ses propres accès.
Connectez-vous au portail pour obtenir votre URL d'API et vos clés d'authentification.
Ouvrir Swagger UISpécification interactive (OpenAPI)
Une documentation technique complète et interactive des endpoints est disponible via Swagger UI : schémas de requêtes/réponses, modèles, codes d'erreur.
Toutes les requêtes vers les endpoints OTP nécessitent deux clés envoyées dans les en-têtes HTTP :
Vos clés donnent accès à votre projet. Ne les envoyez jamais dans une application mobile, un navigateur, un dépôt Git ou un message public. En cas de doute, régénérez-les depuis la configuration du projet.
Envoie un code OTP à 6 chiffres sur le numéro WhatsApp spécifié, ou un message marketing/utilitaire via un template du catalogue.
POST /v1/otp/send
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000"
}Pour envoyer un message non-OTP (utilitaire/marketing) avec des variables, précisez un template du catalogue et ses variables, dans l'ordre des placeholders :
{
"phone": "+22670000000",
"template": "order_update",
"template_language": "fr",
"variables": ["Awa", "#1042"]
}Si le template a un bouton URL dynamique (configuré dans le portail), fournissez son suffixe via "button_variable" - distinct des variables du corps, numérotation propre au bouton.
{
"phone": "+22670000000",
"template": "invite_friend",
"template_language": "fr",
"variables": ["Awa", "MonApp"],
"button_variable": "inv_abc123"
}Vous pouvez fournir votre propre code OTP via le champ "code" (4 à 8 chiffres). Sinon, la plateforme génère le code automatiquement.
{
"phone": "+22670000000",
"code": "483920"
}| Champ | Type | Description |
|---|---|---|
| phone | string | Numéro au format E.164 (+226XXXXXXXX) |
| template | string · optionnel | Nom d'un template du catalogue. Absent = template par défaut du projet. |
| template_language | string · optionnel | Langue du template (ex. fr, en_US). Absent = langue par défaut du template. |
| code | string · optionnel | Code OTP facultatif de 4 à 8 chiffres. S'il est absent, la plateforme le génère. Le code peut ensuite être vérifié via /otp/verify. |
| variables | string[] · optionnel | Valeurs du corps, dans l'ordre des placeholders {{1}}, {{2}}, {{3}}. Requis pour les templates utilitaire/marketing. Les positions auto-remplies par le serveur (code OTP généré, nom du projet) ne doivent pas être fournies. |
| button_variable | string · optionnel | Suffixe dynamique du bouton URL. Requis uniquement si le template a un bouton URL configuré en mode dynamique. |
{
"success": true,
"code": "OTP_SENT",
"message": "OTP sent",
"data": null
}| Code | Statut | Cause |
|---|---|---|
| AUTH_REQUIRED | 401 | En-têtes X-API-Key et/ou X-Auth-Key manquants |
| AUTH_INVALID | 401 | Clés invalides ou paire X-API-Key / X-Auth-Key non correspondante - le message précise la clé en cause |
| PLAN_INACTIVE | 403 | Plan inactif ou expiré - renouvelez depuis la rubrique Facturation |
| INVALID_PHONE | 400 | Numéro invalide (format E.164 requis) |
| TEMPLATE_NOT_FOUND | 400 | Template introuvable ou non disponible dans le catalogue |
| TEMPLATE_VARIABLES_MISMATCH | 400 | Nombre de variables incorrect pour ce template |
| BUTTON_VARIABLE_REQUIRED | 400 | Le suffixe dynamique du bouton URL ("button_variable") est requis pour ce template |
| RATE_LIMITED | 429 | Limite horaire du plan atteinte, ou 3 messages/10 min pour un même numéro (puis blocage 15 min) - le message précise la limite et le délai |
| QUOTA_EXCEEDED | 429 | Quota mensuel du plan épuisé - passez à un plan supérieur ou attendez le renouvellement |
| OTP_SEND_FAILED | 400 | Erreur d'envoi WhatsApp (numéro non enregistré sur WhatsApp) |
Vérifie un code OTP. Le code expire après 5 minutes. Au bout de 5 tentatives incorrectes, le numéro est bloqué 15 minutes.
POST /v1/otp/verify
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"code": "482931"
}| Champ | Type | Description |
|---|---|---|
| phone | string | Numéro E.164 (identique à celui utilisé pour l'envoi) |
| code | string | Code reçu par WhatsApp (4 à 8 chiffres) |
{
"success": true,
"code": "OTP_VERIFIED",
"message": "OTP verified",
"data": null
}| Code | Statut | Cause |
|---|---|---|
| OTP_INVALID | 400 | Code incorrect (le message indique les tentatives restantes), expiré ou déjà utilisé |
| RATE_LIMITED | 429 | Trop de tentatives incorrectes → numéro bloqué 15 min (le message indique le temps restant) |
Envoyez des messages WhatsApp (texte, image, document, audio, vidéo, template) vers n'importe quel numéro. Chaque message consomme des crédits du quota du projet.
Connectez-vous au portail pour obtenir votre URL d'API et vos clés d'authentification.
Toutes les requêtes exigent les en-têtes X-API-Key (clé du projet) et X-Auth-Key (clé du compte), disponibles dans le portail Projets → Gérer le projet → Configuration.
Les messages libres (texte, image, document, audio et vidéo) ne peuvent être envoyés que pendant les 24 heures suivant un message de l'utilisateur. En dehors de cette fenêtre, utilisez un template WhatsApp approuvé via /v1/otp/send ou /v1/messages/template.
Choisissez l'endpoint selon votre besoin. Les trois utilisent les mêmes en-têtes X-API-Key et X-Auth-Key.
| Endpoint | À utiliser pour | Fonctions principales |
|---|---|---|
| POST /v1/otp/send | OTP avec vérification du code | Code généré automatiquement ou fourni par vous, puis vérification avec /otp/verify |
| POST /v1/messages/template | Template WhatsApp déjà configuré | Variables, bouton dynamique, coupon, header texte ou localisation |
| POST /v1/messages/send | Texte, média ou template dans un seul endpoint | type text/image/document/audio/video/template et header_media dynamique |
| Endpoint | Description | Coût quota |
|---|---|---|
| POST /v1/messages/text | Message texte simple (max 4096 caractères) | 1 crédit |
| POST /v1/messages/image | Image avec URL publique ou media_id Meta + légende optionnelle (max 1024 caractères) | 2 crédits |
| POST /v1/messages/document | Document (PDF, etc.) avec URL publique ou media_id Meta + nom de fichier et légende optionnels | 2 crédits |
| POST /v1/messages/audio | Fichier audio avec URL publique ou media_id Meta | 2 crédits |
| POST /v1/messages/video | Vidéo avec URL publique ou media_id Meta + légende optionnelle (max 1024 caractères) | 2 crédits |
| POST /v1/messages/template | Template WhatsApp (UTILITY/MARKETING) avec variables du corps, bouton URL dynamique et bouton copy_code | 1 crédit |
| POST /v1/media/upload | Importe un média vers WhatsApp Cloud API (multipart/form-data) et retourne l'ID classique whatsapp_media_id ainsi que le handle Resumable whatsapp_handle (4::...) s'il est disponible. | - |
| GET /v1/media/:id | Récupère les métadonnées d'un média importé | - |
| DELETE /v1/media/:id | Supprime le média de Meta Cloud API et le marque comme SUPPRIMÉ en base | - |
Message texte simple (max 4096 caractères)
POST /v1/messages/text
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"text": "Bonjour, ceci est un message texte simple."
}Image avec URL publique ou media_id Meta + légende optionnelle (max 1024 caractères)
POST /v1/messages/image
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"image": { "url": "https://example.com/image.jpg" },
"caption": "Voici votre image"
}ℹ️ Vous pouvez aussi fournir un media_id Meta déjà uploadé via /v1/media/upload au lieu d'une URL.
Document (PDF, etc.) avec URL publique ou media_id Meta + nom de fichier et légende optionnels
POST /v1/messages/document
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"document": { "url": "https://example.com/document.pdf" },
"filename": "facture.pdf",
"caption": "Votre facture"
}Fichier audio avec URL publique ou media_id Meta
POST /v1/messages/audio
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"audio": { "url": "https://example.com/audio.mp3" }
}Vidéo avec URL publique ou media_id Meta + légende optionnelle (max 1024 caractères)
POST /v1/messages/video
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"video": { "url": "https://example.com/video.mp4" },
"caption": "Votre vidéo"
}Template WhatsApp (UTILITY/MARKETING) avec variables du corps, bouton URL dynamique et bouton copy_code
POST /v1/messages/template
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"phone": "+22670000000",
"template": "confirmation_commande",
"template_language": "fr",
"variables": ["Awa", "#1042"],
"button_variable": "inv_abc123",
"copy_code_value": "PROMO20"
}Variables dans l'ordre des placeholders {1}, {2}… - hors positions auto (code OTP, nom du projet). Bouton URL dynamique → button_variable requis. Bouton copy_code → copy_code_value requis (15 max).
Chaque zone du template possède son propre champ. Ne mélangez pas les variables du corps avec celles du header ou des boutons.
| Champ API | Emplacement | Utilisation |
|---|---|---|
variables | {{1}}, {{2}} | Valeurs des variables placées dans le corps du message, dans l'ordre des positions. |
header_param | header {{1}} | Valeur d'un header texte dynamique. Une seule variable de header est autorisée. |
button_variable | Suffixe après l'URL de base | Valeur ajoutée à un bouton URL configuré comme dynamique. |
copy_code_value | Bouton « copier le code » | Code du coupon à transmettre au moment de l'envoi, 15 caractères maximum. |
Pour un header IMAGE, VIDEO ou DOCUMENT dynamique, utilisez POST /v1/messages/send et header_media. Fournissez l'ID classique whatsapp_media_id pour l'envoi direct, ou une URL publique accessible par Meta.
POST /v1/messages/send
Content-Type: application/json
X-API-Key: sk_live_votre_cle_api
X-Auth-Key: au_live_votre_cle_auth
{
"type": "template",
"phone": "+22670000000",
"template": "promotion_client",
"template_language": "fr",
"variables": ["Awa", "20"],
"header_media": {
"type": "image",
"media_id": "123456789012345"
}
}Importe un média vers WhatsApp Cloud API (multipart/form-data) et retourne l'ID classique whatsapp_media_id ainsi que le handle Resumable whatsapp_handle (4::...) s'il est disponible.
curl -X POST https://api.exemple.com/v1/media/upload \ -H "X-API-Key: sk_live_votre_cle_api" \ -H "X-Auth-Key: au_live_votre_cle_auth" \ -F "file=@image.jpg"
Types supportés : image (jpeg, png, webp), document (pdf), audio (mpeg, ogg, mp4), vidéo (mp4, 3gpp). Taille max : 100 Mo.
Utilisez whatsapp_media_id pour envoyer un média. Si un whatsapp_handle est retourné, utilisez-le comme header_handle lors de la création d'un template. Ne partagez jamais ces identifiants en dehors de votre intégration.
{
"success": true,
"code": "MEDIA_UPLOADED",
"data": {
"media_id": "clmedia123",
"whatsapp_media_id": "123456789012345",
"whatsapp_handle": "4::aW1hZ2VfZnJhaXM",
"storage_url": "https://api.exemple.com/v1/media/files/clmedia123.jpg"
}
}// JavaScript (fetch)
const res = await fetch("https://api.exemple.com/v1/messages/text", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "sk_live_votre_cle_api",
"X-Auth-Key": "au_live_votre_cle_auth"
},
body: JSON.stringify({
phone: "+22670000000",
text: "Bonjour !"
})
});
const data = await res.json();| Champ | Type | Description |
|---|---|---|
| phone | string | Numéro destinataire format E.164 (ex. : +22670000000) |
| text | string | Contenu du message texte (max 4096 caractères) |
image | object | Source du média à fournir avec url ou media_id |
document | object | Source du média à fournir avec url ou media_id |
audio | object | Source du média à fournir avec url ou media_id |
video | object | Source du média à fournir avec url ou media_id |
| template | string | Nom du template dans le catalogue du portail |
| template_language | string | Langue du template (fr, en_US) |
| variables | string[] | Variables du corps dans l'ordre des placeholders {1}, {2}… (hors positions auto) |
| button_variable | string | Suffixe dynamique du bouton URL (requis si le template a un bouton URL dynamique) |
| copy_code_value | string | Code coupon pour bouton « copier le code » (requis si le template en a un, 15 caractères max.) |
| caption | string | Légende optionnelle (max 1024 caractères) |
| filename | string | Nom du fichier pour les documents (ex. : facture.pdf) |
{
"success": true,
"code": "MESSAGE_QUEUED",
"message": "Message mis en file d'attente",
"data": null
}| Code | Statut | Cause |
|---|---|---|
| AUTH_REQUIRED | 401 | En-têtes d'authentification manquants (X-API-Key / X-Auth-Key) |
| AUTH_INVALID | 401 | Clés invalides ou paire non correspondante |
| INVALID_PHONE | 400 | Numéro invalide (format E.164 requis) |
| INVALID_PAYLOAD | 400 | Corps de requête invalide ou champ manquant |
| TEMPLATE_NOT_FOUND | 400 | Template introuvable ou non disponible |
| TEMPLATE_VARIABLES_MISMATCH | 400 | Nombre de variables incorrect pour ce template |
| BUTTON_VARIABLE_REQUIRED | 400 | Le suffixe dynamique du bouton URL est requis |
| COPY_CODE_VALUE_REQUIRED | 400 | Le code coupon (copy_code_value) est requis pour ce template |
| QUOTA_EXCEEDED | 429 | Quota mensuel épuisé - passez à un plan supérieur |
| RATE_LIMITED | 429 | Limite horaire atteinte (1000 req/h/projet) |
| MEDIA_UPLOAD_FAILED | 400 | Échec de l'upload vers Meta Cloud API |
| INVALID_MIME_TYPE | 400 | Type MIME non supporté |
| FILE_TOO_LARGE | 413 | Fichier trop volumineux (> 100 Mo) |
Recevez un appel HTTP POST sur votre serveur dès qu'un OTP est vérifié avec succès. Idéal pour déclencher une action côté serveur (activer un compte, débloquer un paiement…) sans interroger l'API en boucle.
Définissez l'URL de callback dans le portail : Projets → Gérer le projet → Configuration → Webhook de vérification. Conservez la clé de signature dans votre serveur et ne la publiez jamais.
POST https://votre-serveur.com/otp-callback
Content-Type: application/json
X-OTP-Signature: sha256=<hmac>
{
"event": "otp.verified",
"project_id": "clx0a1b2c3...",
"phone": "+22670000000",
"phone_hash": "a3f9c8...",
"phone_masked": "+226****000",
"timestamp": "2026-07-23T10:00:00.000Z"
}| Champ | Type | Description |
|---|---|---|
| event | string | Type d'événement (toujours "otp.verified") |
| project_id | string | Identifiant du projet concerné |
| phone | string | Numéro complet vérifié (format E.164) |
| phone_hash | string | Identifiant technique anonymisé du numéro, utile pour rapprocher vos événements |
| phone_masked | string | Numéro masqué pour l'affichage |
| timestamp | string | Horodatage ISO 8601 de la vérification |
Chaque appel contient une signature X-OTP-Signature. Vérifiez cette signature avec la clé de votre projet avant de traiter l'événement, afin de confirmer son authenticité.
import crypto from "crypto";
// secret affiché dans le portail (Projet → Configuration → Webhook)
const expected = "sha256=" + crypto
.createHmac("sha256", SECRET)
.update(rawBody) // corps BRUT, non re-sérialisé
.digest("hex");
const ok = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(req.headers["x-otp-signature"] || "")
);
if (!ok) return res.status(401).end();Ces endpoints nécessitent une session authentifiée via le portail (cookie client_session).
Quota global du compte.
{ "data": { "used": 42, "limit": 1000, "plan": { "name": "PRO" }, "reset_at": "2026-06-01T00:00:00.000Z" } }Paramètre optionnel period : 7d, 30d (défaut), month ou all.
{ "data": { "sent": 42, "verified": 38, "failed": 7, "failedDelivery": 4, "failedVerification": 3, "queued": 2, "successRate": 91, "period": "30d" } }failed est le total des échecs ; il se décompose en failedDelivery (message non parti) et failedVerification (code incorrect ou expiré saisi par l'utilisateur final). successRate est le taux de livraison : sent / (sent + failedDelivery). Les envois en file d'attente et les échecs de vérification en sont exclus, et le champ vaut null tant qu'aucun envoi n'est terminé sur la période.
{ "data": { "items": [ { "phone_masked": "+22670******000", "action": "SENT", "created_at": "..." } ], "total": 42 } }curl -X POST https://api.exemple.com/v1/otp/send \
-H "X-API-Key: sk_live_votre_cle_api" \
-H "X-Auth-Key: au_live_votre_cle_auth" \
-H "Content-Type: application/json" \
-d '{"phone": "+22670000000"}'curl -X POST https://api.exemple.com/v1/otp/verify \
-H "X-API-Key: sk_live_votre_cle_api" \
-H "X-Auth-Key: au_live_votre_cle_auth" \
-H "Content-Type: application/json" \
-d '{"phone": "+22670000000", "code": "482931"}'const API_URL = "https://api.exemple.com/v1";
const HEADERS = {
"Content-Type": "application/json",
"X-API-Key": "sk_live_...",
"X-Auth-Key": "au_live_..."
};
async function sendOtp(phone) {
const res = await fetch(`${API_URL}/otp/send`, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({ phone })
});
const data = await res.json();
if (!data.success) throw new Error(data.code);
return data;
}
async function verifyOtp(phone, code) {
const res = await fetch(`${API_URL}/otp/verify`, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({ phone, code })
});
const data = await res.json();
if (!data.success) throw new Error(data.code);
return data;
}
// Usage
await sendOtp("+22670000000");
// L'utilisateur saisit le code reçu sur WhatsApp
await verifyOtp("+22670000000", "482931");import requests
API_URL = "https://api.exemple.com/v1"
HEADERS = {
"Content-Type": "application/json",
"X-API-Key": "sk_live_...",
"X-Auth-Key": "au_live_..."
}
def send_otp(phone: str) -> dict:
res = requests.post(f"{API_URL}/otp/send", headers=HEADERS, json={"phone": phone})
data = res.json()
if not data.get("success"):
raise Exception(data.get("code"))
return data
def verify_otp(phone: str, code: str) -> dict:
res = requests.post(f"{API_URL}/otp/verify", headers=HEADERS, json={"phone": phone, "code": code})
data = res.json()
if not data.get("success"):
raise Exception(data.get("code"))
return data
# Usage
send_otp("+22670000000")
# L'utilisateur saisit le code reçu sur WhatsApp
verify_otp("+22670000000", "482931")| Limite | Valeur | Description |
|---|---|---|
| Tentatives vérification | 5 | Blocage 15 min |
| Expiration OTP | 5 min | Code invalide après délai |
| Envois OTP | Selon le plan | Débit horaire par projet, défini par votre plan (+ 3 OTP/10 min par numéro) |
| Requêtes globales | 100/min | Par IP |
Toutes les erreurs suivent le même format :
{
"success": false,
"code": "ERROR_CODE",
"message": "Description lisible",
"data": null
}| Code | Statut HTTP | Cause |
|---|---|---|
| AUTH_REQUIRED | 401 | En-têtes d'authentification manquants (X-API-Key / X-Auth-Key) |
| AUTH_INVALID | 401 | Clés invalides ou paire non correspondante - le message précise la clé en cause |
| PLAN_INACTIVE | 403 | Plan inactif ou expiré - renouvelez depuis le portail |
| INVALID_PAYLOAD | 400 | Corps de requête invalide ou champ manquant |
| INVALID_PHONE | 400 | Numéro de téléphone invalide (format E.164 requis) |
| OTP_INVALID | 400 | Code incorrect, expiré (5 min) ou déjà utilisé - le message précise la cause et les tentatives restantes |
| OTP_SEND_FAILED | 400 | Échec d'envoi WhatsApp (numéro non joignable) |
| RATE_LIMITED | 429 | Trop de requêtes ou trop de tentatives incorrectes - le message précise la limite et le délai de déblocage |
| QUOTA_EXCEEDED | 429 | Quota mensuel du plan épuisé - upgrade ou renouvellement requis |
| SERVER_ERROR | 500 | Erreur interne - réessayez ou contactez le support |
Lorsqu'un envoi OTP WhatsApp échoue car le numéro n'est pas enregistré sur WhatsApp, le fallback SMS envoie automatiquement le code par SMS. Cette fonctionnalité est désactivée par défaut et doit être activée dans les paramètres de chaque projet.
Dans le portail, allez dans Projets → Gérer le projet → Fallback SMS → Activez le toggle. Les tarifs par pays sont visibles dans cette même section.
Le coût de chaque SMS fallback dépend du pays du destinataire. Les tarifs sont gérés par l'administrateur et visibles dans le portail. Si un pays n'est pas configuré ou son tarif est inactif, le SMS n'est pas envoyé.
Envoyez des SMS en masse à vos utilisateurs. Les campagnes SMS sont séparées des campagnes WhatsApp et gérées intégralement par la plateforme.
Les endpoints de campagnes SMS nécessitent une session authentifiée via le portail (cookie client_session).
| Endpoint | Méthode | Description |
|---|---|---|
| /account/sms-campaigns | GET | Lister les campagnes |
| /account/sms-campaigns | POST | Créer une campagne |
| /account/sms-campaigns/:id/start | POST | Démarrer une campagne |
| /account/sms-campaigns/:id/cancel | POST | Annuler une campagne |
| /account/sms-campaigns/:id/retry | POST | Relancer les échecs |
| /account/sms-campaigns/:id | DELETE | Supprimer une campagne |
Lors de la création, vous pouvez spécifier une date d'envoi future (scheduled_at). La campagne passera automatiquement en mode RUNNING à la date prévue.
POST /account/sms-campaigns
Content-Type: application/json
{
"name": "Promo Black Friday",
"message": "Profitez de -50% sur toute la boutique !",
"phone_numbers": ["+22670000001", "+22670000002"],
"scheduled_at": "2026-11-24T08:00:00.000Z" // optionnel
}DRAFT - DRAFT - Créée, pas encore lancée
SCHEDULED - SCHEDULED - Planifiée pour une date future
RUNNING - RUNNING - En cours d'envoi
COMPLETED - COMPLETED - Tous les SMS envoyés
PARTIAL - PARTIAL - Certains SMS ont échoué
CANCELLED - CANCELLED - Annulée
Les tarifs SMS sont définis par pays et par préfixe téléphonique. Chaque SMS envoyé via le fallback ou une campagne SMS consomme le nombre de crédits correspondant au pays du destinataire.
Le préfixe du numéro de téléphone est comparé aux tarifs configurés. Le nombre de crédits débités correspond au tarif du pays. Si le pays n'est pas trouvé ou le tarif est inactif, le SMS est bloqué.
Consultez la page tarifs SMS dans le portail pour voir la liste des pays configurés et leurs tarifs. Les pays non configurés bloquent l'envoi SMS.
| Pays | Préfixe | Coût SMS |
|---|---|---|
| 🇧🇫 Burkina Faso | +226 | 3 crédits |
| 🇨🇮 Côte d'Ivoire | +225 | 4 crédits |
| 🇳🇪 Niger | +227 | 4 crédits |
| 🇨🇲 Cameroun | +237 | 7 crédits |
| 🇨🇩 RD Congo | +243 | 7 crédits |
Un SMS vers un numéro BF (+226...) coûte 3 crédits. Un SMS vers un numéro CM (+237...) coûte 10 crédits. Le crédit est déduit du quota du projet.
Dans le portail, allez dans le menu Campagnes SMS - vos campagnes affichent le coût par envoi. Dans les paramètres de chaque projet, la section Fallback SMS affiche les tarifs par pays.