Cette documentation couvre les capacités déjà exposées: authentification HMAC, ingestion de contacts, dispatch Trigger.dev prioritaire et compatibilité legacy.
/v1/campaigns/{campaignId}/contactsPayload
external_id"crm-contact-789"CRMphone_e164"+33612345678"E.164consenttruerequisLe contact est accepté et la queue prend le relais.
Priorité
60
Résultat
UI native
Création, révocation, régénération et suivi depuis Paramètres > Intégrations.
Chaque appel signé avec timestamp anti-replay et secret chiffré côté serveur.
Ajout progressif de contacts à une campagne existante pendant sa période de collecte.
Déclenchement Trigger.dev en priorité 60, sans attendre la fin de l’appel.
Les clés se créent depuis l’espace connecté. Le client signe le body brut avec son secret; Vox vérifie la signature, l’expiration et la fenêtre anti-replay.
const crypto = require('crypto')
const payload = {
external_id: 'crm-contact-789',
phone_e164: '+33612345678',
consent: true,
}
const rawBody = JSON.stringify(payload)
const timestamp = new Date().toISOString()
const dataToSign = `${timestamp}.${rawBody}`
const signature = crypto
.createHmac('sha256', apiSecret)
.update(dataToSign)
.digest('hex')/v1/campaigns/{campaignId}/contactscurl -X POST "https://voxsatisfy.com/v1/campaigns/123/contacts" \
-H "content-type: application/json" \
-H "x-api-key: vox_xxxxxxxxxxxxxxxxxxxx" \
-H "x-timestamp: 2026-06-14T12:00:00.000Z" \
-H "x-signature: 8f6d...d2a1" \
-d '{
"external_id": "crm-contact-789",
"phone_e164": "+33612345678",
"email": "client@example.com",
"first_name": "Jean",
"last_name": "Dupont",
"consent": true
}'`external_id` vient de votre système.
Utilisez l’identifiant stable de votre CRM, outil support, ERP ou base interne. VoxSatisfy s’en sert pour reconnaître le même contact lors des prochains envois.
La campagne est portée par l’URL. Le body contient uniquement les informations du contact à injecter.
campaignIdIdentifiant de la campagne VoxSatisfy qui doit recevoir le contact.
Exemple
123external_idIdentifiant du contact dans votre CRM, ERP, outil support ou base interne. Recommandé pour éviter les doublons.
Exemple
crm-contact-789phone_e164Numéro de téléphone au format E.164. C’est le champ utilisé pour déclencher l’appel ou le SMS.
Exemple
+33612345678emailAdresse email du contact, conservée dans sa fiche pour enrichir le contexte.
Exemple
client@example.comfirst_namePrénom du contact, utilisé pour personnaliser les échanges et les vues UI.
Exemple
Jeanlast_nameNom du contact, visible dans les listes et les statistiques de campagne.
Exemple
DupontgenderChamp libre de segmentation si votre outil source transmet cette information.
Exemple
maleconsentDoit être true sur la route canonique. Vox refuse l’ingestion sans consentement explicite.
Exemple
trueopt_inVaut true par défaut. Si false, Vox considère le contact comme opposé et refuse le traitement.
Exemple
true{
"success": true,
"data": {
"contact": {
"id": 123,
"external_id": "crm-contact-789"
},
"campaign_run": {
"id": 456,
"status": "pending"
},
"dispatch": {
"queued": true,
"trigger_run_id": "run_xxx",
"priority": 60
}
}
}La route canonique exige consent: true.
external_id évite les doublons sur la liste de campagne.
La réponse arrive dès que la queue est acceptée.
Étape 1
La signature est vérifiée avant lecture métier.
Étape 2
La clé doit appartenir au propriétaire de la campagne.
Étape 3
Téléphone E.164, consentement et idempotence par external_id.
Étape 4
Vox crée ou réutilise le run de campagne du contact.
Étape 5
Trigger.dev enfile le traitement et lance le scénario.
Résultats transparents dans l’UI
Les contacts injectés par API alimentent la même campagne et les mêmes statistiques.

INVALID_API_KEYINVALID_SIGNATURETIMESTAMP_EXPIREDRATE_LIMITEDCAMPAIGN_NOT_FOUNDCAMPAIGN_FORBIDDENCAMPAIGN_CLOSEDCOLLECTION_CLOSEDINVALID_CONTACTCONSENT_REQUIREDCONTACT_INGESTION_FAILEDALREADY_IN_PROGRESSALREADY_COMPLETEDTRIGGER_DISPATCH_FAILEDLa route historique accepte toujours la clé `CONTACTS_API_KEY`, `campaign_id` dans le body et `list_id` temporairement. Elle utilise maintenant le même service d’ingestion et déclenche aussi Trigger.dev en priorité.
/api/contacts/v1/campaigns/{campaignId}/contacts.curl -X POST "https://voxsatisfy.com/api/contacts" \
-H "content-type: application/json" \
-H "x-api-key: legacy_contacts_api_key" \
-d '{
"campaign_id": 123,
"list_id": 456,
"external_id": "crm-contact-789",
"phone_e164": "+33612345678"
}'Cette route conserve l’ancien contrat: la campagne est transmise dans le body et list_id reste accepté temporairement.
campaign_idIdentifiant de la campagne VoxSatisfy. La route legacy le reçoit dans le body.
Exemple
123list_idAccepté temporairement pour compatibilité. S’il est transmis, il doit correspondre à la liste de la campagne.
Exemple
456external_idIdentifiant du contact dans votre outil interne. Recommandé pour rattacher les futurs appels au même contact.
Exemple
crm-contact-789phone_e164Numéro de téléphone au format E.164, obligatoire pour lancer le scénario.
Exemple
+33612345678emailAdresse email optionnelle pour enrichir la fiche contact.
Exemple
client@example.comfirst_namePrénom optionnel du contact.
Exemple
Jeanlast_nameNom optionnel du contact.
Exemple
DupontgenderChamp libre optionnel transmis depuis l’outil source.
Exemple
maleconsentToléré sur la route legacy, mais non obligatoire pour conserver la compatibilité existante.
Exemple
trueopt_inVaut true par défaut. Si false, le contact est refusé.
Exemple
trueCes capacités existent côté produit ou pourront venir plus tard, mais elles ne sont pas exposées dans l’API publique actuelle.