Développeurs

API — Send & Mail

Notifications multi-canal (push, SMS, WhatsApp)

Send ne se limite plus à l'e-mail : c'est la brique de messagerie multi-canal de la plateforme. Un seul service centralise 4 canaux, avec la même traçabilité (PostgreSQL = source de vérité des statuts, les fournisseurs n'assurent que la délivrabilité).

CanalFournisseurSert à
EmailStalwart (JMAP direct)transactionnel, marketing — voir Référence API — Send
PushExpo Push APInotifications des apps mobiles (chat, fidélité…)
SMSTwilionotifications courtes vers un numéro
WhatsAppTwilionotifications WhatsApp Business

Trois familles de surfaces

Chaque canal est joignable par les mêmes surfaces :

SurfaceAuthUsage
Interne (JWT)JWT + gating senddepuis le Hub / un module côté utilisateur
M2M interneX-Internal-Secretserveur→serveur (fidélité, RDV, chat…)
Publique (clé API)X-Server-API-Key (psk_live_…)intégration tierce du tenant
Module / App ─┐
              ├─ JWT ───────────────▶ /api/send/{messages, text, push/devices}
Serveur M2M ──┼─ X-Internal-Secret ─▶ /api/send/internal/{push, text}
Intégration ──┴─ X-Server-API-Key ──▶ /api/public/send/{messages, sms, whatsapp}

Twilio ──▶ /api/send/text/webhook/twilio   (accusés, signature X-Twilio-Signature)

Push (Expo)

Send tient un registre central des appareils : chaque app mobile enregistre son token Expo, et les modules envoient à des utilisateurs (pas à des tokens).

MéthodeRouteRôle
POST/api/send/push/devicesEnregistrer un appareil (JWT — sujet = l'utilisateur)
DELETE/api/send/push/devices/{app}/{deviceId}Désenregistrer
POST/api/send/internal/pushEnvoyer (M2M) {app, subjectIds[], title, body, data?}

Send résout les appareils des destinataires, poste sur l'Expo Push API et purge automatiquement les tokens invalides (DeviceNotRegistered). Les credentials FCM/APNs vivent dans le build EAS des apps, jamais côté Send.

SMS & WhatsApp (Twilio)

Chaque envoi crée un TextMessage tracé : queued → sent → delivered (ou undelivered / failed), numéro au format E.164 (+336…).

MéthodeRouteAuth
POST/api/send/text/sms · /api/send/text/whatsappJWT
GET/api/send/text · /api/send/text/{id}JWT (historique / statut)
POST/api/send/internal/textM2M {tenantId, channel, to, body, source?}
POST/api/public/send/sms · /api/public/send/whatsappclé API {to, body}
curl -X POST https://send.puwapi.com/api/public/send/whatsapp \
  -H "X-Server-API-Key: psk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+33612345678", "body": "Merci pour votre visite 👋" }'

Accusés de livraison : Twilio notifie …/api/send/text/webhook/twilio à chaque changement de statut ; Send vérifie la signature X-Twilio-Signature puis fait progresser le statut de façon idempotente (jamais de régression d'un statut terminal).

Bon à savoir

  • WhatsApp : hors fenêtre de 24 h d'une conversation ouverte par le client, Meta impose des templates approuvés — le corps libre est refusé. En dev, utilisez le WhatsApp Sandbox Twilio.
  • Twilio non configuré : le message reste queued (jamais soumis), sans erreur métier — pratique en dev.
  • Les changements de statut sont poussés au Hub en temps réel (Convex).
  • La liste complète des variables et clés à générer (Expo, Twilio, secrets M2M) est documentée côté opérateur (send/CANAUX-NOTIFICATIONS.md).

#api #push #sms #whatsapp