Tout savoir sur MAYASEND.
Guide d'utilisation de la plateforme, référence de l'API REST v1 et bonnes pratiques pour envoyer vos SMS, messages WhatsApp et emails.
Introduction
MAYASEND est une plateforme d'envoi de messages en masse et transactionnels sur trois canaux : SMS, WhatsApp et Email. Un solde unique en FCFA alimente les trois canaux : vous rechargez une fois, puis vous envoyez là où vos clients vous lisent.
- Application web : campagnes, contacts, modèles, factures, statistiques, clés API.
- Application mobile : recharge, campagnes et suivi depuis votre téléphone.
- API REST : intégrez l'envoi dans votre site, votre application ou votre logiciel métier.
Démarrage rapide
- Créez votre compte sur la page d'inscription, puis confirmez votre email avec le code reçu.
- Rechargez votre solde (voir ci-dessous). Le crédit est ajouté dès que le paiement est confirmé.
- Faites approuver un Sender ID (nom d'expéditeur SMS).
- Importez vos contacts ou saisissez vos numéros.
- Lancez une campagne ou appelez l'API : le solde est débité à l'envoi.
Solde & recharge
Le paiement s'effectue en ligne via KKiaPay (Mobile Money et autres moyens proposés dans le widget). Lors de l'achat, vous choisissez le type de pack :
| Pack | Pour | Quantité minimale |
|---|---|---|
| SMS + WhatsApp | Envois SMS et messages WhatsApp | 200 messages |
| Campagnes et envois d'emails | 1 000 emails |
Après paiement, MAYASEND interroge directement KKiaPay pour confirmer la transaction : votre solde est crédité même si vous fermez la page. Une facture est générée dans votre espace. Les messages en échec définitif sont remboursés automatiquement.
Canaux & tarifs
| Canal | Usage | Tarif indicatif |
|---|---|---|
| 📱 SMS | Alertes, codes, promotions. Facturé par segment (160 caractères GSM-7, 70 en Unicode). | à partir de 25 FCFA |
| Messages via modèles approuvés, conversations avec vos clients. | 35 FCFA | |
| Newsletters, factures, notifications. | 3 FCFA |
Les tarifs exacts dépendent de votre forfait ; la page Tarifs présente la grille à jour. Votre solde indique aussi l'équivalent en messages pour chaque canal.
Sender ID
Le Sender ID est le nom affiché comme expéditeur du SMS (ex. MAYA). Faites la demande depuis Sender ID dans votre espace : une fois approuvé par l'équipe, il devient utilisable pour vos campagnes et via l'API (champ sender). Si vous n'en précisez pas, le premier Sender ID approuvé est utilisé.
- Choisissez un nom court, lisible et lié à votre marque.
Contacts & listes
Importez vos contacts depuis un fichier CSV ou ajoutez-les un à un, puis organisez-les en listes pour cibler vos campagnes. Les numéros sont normalisés automatiquement (format local 01XXXXXXXX ou international +229…) et les doublons sont ignorés.
- Un contact peut avoir un numéro, un numéro WhatsApp et un email.
- Les contacts désinscrits (par exemple via le lien de désinscription des emails) ne sont plus contactés.
Campagnes
Une campagne envoie un même message à une liste, immédiatement ou à une date programmée.
- Choisissez le canal (SMS, WhatsApp ou Email) et la liste de destinataires.
- Rédigez le message ; vous voyez le nombre de segments et le coût estimé avant d'envoyer.
- Envoyez maintenant ou programmez. Le montant est réservé, puis ajusté selon les messages réellement envoyés.
- Suivez les statuts (envoyé, remis, échec) et, pour l'email, les ouvertures et les clics.
Le système peut basculer automatiquement vers un fournisseur de secours en cas d'incident, sans intervention de votre part.
Modèles WhatsApp
Pour écrire le premier à un client sur WhatsApp, Meta impose l'usage d'un modèle de message approuvé. Créez vos modèles depuis Modèles : variables {{1}}, {{2}}…, catégorie (utilitaire, marketing, authentification), puis soumettez-les à validation. Le statut passe de en attente à approuvé ou refusé (avec le motif).
Emailing
- Un lien de désinscription est ajouté automatiquement à chaque email.
- Le suivi des ouvertures et des clics est disponible dans les statistiques de campagne.
- Les adresses désinscrites ou invalides sont ignorées, et leur envoi est remboursé.
- Pour une bonne délivrabilité, utilisez un expéditeur identifiable et évitez les contenus uniquement composés d'images.
Application mobile
Connectez-vous avec vos identifiants web. Vous pouvez recharger votre solde (en choisissant le pack SMS + WhatsApp ou Email), lancer et suivre vos campagnes, gérer vos contacts et consulter vos factures. En cas de maintenance de la plateforme, l'application affiche un écran d'information avec le message de l'équipe et un bouton « Réessayer ». Voir la page Application mobile.
Revendeurs
Les revendeurs disposent d'un espace dédié pour gérer leurs clients, suivre leurs ventes et leurs commissions. Détails sur la page Revendeurs.
API v1 — Introduction
L'API est une API REST JSON. URL de base :
https://mayasend.bconsultingsarl.com/api/v1
- Toutes les requêtes se font en HTTPS.
- Les corps de requête sont en JSON :
Content-Type: application/json. - Chaque réponse contient
successet, en cas d'erreur, un objeterroravectypeetmessage. - Chaque réponse porte un identifiant de requête (
request_id) à communiquer au support en cas de question.
Clés API
L'accès à l'API est activé à la demande depuis votre espace client (menu « Clés API »). Vous obtenez d'abord un trio de clés test ; les clés live se demandent ensuite. Elles ne s'affichent qu'après confirmation de votre mot de passe.
| Clé | Format | Rôle |
|---|---|---|
| Publique | mk_test_pk_… | Identifie votre compte. Autorise uniquement GET /ping. En-tête X-Public-Key. |
| Privée | mk_test_sk_… | Authentifie vos appels. Côté serveur uniquement. |
| Secrète | mk_test_ss_… | Signe vos requêtes (HMAC-SHA256). Ne circule jamais sur le réseau. |
Pour la production, les clés commencent par mk_live_. Vous pouvez restreindre chaque clé à des adresses IP et à certains canaux, la révoquer ou la régénérer à tout moment.
Authentification
Envoyez votre clé privée dans l'en-tête Authorization :
Authorization: Bearer mk_live_sk_xxxxxxxxxxxxxxxx
L'en-tête X-API-Key: mk_…_sk_… est accepté comme alternative.
Signature des requêtes (HMAC)
Si vous activez « signature obligatoire » pour votre environnement, chaque requête doit porter deux en-têtes supplémentaires :
X-Timestamp: 1760000000
X-Signature: hex( HMAC_SHA256( clé_secrète, TIMESTAMP + "." + METHODE + "." + CHEMIN + "." + CORPS ) )
TIMESTAMP: secondes UNIX, tolérance de ±5 minutes.CHEMIN: par exemple/api/v1/sms/send.CORPS: le texte JSON exact envoyé (vide pour un GET).
$ts = time();
$body = json_encode(['to' => '0197000001', 'message' => 'Bonjour', 'sender' => 'MAYA']);
$sig = hash_hmac('sha256', $ts . '.POST./api/v1/sms/send.' . $body, 'mk_live_ss_xxxxxxxx');
// En-têtes : X-Timestamp: $ts X-Signature: $sig
const crypto = require('crypto');
const ts = Math.floor(Date.now() / 1000);
const body = JSON.stringify({ to: '0197000001', message: 'Bonjour', sender: 'MAYA' });
const sig = crypto.createHmac('sha256', 'mk_live_ss_xxxxxxxx')
.update(`${ts}.POST./api/v1/sms/send.${body}`).digest('hex');
import hmac, hashlib, json, time
ts = str(int(time.time()))
body = json.dumps({"to": "0197000001", "message": "Bonjour", "sender": "MAYA"})
sig = hmac.new(b"mk_live_ss_xxxxxxxx", f"{ts}.POST./api/v1/sms/send.{body}".encode(), hashlib.sha256).hexdigest()
Mode sandbox (clés de test)
Les clés mk_test_… exécutent toute la validation mais n'envoient rien et ne débitent pas votre solde. Les identifiants de messages commencent par sbx_.
- Un numéro se terminant par
0000ou un email commençant parfail@simule un échec de livraison. - Passez en production en remplaçant simplement la clé par une clé
mk_live_….
Ping & solde
GET /ping
Vérifie une clé (publique ou privée).
curl https://mayasend.bconsultingsarl.com/api/v1/ping -H "Authorization: Bearer mk_test_sk_xxxxxxxx"
{ "success": true, "environment": "sandbox", "key_type": "private", "account": "Ma Société" }
GET /balance
Retourne le solde en FCFA, les prix unitaires et l'équivalent en messages.
{ "success": true, "environment": "live",
"balance": { "amount": 12500, "currency": "XOF" },
"unit_prices": { "sms": 25, "whatsapp": 35, "email": 3 },
"equivalent_messages": { "sms": 500, "whatsapp": 357, "email": 4166 } }
POST /sms/send
| Champ | Type | Description |
|---|---|---|
to | string | Numéro du destinataire (01XXXXXXXX ou +229…) |
message | string | Texte, 1 600 caractères maximum. Facturé par segment. |
sender | string | Sender ID approuvé (facultatif) |
reference | string | Votre référence interne (facultatif) |
curl -X POST https://mayasend.bconsultingsarl.com/api/v1/sms/send \
-H "Authorization: Bearer mk_live_sk_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cmd-10452" \
-d '{"to":"0197000001","message":"Bonjour, votre code est 4821","sender":"MAYA"}'
$ch = curl_init('https://mayasend.bconsultingsarl.com/api/v1/sms/send');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer mk_live_sk_xxxxxxxx', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['to' => '0197000001', 'message' => 'Bonjour', 'sender' => 'MAYA']),
]);
$res = json_decode(curl_exec($ch), true);
const res = await fetch('https://mayasend.bconsultingsarl.com/api/v1/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer mk_live_sk_xxxxxxxx', 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '0197000001', message: 'Bonjour', sender: 'MAYA' })
});
const data = await res.json();
import requests
r = requests.post('https://mayasend.bconsultingsarl.com/api/v1/sms/send',
headers={'Authorization': 'Bearer mk_live_sk_xxxxxxxx'},
json={'to': '0197000001', 'message': 'Bonjour', 'sender': 'MAYA'})
print(r.json())
Réponse (HTTP 202) :
{ "success": true,
"message": { "id": "msg_…", "status": "queued", "cost": 25 },
"request_id": "req_…" }
POST /whatsapp/send
Les messages à l'initiative de l'entreprise utilisent un modèle approuvé par Meta (voir « Modèles WhatsApp »).
| Champ | Type | Description |
|---|---|---|
to | string | Numéro WhatsApp du destinataire |
template | string | Identifiant ou nom du modèle approuvé |
params | string[] | Valeurs de {{1}}, {{2}}… (autant que dans le modèle) |
curl -X POST https://mayasend.bconsultingsarl.com/api/v1/whatsapp/send \
-H "Authorization: Bearer mk_live_sk_xxxxxxxx" -H "Content-Type: application/json" \
-d '{"to":"0197000002","template":"rappel_rdv","params":["Awa","demain 10h"]}'
POST /email/send
| Champ | Type | Description |
|---|---|---|
to | string | Adresse email |
subject | string | Objet (200 caractères maximum) |
html / text | string | Contenu (au moins l'un des deux). Le HTML est nettoyé : scripts supprimés. |
from_name, reply_to | string | Facultatifs |
curl -X POST https://mayasend.bconsultingsarl.com/api/v1/email/send \
-H "Authorization: Bearer mk_live_sk_xxxxxxxx" -H "Content-Type: application/json" \
-d '{"to":"awa@exemple.com","subject":"Votre facture","html":"<p>Bonjour Awa,</p>"}'
Un lien de désinscription est ajouté automatiquement ; les destinataires désinscrits ne sont plus contactés et le message est remboursé.
Envoi en lot
Envoyez jusqu'à 100 messages par requête sur n'importe quel point d'entrée d'envoi :
{ "messages": [
{ "to": "0197000001", "message": "Bonjour Awa" },
{ "to": "0197000002", "message": "Bonjour Koffi" }
] }
→ { "success": true, "accepted": 2, "rejected": 0, "total_cost": 50, "results": [ … ] }
Chaque élément est validé séparément : un message invalide n'empêche pas les autres.
GET /messages/{id}
Retourne l'état d'un message : queued → sending → sent → delivered, ou failed (avec le motif dans error). Pour les emails, opened_at et clicked_at sont renseignés.
Idempotence
Ajoutez l'en-tête Idempotency-Key (8 à 100 caractères : lettres, chiffres, . _ : -) pour pouvoir rejouer une requête sans doublon : la même réponse est renvoyée avec l'en-tête Idempotent-Replayed: true. Si la première requête est encore en cours, vous recevez une erreur 409.
Erreurs
{ "success": false, "error": { "type": "insufficient_balance", "message": "Solde insuffisant. Rechargez votre compte." } }
| HTTP | Type | Signification |
|---|---|---|
| 200 / 202 | — | Succès (202 : message accepté, envoi en cours) |
| 400 | invalid_json, invalid_idempotency_key | Corps JSON ou clé d'idempotence invalide |
| 401 | invalid_signature… | Clé absente ou invalide, signature incorrecte |
| 402 | insufficient_balance | Solde insuffisant (rien n'est débité) |
| 403 | channel_not_allowed… | Canal ou IP non autorisés, clé publique sur un point privé, compte inactif |
| 404 | not_found | Point d'entrée ou message inconnu |
| 405 | method_not_allowed | Méthode HTTP non autorisée (voir l'en-tête Allow) |
| 409 | request_in_progress | Même Idempotency-Key encore en traitement |
| 415 | unsupported_media_type | Content-Type doit être application/json |
| 422 | validation_error | Données invalides — error.message détaille le champ |
| 429 | — | Trop de requêtes : attendez (en-tête Retry-After) |
Facturation : le montant est débité à l'acceptation du message et automatiquement remboursé en cas d'échec définitif.
Limites & sécurité
- 100 messages maximum par requête, corps de requête limité à 2 Mo.
- Limitation de débit : en cas de dépassement, l'API répond
429avecRetry-After. - Liste blanche d'IP, restriction par canal et journalisation des appels par clé.
- Révoquez immédiatement une clé compromise depuis « Clés API », puis régénérez-la.
Bonnes pratiques
- Testez toute votre intégration avec les clés sandbox avant de passer en live.
- Utilisez
Idempotency-Keypour les envois déclenchés par une commande ou un paiement. - Surveillez votre solde via
/balanceet rechargez avant d'être à court. - Respectez le consentement de vos destinataires et la réglementation locale sur la prospection.
- Gardez les messages courts : un SMS de plus de 160 caractères coûte plusieurs segments.
Questions fréquentes
Mon paiement est validé mais mon solde n'a pas bougé.
MAYASEND vérifie le paiement directement auprès de KKiaPay. Patientez une minute puis actualisez ; si le solde n'est pas crédité, contactez le support avec la référence de la transaction.
Puis-je utiliser le même solde pour les trois canaux ?
Oui, un seul solde en FCFA est débité selon le tarif de chaque canal. Le choix du pack (SMS + WhatsApp ou Email) définit seulement la quantité minimale à l'achat.
Pourquoi mon Sender ID n'est pas disponible ?
Il doit être approuvé par l'équipe. Vérifiez son statut dans votre espace.
Les clés sandbox débitent-elles mon solde ?
Non. Aucune donnée n'est envoyée et rien n'est débité.
Que se passe-t-il si un message échoue ?
Après échec définitif, le montant est remboursé automatiquement sur votre solde.
Où voir l'état de la plateforme ?
Sur la page Statut, qui indique aussi les maintenances en cours.
Support
Une question, un incident ? Écrivez-nous via la page Contact en indiquant votre email de compte et, pour l'API, le request_id de la réponse concernée.