Développeurs

API publique

Envoyez SMS, email et WhatsApp, lancez des campagnes, vérifiez des OTP et consultez votre solde via une API HTTP simple. Chaque erreur est lisible par machine avec un code stable. La référence complète est ci-dessous.

Démarrage

Tous les endpoints sont servis sous :

https://api-s1.textdigo.com/api/v0

Les requêtes et réponses sont en JSON (hors téléversements multipart). Envoyez l’en-tête x-locale: fr ou en pour localiser les messages d’erreur.

Authentification

Envoyez un de vos jetons d’API dans un en-tête Authorization: Bearer. Vous créez vos jetons dans Paramètres → Organisation → API ; la valeur n’est affichée qu’une fois, à la création. Un jeton par intégration : en révoquer un laisse les autres fonctionner.

curl -H "Authorization: Bearer td_sk_…" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber":"+237670000000","message":"Hello"}' \
  https://api-s1.textdigo.com/api/v0/sms/message

Intégrations existantes : l’ancien couple (HTTP Basic avec votre apiLogin comme identifiant et votre clé API comme mot de passe, également accepté en Bearer ou ?token=) continue de fonctionner, sans date de fin annoncée. C’est vous qui décidez du jour où vous le révoquez, depuis le même écran.

Réponses & erreurs

Les erreurs partagent une même forme. statusCode est le statut HTTP, errorCode une chaîne stable lisible par machine (voir la référence), message est lisible par un humain, et details[] liste les problèmes par champ pour les erreurs de validation.

{
  "statusCode": 422,
  "errorCode": "PUBLIC_API_INVALID_PHONE_NUMBER",
  "message": "The phone number 0670 is not a valid international number",
  "details": [],
  "timestamp": "2026-06-10T10:00:00.000Z",
  "path": "/api/v0/sms/message"
}

Envoi de messages

POST/sms/messageenvoi de test

Envoyer un SMS à un numéro.

ChampTypeDansDescription
phoneNumber*string (E.164)bodyNuméro du destinataire au format international, ex. +237670000000.
message*string (≤2000)bodyContenu du message.
senderNamestring (≤50)bodyNom d'expéditeur approuvé.
smsTypeenum TRANSACTIONAL|MARKETINGbodyCatégorie de facturation (défaut TRANSACTIONAL).
externalIdstringbodyVotre référence, renvoyée dans les webhooks.

Erreurs possibles : PUBLIC_API_INVALID_PHONE_NUMBER (422), PUBLIC_API_UNSUPPORTED_PHONE_NUMBER (422)

POST/email/messagefacturé

Envoyer un email.

ChampTypeDansDescription
email*string (email)bodyAdresse email du destinataire.
subject*string (≤998)bodyObjet de l'email.
htmlMessagestringbodyCorps HTML.
textMessagestringbodyCorps texte.

Erreurs possibles : PUBLIC_API_INVALID_EMAIL (422)

POST/email/template/messagefacturé

Envoyer un email depuis un modèle.

ChampTypeDansDescription
email*string (email)bodyAdresse email du destinataire.
subject*stringbodyObjet de l'email.
templateId*stringbodyIdentifiant du modèle.
parametersobject<string,string>bodyValeurs des variables du modèle.

Erreurs possibles : PUBLIC_API_INVALID_EMAIL (422), PUBLIC_API_TEMPLATE_NOT_FOUND (404)

POST/whatsapp-business/messagefacturé

Envoyer un message WhatsApp Business.

ChampTypeDansDescription
whatsappBusinessPhoneNumberId*stringbodyIdentifiant de l'expéditeur WhatsApp.
phoneNumber*string (E.164)bodyNuméro du destinataire au format international, ex. +237670000000.
messagestring (≤4096)bodyCorps texte (dans la fenêtre 24 h).
mediaUrlstring (url)bodyURL publique d'une pièce jointe.

Erreurs possibles : PUBLIC_API_INVALID_PHONE_NUMBER (422), PUBLIC_API_WAB_ACCOUNT_NOT_FOUND (404)

POST/whatsapp-business/otp/messagefacturé

Envoyer un OTP WhatsApp.

ChampTypeDansDescription
whatsappBusinessPhoneNumberId*stringbodyIdentifiant de l'expéditeur WhatsApp.
phoneNumber*string (E.164)bodyNuméro du destinataire au format international, ex. +237670000000.
message*string (≤4096)bodyLe texte OTP rendu, ex. « 482913 est votre code de vérification. ». Il n'est pas envoyé tel quel : il sert à identifier le modèle AUTHENTICATION approuvé dont il provient, et le code part sous forme de ce modèle.

Erreurs possibles : PUBLIC_API_INVALID_PHONE_NUMBER (422), PUBLIC_API_WAB_ACCOUNT_NOT_FOUND (404), PUBLIC_API_OTP_NO_AUTH_TEMPLATE (422), PUBLIC_API_OTP_TEMPLATE_NO_MATCH (422)

POST/whatsapp-business/template/messagefacturé

Envoyer un message modèle WhatsApp.

ChampTypeDansDescription
whatsappBusinessPhoneNumberId*stringbodyIdentifiant de l'expéditeur WhatsApp.
phoneNumber*string (E.164)bodyNuméro du destinataire au format international, ex. +237670000000.
templateId*stringbodyIdentifiant du modèle approuvé.
bodyParametersobject<string,string>bodyValeurs des variables du corps.

Erreurs possibles : PUBLIC_API_INVALID_PHONE_NUMBER (422), PUBLIC_API_TEMPLATE_NOT_FOUND (404), PUBLIC_API_WAB_ACCOUNT_NOT_FOUND (404)

POST/api-campaign/send-smsfacturé

Envoyer un SMS à plusieurs contacts (lot).

ChampTypeDansDescription
message*stringbodyContenu du message.
contacts*string[] (≤1000)bodyNuméros destinataires ; les invalides sont ignorés et reportés.
senderNamestringbodyNom d'expéditeur approuvé.

Erreurs possibles : PUBLIC_API_INVALID_RECIPIENTS (422)

GET/api-campaign/send-smsfacturé

SMS en lot (variante query).

ChampTypeDansDescription
message*stringqueryContenu du message.
contacts*string (comma-separated)queryNuméros séparés par des virgules.

Erreurs possibles : PUBLIC_API_INVALID_RECIPIENTS (422)

Statut de livraison

GET/message/{channel}/status/{msgId}lecture seule

Statut de livraison d’un message.

ChampTypeDansDescription
channel*enum sms|email|whatsapppathCanal du message.
msgId*stringpathLe msgId renvoyé à l'envoi.

Erreurs possibles : PUBLIC_API_MESSAGE_NOT_FOUND (404)

GET/message/sms/{msgId}lecture seule

Détails complets d’un SMS.

ChampTypeDansDescription
msgId*stringpathLe msgId renvoyé à l'envoi.

Erreurs possibles : PUBLIC_API_MESSAGE_NOT_FOUND (404)

Compte & usage

GET/integration/usagelecture seule

Aperçu usage & quotas.

GET/integration/walletlecture seule

Solde du portefeuille & transactions récentes.

GET/integration/canalslecture seule

Lister vos canaux.

ChampTypeDansDescription
typeenum CanalTypequeryFiltrer par type de canal.
limitnumberqueryTaille de page (défaut 50).

Ressources

POST/integration/campaignsfacturé

Créer et lancer une campagne.

ChampTypeDansDescription
campaignSpecId*uuidbodyIdentifiant du modèle de message.
profileIds*uuid[]bodyIdentifiants des listes de contacts.
frequency*enum CampaignFrequencybodyCadence d’envoi.
POST/integration/campaign-specsfacturé

Créer un modèle de message.

ChampTypeDansDescription
name*string (≤200)bodyNom du modèle.
type*enum CampaignSpecTypebodyType de canal (SMS, EMAIL…).
configobjectbodyConfiguration propre au canal.
POST/integration/campaign-profilesfacturé

Créer une liste de contacts.

ChampTypeDansDescription
name*string (≤200)bodyNom de la liste.
type*enum CampaignProfileTypebodyType de source de la liste.
campaignSpecType*enum CampaignSpecTypebodyCanal ciblé par la liste.
POST/integration/campaign-profiles/{id}/contacts/importfacturé

Importer des contacts dans une liste.

ChampTypeDansDescription
id*uuidpathIdentifiant de la liste.
contacts*object[] (≤10000)bodyTableau de { phoneNumber?, email?, parameters? }.
POST/integration/ticketsfacturé

Créer un ticket.

ChampTypeDansDescription
canalType*enum TicketCanalTypebodyCanal du ticket.
descriptionstring (≤2000)bodyDescription du ticket.
POST/integration/contactsfacturé

Créer un contact.

ChampTypeDansDescription
namestringbodyNom du contact.
phoneNumbersstring[]bodyNuméros de téléphone.
emailsstring[] (email)bodyAdresses email.
POST/integration/groupsfacturé

Créer un groupe de contacts.

ChampTypeDansDescription
name*stringbodyNom du groupe.

Codes à usage unique

POST/otp/smsfacturé

Envoyer un OTP par SMS.

ChampTypeDansDescription
phoneNumber*string (E.164)bodyNuméro du destinataire au format international, ex. +237670000000.
numberOfDigitsint 4–8bodyLongueur du code (valeur par défaut).

Erreurs possibles : PUBLIC_API_INVALID_PHONE_NUMBER (422)

POST/otp/emailfacturé

Envoyer un OTP par email.

ChampTypeDansDescription
email*string (email)bodyAdresse email du destinataire.

Erreurs possibles : PUBLIC_API_INVALID_EMAIL (422)

Fichiers & tickets

POST/issuefacturé

Créer un ticket de support (multipart).

ChampTypeDansDescription
email*string (email)multipartAdresse email du destinataire.
issueCanalType*enum SMS|WHATSAPP|EMAILmultipartCanal de réponse.
issueMessagestringmultipartLe texte de la demande.
filebinarymultipartPièce jointe optionnelle.

Erreurs possibles : PUBLIC_API_INVALID_EMAIL (422), PUBLIC_API_FILE_TOO_LARGE (413)

Webhooks

Configurez des URL de rappel par canal dans Paramètres → Organisation → API. Chaque appel est un POST signé avec X-TextDigo-Signature: sha256=HMAC_SHA256(webhookSecret, rawBody). Vérifiez-le avec votre webhookSecret.

Rapports de livraison

{ "msgId": "...", "from": "...", "status": "DELIVERED",
  "partCount": 1, "amount": 0.02, "operator": "...",
  "externalId": "...", "currency": "XAF", "subject": "dlr", "type": "sms" }

status ∈ DELIVERED | UNDELIVERED | SENT | FAILED

Messages entrants

{ "event": "inbound-message", "type": "sms", "lineId": "...",
  "phoneNumber": "...", "chatId": "...", "message": "...", "medias": [] }

Codes d'erreur

Branchez sur errorCode, pas sur le message humain (qui est localisé). Les codes issus de l’ancienne API Meteor affichent leur ancien code numérique.

Authentification

CodeHTTPSignificationRésolution
API_KEY_MISSING_CREDENTIALS401Identifiants API manquants.Aucun en-tête Authorization (ou token) n'a été fourni.Envoyez Authorization: Bearer <votre jeton d’API>.
API_KEY_INVALID_CREDENTIALS401Identifiants API invalides.Le jeton est inconnu ou a été révoqué (l’ancien couple apiLogin/apiKey est vérifié de la même façon).Créez un jeton dans Paramètres → Organisation → API et copiez le : sa valeur n’est affichée qu’une fois.
API_KEY_ORG_NOT_ACTIVE403L'organisation n'est pas active.Le compte est suspendu ou résilié.Réactivez le compte ou contactez le support.

Validation

CodeHTTPSignificationRésolution
VALIDATION_FAILED422Un ou plusieurs champs sont invalides.Un champ est manquant, du mauvais type, trop long ou inconnu.Consultez le tableau details[] par champ dans la réponse.
PUBLIC_API_INVALID_PHONE_NUMBERex- #3001422Le numéro n'est pas un numéro international valide.Le numéro n’est pas analysable en E.164.Utilisez la forme internationale complète, ex. +237670000000.
PUBLIC_API_UNSUPPORTED_PHONE_NUMBERex- #3002422Aucun opérateur actif ne dessert ce numéro.Le pays/opérateur de destination n'est pas activé sur votre compte.Vérifiez votre couverture activée ou contactez le support.
PUBLIC_API_INVALID_EMAILex- #3003422L'adresse email n'est pas valide.L’adresse a échoué à la validation de format.Fournissez une adresse syntaxiquement valide.
PUBLIC_API_INVALID_RECIPIENTS422Aucun des destinataires fournis n'est valide.Tous les numéros d’un envoi en lot ont échoué à la validation.Envoyez au moins un numéro E.164 valide.
OTP_EXPIRED400Le code OTP a expiré.La fenêtre de validité a expiré avant la vérification.Demandez un nouvel OTP et vérifiez-le plus tôt.
OTP_TOO_MANY_ATTEMPTS400Trop de tentatives OTP échouées.Le code a été saisi incorrectement trop de fois.Demandez un nouvel OTP pour réinitialiser le compteur.
OTP_INVALID_CODE400Code OTP invalide.Le code soumis ne correspond pas à l'OTP en attente.Resaisissez le code exact qui a été envoyé.
PUBLIC_API_OTP_TEMPLATE_NO_MATCH422Le message ne correspond à aucun modèle AUTHENTICATION approuvé de cet expéditeur.La formulation envoyée doit correspondre au corps d’un modèle approuvé pour que les valeurs des paramètres puissent en être extraites.Alignez votre formulation sur le modèle approuvé, ou ajoutez votre variante aux formulations acceptées de ce modèle.
PUBLIC_API_FILE_REQUIREDex- #101422Un fichier est requis.La requête multipart ne contenait aucun fichier.Joignez le fichier sous le champ « file ».
PUBLIC_API_FILE_TOO_LARGE413Le fichier dépasse la taille maximale.Le téléversement dépasse la limite par fichier.Compressez ou divisez le fichier sous la limite.

Ressources

CodeHTTPSignificationRésolution
PUBLIC_API_MESSAGE_NOT_FOUND404Message introuvable.Le msgId n'appartient pas à votre compte.Utilisez le msgId renvoyé par l'appel d'envoi.
PUBLIC_API_OTP_CONTACT_NOT_FOUND404Aucun OTP en attente pour ce contact.Aucun OTP n'a été envoyé, ou il a expiré.Envoyez un nouvel OTP avant de vérifier.
OTP_NOT_FOUND404Aucun OTP trouvé.Aucun OTP n'a été généré pour ce contact, ou il a déjà été consommé.Envoyez un nouvel OTP avant de vérifier.
OTP_CONTACT_NOT_FOUND404Le contact est introuvable.Le contactId fourni n'appartient pas à votre compte.Omettez contactId pour cibler par téléphone/email, ou utilisez un identifiant valide.
PUBLIC_API_WAB_ACCOUNT_NOT_FOUND404Aucun expéditeur WhatsApp Business ne correspond à l'identifiant.whatsappBusinessPhoneNumberId est erroné ou non connecté.Utilisez un identifiant de vos canaux WhatsApp connectés.
PUBLIC_API_TEMPLATE_NOT_FOUND404Modèle introuvable.Le templateId est inconnu dans votre compte.Listez vos modèles et utilisez un identifiant valide.
PUBLIC_API_OTP_NO_AUTH_TEMPLATE422Cet expéditeur WhatsApp n'a aucun modèle AUTHENTICATION approuvé.WhatsApp ne délivre les OTP que sous forme de modèle AUTHENTICATION approuvé, et cet expéditeur n'en a aucun.Créez un modèle AUTHENTICATION, faites-le approuver par Meta, puis réessayez.
PUBLIC_API_OTP_TEMPLATE_PARAM_MISMATCH422Aucun modèle AUTHENTICATION de cet expéditeur n'attend exactement un paramètre.Nous générons le code nous-mêmes : le corps du modèle doit porter cette seule valeur et rien d’autre.Faites approuver un modèle AUTHENTICATION dont le corps ne comporte qu’un seul paramètre, ou envoyez votre propre texte sur /whatsapp-business/otp/message.
PUBLIC_API_CANAL_NOT_ACTIVEex- #501422Le canal ciblé n'est pas actif.Le canal existe mais est désactivé.Activez le canal dans le tableau de bord.

Limitation de débit

CodeHTTPSignificationRésolution
RATE_LIMITED429Trop de requêtes.Vous avez dépassé le budget de requêtes par clé.Patientez puis réessayez après un court délai.

Serveur

CodeHTTPSignificationRésolution
INTERNAL_ERRORex- #100500Erreur serveur inattendue.Une défaillance est survenue de notre côté.Réessayez plus tard ; contactez le support si cela persiste.

Limites & quotas

  • Limitation de débit : les requêtes sont limitées par clé API. Patientez en cas de 429 (RATE_LIMITED).
  • SMS en lot : jusqu’à 1000 contacts par appel /api-campaign/send-sms.
  • Import de contacts : jusqu’à 10 000 contacts par appel.
  • Les téléversements sont plafonnés par la taille maximale par fichier (sinon PUBLIC_API_FILE_TOO_LARGE).