Recevez message.status et message.inbound en temps réel, signés HMAC-SHA256. Vérifiez toujours la signature.
Plutôt que de sonder GET /v1/messages/{id}, enregistrez UN endpoint HTTPS et nous y postons les événements en temps réel : mises à jour de statut de vos envois, et messages entrants de vos clients. Nous ne faisons tourner aucun bot sur votre numéro — nous vous relayons l'entrant.
POST /v1/console/webhook
Attention — Le secret n'est affiché qu'une fois
À l'enregistrement, le secret de signature est renvoyé une seule fois — stockez-le. Un GET ultérieur renvoie { url, configured } sans jamais le secret ; DELETE désactive le webhook.
Chaque événement est un POST vers votre URL. La livraison est best-effort (~8 s de timeout, pas de retries automatiques pour l'instant) : répondez 2xx rapidement et faites le gros du travail de façon asynchrone.
En-tête de signature
X-Camairetech-Signature: sha256=<hex hmac-sha256 du corps brut>
message.status
{
"event": "message.status",
"data": {
"id": "6f1c…",
"wa_message_id": "wamid…",
"status": "delivered",
"recipient_masked": "2376****3456",
"error": null
},
"timestamp": "2026-08-04T09:14:07.123456+00:00"
}
message.inbound
{
"event": "message.inbound",
"data": {
"from": "+237699123456",
"wa_message_id": "wamid…",
"type": "text",
"text": "Bonjour",
"media_url": null
},
"timestamp": "…"
}
type vaut text ou un type média (image, audio, video, document, sticker). media_url est null : nous n'hébergeons pas les médias des numéros API — récupérez-les auprès de Meta avec votre propre jeton si besoin.
Recalculez le HMAC sur les octets bruts du corps (avant tout parsing JSON) et comparez à l'en-tête ; rejetez en cas d'écart. Re-sérialiser le corps changerait la signature.
Vérification (Python)
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Vérification (Node.js)
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header || ""));
}