Note de langue
Cette version française est une traduction abrégée : les sections « 4. Personalization and locale », « 8. Subscribe to campaign webhooks » et « Worked example: retail promo, draft to analytics » n’existent qu’en anglais : /en/guides/campaign-end-to-end. Les blocs de code, chemins d’endpoints, noms de champs API et codes d’erreur restent en anglais.Envoyer une campagne de bout en bout
Ce guide parcourt le cycle de vie complet d’une campagne via l’API : créer un brouillon, attacher une audience, vérifier la personnalisation, exécuter le dry-run de pré-vol, lancer et mesurer le résultat. Une fois parcouru, la même séquence fonctionne pour chaque canal — SMS, WhatsApp, e-mail, RCS, voice, push.1. Prérequis
- Une clé API avec le scope
campaigns:write. Toutes les lectures ci-dessous (aperçu d’audience, dry-run, statistiques) acceptent aussicampaigns:read, mais les actions de lancement exigent l’écriture. Créez ou modifiez vos clés dans le dashboard sous Settings → API keys. - Node SDK (optionnel).
npm install @devotel-orbit/nodesi vous préférez les onglets SDK à cURL. - Une identité d’envoi pour votre canal. Pour SMS/MMS, un numéro ou un pool d’expéditeurs avec les enregistrements adéquats (l’A2P américain exige 10DLC) ; pour WhatsApp, une WABA connectée ; pour l’e-mail, un domaine expéditeur vérifié.
- Une source d’audience légitime. Une liste de contacts, un segment live, un CSV d’adresses, une audience CRM externe (liste HubSpot / rapport Salesforce) ou un jeu de contacts choisi à la main. Les audiences doivent venir de destinataires ayant donné leur opt-in — la suppression et les désabonnements sont appliqués à l’envoi, pas laissés à l’expéditeur.
2. Créer la campagne brouillon
Créez la campagne avec un canal, une audience et unmessage_template. Le template est optionnel à la création — un brouillon sans template ne peut pas être lancé — mais le fournir d’emblée garde le brouillon complet.
La réponse rend la campagne au statut
draft. Rien n’est envoyé tant que l’étape 6 ne la lance pas explicitement.
3. Attacher et vérifier l’audience
Liste ou segment. Passezaudience_type: "list" | "segment" avec une audience_id, ou un descripteur CRM audience_source. Les segments sont évalués en direct à l’envoi — un segment qui grandit continue de fonctionner.
Destinataires CSV. Pour une liste ponctuelle, POSTez les adresses directement dans le tableau variables.csv_recipients de la campagne (E.164 pour les canaux téléphoniques).
Sélection manuelle. audience_type: "manual" avec variables.manual_contact_ids cible des identifiants de contact précis — même calcul d’éligibilité qu’une liste.
Avant le lancement, comptez toujours ce à quoi l’audience se résout. POST /api/v1/campaigns/audience/preview accepte la même forme d’audience que la campagne et rend matching_count plus un échantillon de 10 contacts :
channel, la réponse rend aussi une projection nette : correspondances brutes moins les lignes en suppression, moins les opt-outs du canal, moins les contacts sans adresse joignable pour ce canal. Si matching_count revient à 0, corrigez l’audience avant d’aller plus loin — c’est ici que vous itérez.
5. Pré-vol : exécuter le dry-run
Avant le lancement, POSTez le dry-run. Il est en lecture seule — il ne modifie aucun état, ne touche pas le portefeuille et n’enfile aucun job.audience.total_in_audience— nombre brut de correspondances.audience.suppressed/opted_out/unreachable— les cohortes de la projection nette.audience.deliverable— le compte net exact que le lancement tentera.cost.unit_price_cents/cost.total_cents— tarifié par le même résolveur que le chemin d’envoi.cost.balance_cents/cost.sufficient— contrôle du portefeuille ; un dry-run vert implique une porte de solde verte au lancement.quiet_hours.skipped_estimateetquiet_hours.window— proportion de sauts projetée due aux quiet hours locales des destinataires.warnings[]— problèmes non bloquants, rendus séparément des échecs durs.
warnings: [] et cost.sufficient: true dégage le lancement.
6. Lancer et choisir la forme d’envoi
Lancez avecPOST /api/v1/campaigns/cmp_abc123/send (ou scheduled_at pour un lot différé). Quatre formes d’envoi au choix :
Blast. Un lot à un horaire — la forme la plus simple ; toute l’audience joignable part en une passe à la cadence throttle_rate.
Séquence drip. type: "drip" avec un tableau steps (jusqu’à 50 étapes). Chaque étape a son canal, son délai et son éventuelle condition de lecture.
Journey. type: "journey" — enrôlement piloté par événements avec des analyses par nœud.
Échelle de repli multi-canal. Pour les campagnes omnicanal, le tableau channels est une chaîne ordonnée ; chaque entrée sauf la dernière porte un déclencheur fallback_on (failed, no_delivery ou no_engagement) et une fenêtre fallback_after_seconds.
Quels que soient la forme, ces réglages de cadence s’appliquent :
- Throttle.
throttle_rate(msg/s) plafonne le rythme — le défaut de la plateforme est 50 msg/s. - Smart send.
send_time_optimization: "recipient-optimal"planifie chaque destinataire à sa prochaine meilleure fenêtre et étale la livraison sur les 24 h suivantes. - Fenêtre d’envoi.
send_window: { start_local_hour, end_local_hour }diffère les destinataires dont l’heure locale sort de la fenêtre.
7. Observer et mesurer
Statistiques live.GET /campaigns/:id/stats rend les totaux sent, delivered, failed, opened, clicked, replied.
Lift de holdout. Si la campagne a défini un holdout (campaign_holdout_percent dans variables), GET /campaigns/:id/holdout-lift compare la cohorte traitée au témoin et rend un écart de conversion avec intervalle de confiance — vous voyez si le message a fait mieux que ne rien envoyer.
ROI / ROAS. GET /campaigns/:id/roas rend le revenu attribué, l’entonnoir de clics et le revenu incrémental du holdout ; GET /campaigns/:id/cost et /campaigns/:id/export servent à rapprocher la dépense.
9. Dépannage
- L’audience se résout à zéro. Relancez l’aperçu d’audience avec
channel; la projection nette indique quelle cohorte l’a vidée. - Le dry-run montre des avertissements rouges. Les entrées de
warnings[]sont explicites — « no provider registered » signifie que le canal n’a pas d’identité d’envoi configurée ; « insufficient balance » signifiecost.sufficient: false. - Le lancement rend 402 ou une forme pending-approval. Le contrôle de solde a échoué, ou le circuit d’approbation est actif — rechargez le portefeuille ou attendez l’approbation.
- Campagne journey bloquée en paused. Une campagne se met en pause automatiquement à
credit_cap_usd_centsou sur une condition drip cassée. Levez le blocage puisPOST /campaigns/:id/resume.