Documentation API

WhatsApp, SMS, e-mails transactionnels, routage intelligent (auto), tests en bac à sable, statistiques et journaux d’envoi — avec une seule clé API.

Dernière mise à jour : mars 2026. La documentation reflète le fonctionnement actuel en production.

URL de base
https://api.notif.ml

CLI

Envoyez rapidement des messages WhatsApp, des e-mails et des messages planifiés depuis votre terminal avec notifml-cli.

npm i -g notifml-cli
notif init --key ntf_live_xxx --to +22370000000
notif me "Build failed on prod"
notif "Ship done"
notif send +22370000000 "Check ASAP"
notif run -- npm run build
notif balance
notif doctor
notif me --at "in 10m" "Check deploy"

Vos destinataires fréquents restent des alias locaux dans la configuration du terminal. Notif reste ainsi une API de notification légère, sans dupliquer les contacts et campagnes SMSV.

notif alias set boss +22370000000
notif send boss "Besoin de ton retour"
notif boss "Besoin de ton retour"
tail -n 30 error.log | notif me --title "Prod error"

Les développeurs peuvent consulter leur clé locale, leur compte, leur utilisation et leur solde sans ouvrir le tableau de bord.

notif whoami
notif key
notif key --show
notif balance --transactions
notif status ntf_msg_xxx
notif logs --limit 10

Exemple rapide

Envoyez votre premier message en une seule requête :

POST/api/send
curl -X POST https://api.notif.ml/api/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+1234567890",
    "channel": "whatsapp",
    "message": "Your order #1234 is ready"
  }'

Paramètres de la requête

torequischaîne

Numéro au format E.164 (ex. +22370123456) pour whatsapp, sms, ou auto. Adresse e-mail valide lorsque channel vaut email.

channelrequischaîne

whatsapp — WhatsApp (médias acceptés). sms — SMS (texte uniquement). email — e-mail transactionnel via HTTP (sans clé SMSV). auto — routage via SMSV (ex. WhatsApp → SMS → e-mail selon disponibilité).
Une connexion WhatsApp (SMSV) est requise pour whatsapp/sms/auto, sauf en mode bac à sable ou pour un envoi par e-mail seul.

messagerequischaîne

Corps du message. Peut être omis si vous utilisez preset avec presetVariables ou uniquement mediaUrl (WhatsApp).

Pour les codes et liens de récupération, définissez sensitive: true (automatique avec preset: "otp"). Le contenu est exclu de l’historique ; la planification, les groupes, les médias et le rejeu sont désactivés. La livraison SMS expire après cinq minutes. Générez un nouveau code pour une nouvelle tentative. Ne placez aucun secret dans les métadonnées personnalisées.

htmlfacultatifchaîne

Corps HTML pour le canal e-mail. Lorsque ce champ accompagne message, l’e-mail contient à la fois une partie text (texte brut) et une partie html . Ignoré pour WhatsApp/SMS/auto.

subjectfacultatifchaîne

Objet de l’e-mail lorsque channel vaut email (titre générique par défaut si omis).

sandboxfacultatifbooléen

Lorsque true (ou l’en-tête X-Notif-Sandbox: 1, ou la variable d’environnement NOTIF_SANDBOX=1), aucun envoi réel : réponse SANDBOX, identifiants préfixés par sb_. Événements webhook simulés facultatifs, sauf si sandboxWebhooks: false.

sandboxWebhooksfacultatifbooléen

En mode bac à sable, définissez la valeur à false pour ignorer les webhooks simulés message.status .

presetfacultatifchaîne

Applique un modèle intégré : otp, order_confirmed, order_shipped, delivery_out, appointment_reminder, payment_received. À utiliser avec presetVariables.

presetVariablesfacultatifobjet

Paires clé/valeur textuelles transmises au modèle sélectionné preset.

mediaUrlfacultatifchaîne

URL d’une image, vidéo ou d’un document à joindre (WhatsApp uniquement)

scheduledAtfacultatifchaîne (date ISO)

Planifie l’envoi. Les dates futures renvoient 202 SCHEDULED et peuvent être suivies avec /api/status/:messageId (exemple : 2026-03-05T14:30:00Z)

retryfacultatifbooléen | objet

Retente la livraison fournisseur avant de marquer le message en échec. Utilisez { maxAttempts: 3, delayMs: 1000 } pour les alertes critiques.

senderIdfacultatifchaîne

Envoie depuis un numéro WhatsApp précis lorsque votre compte dispose de plusieurs expéditeurs.

captionfacultatifchaîne

Légende des pièces jointes

templatefacultatifchaîne

Ancien champ accepté pour les clients existants. Préférez preset pour les modèles structurés ; cette chaîne est ignorée sur les routes Partner Cloud actuelles.

buttonsfacultatiftableau

Ancien contenu interactif ; ignoré sur les routes actuelles. Utilisez les parcours natifs WhatsApp via SMSV pour les interfaces enrichies.

groupIdfacultatifchaîne

Identifiant du groupe WhatsApp (format xxx@g.us) pour envoyer à un groupe plutôt qu’à un contact. Lorsqu’il est renseigné, to reste requis pour le suivi interne mais le message est remis au groupe. Utilisez GET /api/partner/whatsapp/groups pour lister les groupes disponibles.

Exemples

Envoyer un média

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "message": "Here's your invoice",
  "mediaUrl": "https://example.com/invoice.pdf",
  "caption": "Invoice #1234"
}

Envoyer un audio/une vidéo

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "message": "Voice note",
  "mediaUrl": "https://example.com/audio.mp3"
}

Planifier un message

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "message": "Reminder for tomorrow",
  "scheduledAt": "2026-03-05T14:30:00Z"
}

L’API renvoie 202 avec status: "SCHEDULED"; le message est envoyé automatiquement à l’heure prévue.

Envoi par lot

{
  "messages": [
    {
      "to": "+1234567890",
      "channel": "whatsapp",
      "message": "Hello #1"
    },
    {
      "to": "+22372830996",
      "channel": "whatsapp",
      "message": "Hello #2",
      "mediaUrl": "https://example.com/video.mp4"
    }
  ],
  "continueOnError": true
}

E-mail transactionnel

{
  "to": "customer@example.com",
  "channel": "email",
  "subject": "Your receipt",
  "message": "Thanks for your order — details inside."
}

Envoyer dans un groupe WhatsApp

{
  "to": "+22372830996",
  "groupId": "120363123456789@g.us",
  "channel": "whatsapp",
  "message": "Hello team! Meeting at 3pm"
}

Test en bac à sable

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "message": "Integration test",
  "sandbox": true
}

Modèle prédéfini

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "preset": "order_confirmed",
  "presetVariables": {
    "orderId": "A-1024",
    "customerName": "Awa"
  }
}

Anciens champs (template/buttons)

{
  "to": "+1234567890",
  "channel": "whatsapp",
  "message": "Your order is ready for pickup",
  "template": "order_ready",
  "buttons": [
    { "type": "reply", "text": "On my way" },
    { "type": "reply", "text": "Reschedule" }
  ]
}

Les anciens champs template / buttons sont acceptés pour la compatibilité ; préférez preset pour le contenu structuré.

Authentification

Utilisez votre clé API dans l’en-tête Authorization ou X-API-Key :

Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_API_KEY

Groupes WhatsApp

Envoyez des messages aux groupes WhatsApp dont votre numéro connecté est membre.

GET/api/partner/whatsapp/groups

Liste tous les groupes WhatsApp dont votre numéro connecté est membre.

Exemple : curl -H "X-API-Key: YOUR_KEY" https://api.notif.ml/api/partner/whatsapp/groups

{
  "success": true,
  "groups": [
    { "id": "120363123456789@g.us", "name": "Team Dev", "participants": 12, "isAdmin": true },
    { "id": "120363987654321@g.us", "name": "Marketing", "participants": 25, "isAdmin": false }
  ],
  "count": 2
}

Utilisez la valeur id de cette réponse comme groupId dans POST /api/send.

Points d’accès

POST/api/send

Envoie des messages WhatsApp, SMS, e-mail ou à routage automatique (même authentification que ci-dessous). Accepte les groupes via groupId.

POST/api/send/batch

Envoie jusqu’à 100 messages en une requête (résultats par élément ; mêmes champs que /api/send).

GET/api/status/:messageId

Récupère le statut d’un message (principalement pour le tableau de bord et les intégrations avancées).

GET/api/me

Récupère le profil développeur authentifié, les métadonnées publiques/masquées de clé, l’offre, l’utilisation quotidienne, le solde, les messages récents et les paramètres webhook.

GET/api/credits

Récupère le quota de l’offre, l’utilisation du jour, le solde, les prix par canal et les opérations récentes sur le crédit.

Statistiques et journaux d’envoi

Même authentification que POST /api/send: X-API-Key: ntf_live_… ou Bearer, ou une session de tableau de bord authentifiée.

GET/api/notif-analytics

Agrégats sur l’historique récent des envois (Convex). Le paramètre facultatif sample (50–500, 200 par défaut) contrôle la taille de l’échantillon.

Exemple : curl -H "X-API-Key: YOUR_KEY" https://api.notif.ml/api/notif-analytics

GET/api/notif-logs

Liste des messages sortants récents de votre clé API. Paramètre limit (1–200, 50 par défaut).

Exemple : curl -H "X-API-Key: YOUR_KEY" "https://api.notif.ml/api/notif-logs?limit=50"

Mode bac à sable

Utilisez le bac à sable sans connecter WhatsApp/SMSV : aucun trafic opérateur, réponses prévisibles SANDBOX et événements webhook simulés facultatifs.

  • JSON "sandbox": true
  • En-tête X-Notif-Sandbox: 1
  • Variable serveur NOTIF_SANDBOX=1 (global)

Les clés préfixées par ntf_test_ renvoient toujours la simulation historique TEST sans contacter SMSV ; le bac à sable complète ce fonctionnement pour les clés ntf_live_ .

Idempotence

Les relances sont sûres. Ajoutez une clé d’idempotence à POST /api/send et la première requête reçue crée le message ; les requêtes suivantes utilisant la même clé renvoient le message enregistré sans nouvel envoi.

  • En-tête Idempotency-Key: <your-key> — recommandé.
  • Ou le champ JSON "idempotencyKey". Si les deux sont présents, l’en-tête est prioritaire.
  • Les espaces en début et fin de clé sont supprimés. Une clé vide ou composée d’espaces est ignorée et le message est envoyé normalement.
POST/api/send
curl -X POST https://api.notif.ml/api/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: order-1234-confirmed" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+22370123456",
    "channel": "whatsapp",
    "message": "Your order #1234 is confirmed"
  }'

Réponse lors d’un rejeu

Un rejeu renvoie le message enregistré avec "deduplicated": true pour le distinguer d’un nouvel envoi. Le statut vaut 200, ou 409 si le message enregistré s’est terminé en FAILED. Un rejeu d’envoi planifié renvoie également 200 dans ce format, et non 202 de la requête initiale.

{
  "success": true,
  "messageId": "msg_...",
  "notifMessageId": "msg_...",
  "channel": "whatsapp",
  "to": "+22370123456",
  "status": "SENT",
  "deduplicated": true
}

Portée et durée de vie

  • Les clés sont limitées à votre compte et ne peuvent pas entrer en conflit avec celles d’un autre client.
  • La correspondance porte uniquement sur la clé, pas sur le destinataire, le canal ou le contenu. Réutiliser une clé avec un contenu différent renvoie le message initial sans nouvel envoi.
  • Les clés n’expirent pas : une clé utilisée il y a plusieurs mois déduplique encore aujourd’hui. Utilisez une clé unique par événement.

Modèle recommandé

Dérivez la clé de l’événement concerné — identifiant de commande, facture ou événement — et du type de message, par exemple order-1234-confirmed. Ne générez pas un nouvel UUID à chaque tentative : un nouvel UUID lors d’une relance crée une nouvelle clé et un double envoi.

Sur POST /api/send/batch, une clé par élément idempotencyKey est utilisée telle quelle ; sinon, l’en-tête de requête Idempotency-Key reçoit le suffixe correspondant à l’index de l’élément (:0, :1, …), afin que chaque élément garde sa propre clé.

Limites de débit et HTTP 429

Lorsque le quota quotidien est dépassé, POST /api/send renvoie 429 avec messagesUsed, limit, et upgradeUrl.

Si votre compte a un plafond quotidien par destinataire, les envois au même téléphone/e-mail peuvent renvoyer 429 avec recipientLimit lorsque ce plafond est atteint.

Les limites et l’utilisation de votre offre sont également disponibles sur GET /api/me (cookie de session).

Webhooks

Enregistrez une valeur webhookUrl sur votre compte notif.ml. Une fois définie, notif.ml envoie les événements de livraison et de réception à votre URL HTTPS. L’appel authentifié GET /api/me renvoie l’URL actuelle ; contactez l’assistance ou utilisez votre accès administrateur pour la modifier tant que les réglages autonomes ne sont pas disponibles dans le tableau de bord.

Événements
  • message.status - mises à jour : envoyé, livré, échec.
  • message.received - messages WhatsApp reçus sur votre numéro connecté.
{
  "event": "message.received",
  "messageId": "wamid.HBg...",
  "from": "+22370000000",
  "to": "+22372830996",
  "channel": "whatsapp",
  "type": "text",
  "text": "Bonjour",
  "timestamp": "2026-03-04T13:37:00.000Z"
}
Applications mobiles : voir SDK mobiles. Pour le CRM, les campagnes et l’IA, découvrez SMSV.