KoraFlow

Documentation développeurs · API v1

Intégrez WhatsApp à votre application avec KoraFlow

Une API REST simple pour envoyer des messages WhatsApp (texte, modèles approuvés, documents, images), suivre leur livraison et recevoir en temps réel les réponses de vos clients — depuis votre ERP, votre boutique en ligne, votre CRM ou un outil comme Make, Zapier ou n8n.

Sommaire

Introduction

Avec l’API KoraFlow, votre application peut :

  • envoyer des notifications WhatsApp : confirmation de commande, facture PDF, rappel de rendez-vous, code de vérification (OTP), avis d’expédition… ;
  • répondre à vos clients depuis votre propre logiciel ou chatbot ;
  • savoir si un message a été livré, lu ou a échoué ;
  • recevoir par webhook chaque message entrant et chaque changement de statut ;
  • synchroniser vos contacts avec KoraFlow.

Les messages partent du numéro WhatsApp Business connecté au compte KoraFlow (API Cloud officielle de Meta). Ils apparaissent dans la Boîte de réception KoraFlow : vos équipes voient tout ce que votre application envoie.

ÉlémentValeur
URL de basehttps://api.kora-flow.com/api/v1
FormatJSON (UTF-8) en entrée et en sortie — en-tête Content-Type: application/json
AuthentificationClé API dans l’en-tête Authorization: Bearer kfk_…
ProtocoleHTTPS uniquement
DatesISO 8601 en UTC (ex. 2026-10-03T14:05:12.000Z)
Numéros de téléphoneFormat international, indicatif pays inclus, sans + ni 00 (ex. 237699112233). Espaces, tirets et + sont tolérés et nettoyés.

Démarrage rapide

  1. Créez un compte KoraFlow et connectez votre numéro WhatsApp Business (Réglages → WhatsApp).
  2. Dans Réglages → Intégrations, cliquez sur Créer la clé. Copiez-la immédiatement : elle ne sera plus jamais affichée.
  3. Vérifiez la clé :
cURL
curl https://api.kora-flow.com/api/v1/me \
  -H "Authorization: Bearer kfk_VOTRE_CLE"

Réponse :

200 OK
{
  "tenant": { "id": "4f6c…", "name": "Boutique Awa", "isActive": true },
  "scopes": ["messages.send", "messages.read", "templates.read", "contacts.read"],
  "plan": "Pro (Croissance)",
  "rateLimitPerMinute": 120
}
  1. Envoyez votre premier message. Pour un test, écrivez d’abord au numéro de l’entreprise depuis votre téléphone (cela ouvre la fenêtre de 24 h, voir plus bas), puis :
curl -X POST https://api.kora-flow.com/api/v1/messages \
  -H "Authorization: Bearer kfk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"to": "237699112233", "text": "Bonjour ! Ceci est un test KoraFlow 🎉"}'

Le message apparaît sur le téléphone et dans la Boîte de réception KoraFlow. Suivez ensuite sa livraison avec GET /messages/{id} ou un webhook.

Authentification

Chaque requête doit contenir votre clé API dans l’en-tête Authorization :

En-tête HTTP
Authorization: Bearer kfk_VOTRE_CLE

Les clés commencent par kfk_. KoraFlow ne stocke qu’une empreinte (hachage) de la clé : si vous la perdez, révoquez-la et créez-en une nouvelle. Seul le propriétaire du compte peut créer ou révoquer des clés.

Scopes (permissions)

Chaque clé ne peut faire que ce que ses scopes autorisent. Donnez à chaque application le strict nécessaire.

ScopeAutorise
messages.sendEnvoyer des messages (POST /messages)
messages.readLire le statut et l’historique des messages
templates.readLister les modèles WhatsApp
contacts.readLister et rechercher les contacts
contacts.writeCréer des contacts et leur ajouter des tags
campaigns.readLister les campagnes et leurs compteurs
assistant.readLire les instructions de l’assistant IA de l’entreprise
assistant.writeModifier les instructions, le message d’accueil et les consignes par canal
*Tous les droits (à éviter en production)

/me, /usage et /numbers sont accessibles avec n’importe quelle clé valide.

Ne mettez jamais la clé dans un navigateur ou une application mobile

La clé permet d’envoyer des messages au nom de l’entreprise. Appelez l’API uniquement depuis votre serveur(back-end, fonction cloud, outil d’automatisation). Ne la placez jamais dans du JavaScript côté navigateur, dans une application Android/iOS ni dans un dépôt Git. Stockez-la dans une variable d’environnement.

Règles WhatsApp à connaître

KoraFlow utilise l’API Cloud officielle de Meta. Trois règles de Meta déterminent ce que vous pouvez envoyer :

1. La fenêtre de 24 heures

Quand un client vous écrit, une fenêtre de 24 heures s’ouvre. Pendant cette fenêtre, vous pouvez lui envoyer des messages libres : texte, image, document, vidéo, audio. En dehors de cette fenêtre, seul un modèle approuvé peut être envoyé.

Piège fréquent

Un texte libre envoyé hors fenêtre est d’abord accepté (201, statut SENT), puis Meta le refuse quelques secondes plus tard : le statut passe à FAILED avec l’erreur Meta 131047. Pour écrire en premier à un client (notification, OTP, facture), utilisez toujours un modèle.

2. Les modèles (templates)

Un modèle est un message pré-écrit, validé par Meta, avec des variables {{1}}, {{2}}… que vous remplissez à l’envoi. Créez-les dans KoraFlow (menu Modèles) ; la validation par Meta prend de quelques minutes à 24 h. Meta classe les modèles en trois catégories :

CatégorieUsageExemple
UTILITYSuite à une action du client (commande, paiement, rendez-vous)Votre commande {{1}} de {{2}} est confirmée.
AUTHENTICATIONCodes de vérificationVotre code KoraShop est {{1}}. Il expire dans 10 minutes.
MARKETINGPromotions, relances, nouveautés-20 % ce week-end sur toute la boutique !

3. Le consentement

N’écrivez qu’à des personnes qui ont accepté d’être contactées sur WhatsApp. Des signalements « spam » font baisser la note de qualité du numéro et peuvent entraîner des restrictions par Meta. La note de chaque numéro est visible via GET /numbers.

Facturation

Chaque message envoyé avec succès via l’API est décompté du quota de messages du forfait KoraFlow, comme un envoi depuis le tableau de bord (les envois échoués ne sont pas comptés). Les éventuels frais de Meta pour les modèles s’appliquent selon la grille tarifaire de Meta du compte WhatsApp Business connecté.

Envoyer un message

POST/api/v1/messagesscope : messages.send

Un seul point d’entrée pour tous les types de messages. Le type est déduit des champs fournis, ou indiqué avec type.

Paramètres du corps

ChampTypeDescription
tostringrequisNuméro du destinataire au format international (ex. 237699112233). Le contact est créé automatiquement s’il n’existe pas.
typestringoptionneltext, template, image, document, video ou audio. Par défaut : template si templateName est fourni, document si mediaUrl est fourni, sinon text.
textstringoptionnelTexte du message (max. 4 096 caractères). Requis pour type=text. Uniquement dans la fenêtre de 24 h.
templateNamestringoptionnelNom exact d’un modèle APPROVED. Requis pour type=template.
variablesstring[]optionnelValeurs des variables du modèle, dans l’ordre : le 1er élément remplace {{1}}, le 2e {{2}}, etc.
languagestringoptionnelCode langue du modèle (ex. fr, en_US). Si absent, KoraFlow utilise la langue sous laquelle le modèle est enregistré.
mediaUrlstringoptionnelURL publique HTTPS du fichier. Requis pour image/document/video/audio. Pour un modèle avec en-tête média (ex. facture PDF), sert d’en-tête au modèle.
captionstringoptionnelLégende d’une image, vidéo ou d’un document.
filenamestringoptionnelNom de fichier affiché pour un document (ex. Facture-A1234.pdf).
fromstringoptionnelNuméro expéditeur : id renvoyé par GET /numbers ou numéro au format international. Par défaut : le numéro principal du compte.
namestringoptionnelNom du contact, utilisé seulement s’il est créé par cet envoi.

En-têtes optionnels

En-têteDescription
Idempotency-KeyIdentifiant unique de votre côté (ex. commande-A1234-confirmation). Si la même requête est rejouée avec la même clé dans les 24 h, le message n’est pas renvoyé : vous recevez la réponse d’origine. Détails.

Exemple : texte libre (dans la fenêtre de 24 h)

JSON
{
  "to": "237699112233",
  "text": "Bonjour Awa, votre colis est arrivé à l'agence de Douala. Passez le récupérer avant 18 h."
}

Exemple : modèle avec variables (à tout moment)

Modèle confirmation_commande : « Bonjour, votre commande {{1}} d’un montant de {{2}} est confirmée. Livraison prévue le {{3}}. »

curl -X POST https://api.kora-flow.com/api/v1/messages \
  -H "Authorization: Bearer kfk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: commande-A1234-confirmation" \
  -d '{
    "to": "237699112233",
    "templateName": "confirmation_commande",
    "variables": ["A1234", "45 000 FCFA", "lundi 6 octobre"]
  }'

Exemple : document PDF (facture, reçu, bulletin)

JSON
{
  "to": "237699112233",
  "type": "document",
  "mediaUrl": "https://exemple.com/factures/A1234.pdf",
  "filename": "Facture-A1234.pdf",
  "caption": "Votre facture A1234"
}

L’URL doit être publique (accessible sans connexion) au moment de l’envoi. Formats acceptés par WhatsApp : images JPEG/PNG (5 Mo max.), documents PDF, Word, Excel… (100 Mo max.), vidéos MP4 (16 Mo max.), audio MP3/OGG/AAC (16 Mo max.). Hors fenêtre de 24 h, utilisez un modèle à en-tête « Document » et passez le PDF dans mediaUrl avec templateName.

Réponse

201 Created
{
  "ok": true,
  "id": "8b1e6c2a-3f0d-4c55-9a8e-2f1b7d9e4a10",
  "status": "SENT",
  "to": "237699112233",
  "metaMessageId": "wamid.HBgMMjM3Njk5MTEyMjMzFQIAERgSM0Q…"
}
ChampDescription
idIdentifiant KoraFlow du message. Conservez-le pour suivre son statut.
statusToujours SENT à ce stade : Meta a accepté le message. La livraison réelle arrive ensuite (voir Suivre un message).
metaMessageIdIdentifiant WhatsApp (wamid…). Utilisable aussi avec GET /messages/{id}.

Suivre un message

GET/api/v1/messages/{id}scope : messages.read

{id} accepte l’id KoraFlow ou le metaMessageId.

cURL
curl https://api.kora-flow.com/api/v1/messages/8b1e6c2a-3f0d-4c55-9a8e-2f1b7d9e4a10 \
  -H "Authorization: Bearer kfk_VOTRE_CLE"
200 OK
{
  "data": {
    "id": "8b1e6c2a-3f0d-4c55-9a8e-2f1b7d9e4a10",
    "to": "237699112233",
    "direction": "OUTBOUND",
    "status": "READ",
    "text": "Bonjour, votre commande A1234 d'un montant de 45 000 FCFA est confirmée…",
    "template": "confirmation_commande",
    "media": null,
    "error": null,
    "metaMessageId": "wamid.HBgMMjM3Njk5MTEyMjMzFQIAERgSM0Q…",
    "createdAt": "2026-10-03T14:05:12.000Z"
  }
}

Cycle de vie d’un message

StatutSignification
SENTAccepté par Meta, en route vers le téléphone.
DELIVEREDArrivé sur le téléphone du destinataire (deux coches grises).
READOuvert par le destinataire (deux coches bleues). Absent si le destinataire a désactivé les confirmations de lecture.
FAILEDNon livré. La raison donnée par Meta est dans error (voir erreurs Meta courantes).

Plutôt que d’interroger cette route en boucle, abonnez-vous au webhook message.status_updated : vous êtes prévenu à chaque changement.

Historique

GET/api/v1/messagesscope : messages.read
Paramètre de requêteDescription
phoneFiltrer sur un numéro (conversation complète, messages entrants et sortants).
limitNombre de messages (1 à 200, défaut 50), du plus récent au plus ancien.
cURL
curl "https://api.kora-flow.com/api/v1/messages?phone=237699112233&limit=20" \
  -H "Authorization: Bearer kfk_VOTRE_CLE"

Réponse : { "data": [ …messages au même format que GET /messages/{id}… ], "count": 20 }. Les messages reçus ont direction: "INBOUND".

Modèles

GET/api/v1/templatesscope : templates.read

Liste les modèles approuvés (paramètre status=ALL pour inclure ceux en attente ou refusés). variablesCount indique combien d’éléments mettre dans variables.

200 OK
{
  "data": [
    {
      "id": "0c9d…",
      "name": "confirmation_commande",
      "language": "fr",
      "category": "UTILITY",
      "status": "APPROVED",
      "variablesCount": 3,
      "components": [
        { "type": "BODY", "text": "Bonjour, votre commande {{1}} d'un montant de {{2}} est confirmée. Livraison prévue le {{3}}." }
      ]
    }
  ]
}

Numéros expéditeurs

GET/api/v1/numbers

Si le compte a plusieurs numéros WhatsApp (ex. une agence par ville), choisissez l’expéditeur avec le champ from de POST /messages.

200 OK
{
  "data": [
    { "id": "a1f2…", "name": "Boutique Douala", "phoneNumber": "237699112233", "isDefault": true,  "status": "ACTIVE", "qualityRating": "GREEN" },
    { "id": "b7c3…", "name": "Agence Yaoundé", "phoneNumber": "237677445566", "isDefault": false, "status": "ACTIVE", "qualityRating": "GREEN" }
  ]
}

qualityRating : GREEN (bonne), YELLOW (à surveiller), RED (risque de restriction par Meta).

Contacts

GET/api/v1/contactsscope : contacts.read

Paramètres : limit (1–200, défaut 50), phone (recherche par numéro).

POST/api/v1/contactsscope : contacts.write

Crée le contact (ou met à jour son nom s’il existe déjà) et lui ajoute des tags — pratique pour cibler ensuite des campagnes dans KoraFlow.

{
  "phoneNumber": "237699112233",
  "name": "Awa Mballa",
  "tags": ["client-vip", "douala"]
}

Chaque nouveau contact compte dans la limite de contacts du forfait (erreur 402 CONTACTS_LIMIT si elle est atteinte).

Campagnes

GET/api/v1/campaignsscope : campaigns.read

Les 50 dernières campagnes avec leurs compteurs (targetCount, deliveredCount, failedCount) et leur status. Les campagnes se créent depuis le tableau de bord KoraFlow.

Assistant IA

Chaque entreprise a son propre assistant : ces routes lisent et modifient uniquement celui de l’entreprise de la clé. Les instructions décrivent l’activité, le ton et les règles de réponse ; elles s’appliquent à tous les canaux, sauf si un canal a ses propres consignes. Fonctionne avec la clé IA KoraFlow comme avec votre propre clé IA. La clé IA personnelle n’est jamais renvoyée.

GET/api/v1/assistantscope : assistant.read
200 OK
{
  "data": {
    "enabled": true,
    "instructions": "Tu es l'assistant de la boutique Awa (pagnes, Douala)…",
    "welcomeMessage": "Bienvenue chez Awa !",
    "ai": { "keyMode": "OWN", "provider": "openai", "model": "gpt-5" },
    "channels": [
      { "channel": "WHATSAPP", "enabled": true, "instructions": null, "welcomeMessage": null },
      { "channel": "MESSENGER", "enabled": true, "instructions": null, "welcomeMessage": null },
      { "channel": "INSTAGRAM", "enabled": true, "instructions": "Tutoie le client.", "welcomeMessage": null }
    ]
  }
}
PUT/api/v1/assistantscope : assistant.write

Modification partielle : seuls les champs envoyés changent. null efface un texte. Réponse : la configuration complète à jour.

cURL
curl -X PUT https://api.kora-flow.com/api/v1/assistant \
  -H "Authorization: Bearer kfk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Tu vends des pagnes et du wax. Livraison à Douala sous 24 h. Paiement Mobile Money.",
    "channels": [{ "channel": "WHATSAPP", "instructions": "Réponds en 2 phrases au maximum." }]
  }'
ChampTypeDescription
enabledbooleanActive ou coupe les réponses de l’IA
instructionsstring | nullInstructions générales (20 000 caractères max)
welcomeMessagestring | nullMessage d’accueil (2 000 caractères max)
channelsarrayPar canal (WHATSAPP, MESSENGER, INSTAGRAM) : enabled, instructions, welcomeMessage

Chaque modification est inscrite au journal d’audit de l’entreprise (avec l’identifiant de la clé). Erreurs : 400 INVALID_REQUEST, 400 EMPTY_UPDATE, 403 si la clé n’a pas le scope.

Consommation & compte

GET/api/v1/usage
200 OK
{
  "plan": "Pro (Croissance)",
  "period": "month",
  "messages": { "used": 3820, "limit": 10000 },
  "contacts": { "used": 1240, "limit": 10000 },
  "thisKey": { "messagesThisMonth": 2950 }
}

period vaut month pour les forfaits payants (remise à zéro le 1er du mois) et total pour le forfait gratuit (quota cumulé). thisKey donne la consommation de la clé utilisée.

GET/api/v1/me

Compte, scopes de la clé, forfait et débit autorisé (voir Démarrage rapide).

Webhooks

Les webhooks vous préviennent en temps réel : KoraFlow envoie une requête POST en JSON vers votre URL à chaque événement. Configurez-les dans Réglages → Intégrations → Webhooks sortants : saisissez l’URL HTTPS, cochez les événements, conservez le secret affiché, puis cliquez sur Tester.

Événements

ÉvénementDéclenché quand…
message.receivedun client envoie un message WhatsApp
message.sentun message est envoyé via l’API
message.status_updatedun message passe à DELIVERED, READ ou FAILED
contact.createdun contact est créé (tableau de bord ou API)
campaign.launchedune campagne démarre
campaign.completedtous les messages d’une campagne ont été traités
lead.capturedun prospect remplit un formulaire Facebook Lead Ads
form.completedun client termine un formulaire WhatsApp KoraFlow (réponses incluses ; contactId nul si le formulaire est anonyme)
form.automationaction « webhook » d'une automatisation de formulaire : envoyé au seul webhook choisi dans l'automatisation (événement, formulaire, session ; contactId nul si anonyme ; même identifiant d'événement à chaque nouvel essai)
webhook.testvous cliquez sur « Tester »

Format de la requête

En-têteValeur
Content-Typeapplication/json
X-KoraFlow-Eventnom de l’événement (ex. message.received)
X-KoraFlow-Event-Ididentifiant unique de l’événement, identique à chaque nouvelle tentative (dédoublonnage)
X-KoraFlow-Signaturesha256=<HMAC-SHA256 hexadécimal du corps brut, avec votre secret>
User-AgentKoraFlow-Webhook/1.0

Tous les événements partagent la même enveloppe ; le contenu propre à l’événement est dans data :

{
  "id": "9b1f…",
  "event": "message.received",
  "tenantId": "4f6c…",
  "timestamp": "2026-10-03T14:07:40.120Z",
  "data": {
    "messageId": "c41d…",
    "contactId": "5d2a…",
    "phoneNumber": "237699112233",
    "contactName": "Awa Mballa",
    "text": "Bonjour, je veux commander 2 sacs de riz",
    "metaMsgId": "wamid.HBgM…",
    "receivedAt": "2026-10-03T14:07:39.000Z"
  }
}

Vérifier la signature

Vérifiez toujours X-KoraFlow-Signature pour être sûr que la requête vient de KoraFlow. Calculez le HMAC-SHA256 du corps brut (avant tout décodage JSON) avec votre secret, puis comparez.

import crypto from "crypto";
import express from "express";

const app = express();

app.post("/webhooks/koraflow", express.raw({ type: "application/json" }), (req, res) => {
  const expected = "sha256=" + crypto
    .createHmac("sha256", process.env.KORAFLOW_WEBHOOK_SECRET)
    .update(req.body) // Buffer brut
    .digest("hex");
  const received = req.get("X-KoraFlow-Signature") || "";
  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);

  const { event, data } = JSON.parse(req.body.toString("utf8"));
  res.sendStatus(200); // répondre vite, traiter ensuite
  if (event === "message.received") handleIncoming(data);
  if (event === "message.status_updated") updateDelivery(data.messageId, data.status);
});

Livraison et nouvelles tentatives

  • Votre endpoint doit répondre un code 2xx en moins de 10 secondes. Répondez d’abord, traitez ensuite (file d’attente, tâche de fond).
  • En cas d’échec (code non-2xx, délai dépassé, erreur réseau), KoraFlow réessaie 2 fois : après 2 s puis après 5 s.
  • Un même événement peut exceptionnellement arriver deux fois : dédoublonnez avec data.messageId (ou data.metaMsgId).
  • L’ordre d’arrivée n’est pas garanti (un READ peut arriver avant un DELIVERED) : ne faites jamais régresser un statut.
  • L’historique des livraisons (code HTTP, réponse de votre serveur) est visible dans Réglages → Intégrations.

Erreurs

En cas d’erreur, la réponse contient un message lisible et, le plus souvent, un code stable à utiliser dans votre programme :

402 Payment Required
{
  "error": "Limite de 10000 messages mensuels atteinte sur le forfait Pro (Croissance). Passez au forfait supérieur dans « Abonnement » ou attendez le mois prochain.",
  "code": "MESSAGES_LIMIT"
}
HTTPcodeCauseQue faire
400INVALID_PARAMChamp manquant ou invalide (to, text, templateName, from…)Corriger la requête
401—Clé absente, mal formée ou révoquéeVérifier l’en-tête Authorization
402MESSAGES_LIMITQuota de messages du forfait atteintChanger de forfait ou attendre le mois suivant
402CONTACTS_LIMITLimite de contacts du forfait atteinteChanger de forfait
402API_NOT_IN_PLANL’API n’est pas incluse dans le forfaitChanger de forfait
403—La clé n’a pas le scope requisCréer une clé avec le bon scope
404NOT_FOUNDMessage introuvableVérifier l’id
409WHATSAPP_NOT_CONNECTEDAucun numéro WhatsApp connecté au compteConnecter WhatsApp dans Réglages
429RATE_LIMITEDTrop de requêtes par minuteAttendre Retry-After secondes
502META_ERRORMeta a refusé l’envoi (détails dans details)Voir le tableau ci-dessous
500—Erreur interne KoraFlowRéessayer plus tard avec la même Idempotency-Key

Erreurs Meta courantes

Elles apparaissent dans details (réponse 502) ou dans error d’un message FAILED.

Code MetaSignificationSolution
131047Plus de 24 h depuis le dernier message du clientEnvoyer un modèle
132001Le modèle n’existe pas (nom ou langue incorrects)Vérifier GET /templates
132000Nombre de variables incorrectFournir exactement variablesCount valeurs
131026Message non livrable (numéro sans WhatsApp, version trop ancienne…)Vérifier le numéro
131049Meta a limité les messages marketing vers ce destinataireRéessayer plus tard, espacer les envois marketing
131056Trop de messages vers le même destinataire en peu de tempsEspacer les envois
131053Fichier média illisible ou trop lourdVérifier l’URL et le format

Limites & idempotence

Débit

Le nombre de requêtes par minute est limité par clé, selon le forfait. Valeurs standard ci-dessous ; la valeur exacte de votre compte est renvoyée par GET /me (rateLimitPerMinute).

ForfaitRequêtes / minute / clé
Gratuit (Découverte)10
Starter30
Pro120
Enterprise600

Chaque réponse indique où vous en êtes :

En-têteDescription
X-RateLimit-LimitRequêtes autorisées par minute
X-RateLimit-RemainingRequêtes restantes dans la minute en cours
X-RateLimit-ResetDébut de la minute suivante (timestamp Unix, secondes)
Retry-AfterSecondes à attendre (uniquement sur une réponse 429)

Pour des envois en masse (plusieurs centaines de destinataires), préférez les campagnes du tableau de bord : elles gèrent le rythme d’envoi pour vous.

Idempotence

Un réseau instable peut vous faire perdre une réponse alors que le message est parti. Pour réessayer sans risque de doublon, ajoutez Idempotency-Key à POST /messages :

  • même clé + même compte API dans les 24 h → la réponse d’origine est renvoyée, avec l’en-tête Idempotent-Replayed: true, et rien n’est renvoyé à WhatsApp ;
  • les réponses 429 et 5xx ne sont pas mémorisées : vous pouvez réessayer avec la même clé ;
  • construisez la clé à partir de votre donnée métier : otp-{userId}-{timestamp}, commande-{ref}-expedition…

Recettes

Envoyer un code de vérification (OTP)

Créez un modèle de catégorie AUTHENTICATION (ex. code_verification : « Votre code est {{1}} »), puis :

JavaScript
const code = String(Math.floor(100000 + Math.random() * 900000));
await saveOtp(user.id, code, { expiresInMinutes: 10 }); // dans VOTRE base

await fetch("https://api.kora-flow.com/api/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.KORAFLOW_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": `otp-${user.id}-${Date.now()}`,
  },
  body: JSON.stringify({ to: user.phone, templateName: "code_verification", variables: [code] }),
});

Confirmation de commande + facture PDF

  1. Créez un modèle UTILITY avec un en-tête Document : « Merci {{1}} ! Voici la facture de votre commande {{2}} ».
  2. Générez le PDF sur une URL publique (lien signé valable quelques heures, par exemple).
  3. Envoyez le modèle en passant le PDF dans mediaUrl :
JSON
{
  "to": "237699112233",
  "templateName": "facture_commande",
  "variables": ["Awa", "A1234"],
  "mediaUrl": "https://exemple.com/factures/A1234.pdf?signature=…"
}

Brancher votre propre chatbot ou CRM

  1. Abonnez un webhook à message.received.
  2. À chaque message, votre serveur calcule la réponse.
  3. Il répond avec un text libre : le client vient d’écrire, la fenêtre de 24 h est ouverte.
Node.js
async function handleIncoming(data) {
  const answer = await monBot.repondre(data.phoneNumber, data.text);
  await fetch("https://api.kora-flow.com/api/v1/messages", {
    method: "POST",
    headers: { "Authorization": `Bearer ${process.env.KORAFLOW_API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ to: data.phoneNumber, text: answer }),
  });
}

Chatbot KoraFlow et chatbot externe

Si vous répondez vous-même via l’API, désactivez le chatbot / l’IA de KoraFlow (Réglages → Chatbot) pour éviter que le client reçoive deux réponses.

Make, Zapier, n8n (sans code)

Dans votre scénario, ajoutez un module HTTP → Make a request (Make), Webhooks by Zapier → Custom Request (Zapier) ou HTTP Request (n8n) :

RéglageValeur
MéthodePOST
URLhttps://api.kora-flow.com/api/v1/messages
En-têtesAuthorization = Bearer kfk_… et Content-Type = application/json
Corps (JSON){"to": "<téléphone>", "templateName": "confirmation_commande", "variables": ["<réf>", "<montant>"]}

Remplacez les valeurs entre chevrons par les champs de l’étape précédente (ligne Google Sheets, commande WooCommerce, formulaire…).

Bonnes pratiques

  • Une clé par application et par environnement (« ERP – production », « Site – test ») avec le minimum de scopes. En cas de fuite, révoquez une seule clé.
  • Modèles pour le premier contact, texte libre seulement pour répondre dans les 24 h.
  • Toujours une Idempotency-Key sur les envois déclenchés par un événement métier (commande, paiement, OTP).
  • Webhooks plutôt que interrogation en boucle pour suivre les statuts et les réponses.
  • Gérez le 402 : prévenez l’administrateur du compte quand le quota est atteint au lieu de réessayer en boucle.
  • Numéros propres : stockez-les au format international dès la saisie (237…, 225…, 221…).
  • Respectez le consentement et proposez toujours un moyen de se désabonner pour les messages marketing.

Versions

L’API est versionnée dans l’URL (/api/v1). Dans une même version, nous pouvons ajouter des champs, des routes ou des événements sans préavis : ignorez les champs que vous ne connaissez pas. Tout changement incompatible fera l’objet d’une nouvelle version (/api/v2).

DateChangement
3 octobre 2026Envoi de médias, choix du numéro expéditeur (from), Idempotency-Key, GET /messages/{id}, /messages, /templates, /numbers, /usage ; limites de débit par forfait ; messageId et raison d’échec dans message.status_updated ; événement message.sent.
13 septembre 2026Variables de modèle (variables) dans POST /messages.
2026Première version : contacts, envoi texte et modèle, campagnes, webhooks signés.

Besoin d’aide pour votre intégration ?

Écrivez-nous à contact@tch-solution.com en précisant le id du message ou l’heure de la requête (jamais votre clé API). Notre équipe peut aussi réaliser l’intégration pour vous.