Envoyer des donnees par webhook
Cette page explique exactement quoi envoyer a DURUM.ai pour que l'app fonctionne a son plein potentiel. Que vous utilisiez GHL, Typeform, Calendly, Stripe, Zoho, Pipedrive ou un outil custom, les regles sont les memes.
Les 3 choses absolument essentielles
Sans ces 3 elements, votre evenement ne sera pas traite correctement.
1. Identifier votre compte (client_key)
Chaque webhook doit etre associe a votre compte. Il y a deux facons de le faire :
Option A -- Dans l'URL (recommande) :
https://app.durum.ai/api/webhook/lead?client_key=VOTRE_CLEOption B -- Dans le payload JSON :
{ "client_key": "VOTRE_CLE", "email": "..." }Sans client_key
L'evenement est mis en quarantaine. Il ne sera pas perdu, mais il devra etre classe manuellement par l'agence. Vos KPIs ne seront pas a jour en temps reel.
2. Identifier le contact (email ou telephone)
DURUM.ai doit pouvoir identifier qui est le prospect. Envoyez au minimum un de ces champs :
| Champ | Exemple | Priorite |
|---|---|---|
email | jean.tremblay@email.com | Ideal -- sert aussi a la deduplication et a l'attribution |
phone | +15145551234 | Bon backup -- format E.164 ou 10 chiffres |
name | Jean Tremblay | Utile mais insuffisant seul |
Sans email ni telephone
L'evenement sera quand meme enregistre, mais le systeme ne pourra pas :
- Detecter les doublons (risque de compter 2 fois le meme lead)
- Relier le lead a ses futures actions (booking, vente)
- Enrichir les donnees avec l'historique du contact
3. Envoyer au bon endpoint
Chaque type d'evenement a son propre endpoint. C'est ce qui determine le type dans DURUM.ai.
| Quand | Endpoint | Ce qui est cree |
|---|---|---|
| Un prospect montre de l'interet | /api/webhook/lead | Lead |
| Un prospect remplit un formulaire detaille | /api/webhook/application | Application |
| Un rendez-vous est reserve | /api/webhook/booking | Booking |
| Un prospect ne se presente pas | /api/webhook/no-show | No-show |
| Une vente est conclue | /api/webhook/sale | Vente |
| Un paiement est recu | /api/webhook/payment | Paiement |
| Un remboursement est emis | /api/webhook/refund | Remboursement |
Les 13 champs d'attribution publicitaire
Ces champs permettent a DURUM.ai de relier chaque lead, booking et vente a la publicite exacte qui l'a genere. C'est ce qui alimente le tableau Marketing, le calcul du CPA, ROAS, ROI, et toute l'attribution dans l'app.
Sans ces champs, l'app perd sa valeur principale
Un lead sans UTMs arrive dans DURUM.ai mais il est impossible de savoir de quelle publicite il vient. Vos KPIs marketing (CPA, ROAS, ROI) seront fausses. Vous ne saurez pas quel ad performe et lequel gaspille votre budget.
Les 5 UTMs (noms des elements publicitaires)
Ce sont les noms lisibles de vos campagnes, publicites et adsets. DURUM.ai les utilise pour matcher les events avec vos publicites Meta.
| # | Champ | Alias acceptes | Ce que ca fait dans l'app | Exemple | Priorite |
|---|---|---|---|---|---|
| 1 | utm_campaign | utmcampaign, UTM_Campaign, campaign_name | Lie l'event a la campagne. Utilise dans le tableau Marketing, le filtre par campagne, et le calcul du spend par campagne. | bootcamp-mars-2026 | Non negociable |
| 2 | utm_content | utmcontent, UTM_Content, ad_name, utm_ad_name | Lie l'event a la publicite (ad). C'est LE champ qui connecte un lead a un ad dans Meta. Sans lui, pas d'attribution par ad. | ad-temoignage-tx1-ix2 | Non negociable |
| 3 | utm_source | utmsource, UTM_Source | Identifie la source du trafic. Permet de distinguer Meta vs Google vs organique dans les rapports. | meta, google, tiktok, organic | Important |
| 4 | utm_medium | utmmedium, UTM_Medium | Identifie le type de trafic. Distingue le paid du organique, de l'email, du social. | paid, cpc, email, social, organic | Important |
| 5 | utm_term | utmterm, UTM_Term, utm_adset_name, adset_name | Lie l'event a l'adset. Permet l'analyse de performance par audience/adset. | adset-lookalike-1pct, adset-retarget-30j | Recommande |
Les 3 IDs Meta (identifiants numeriques)
Ce sont les IDs numeriques de Meta Ads. Ils permettent un match exact au lieu de matcher par nom (plus fiable si vous renommez une campagne).
| # | Champ | Alias acceptes | Ce que ca fait dans l'app | Exemple | Priorite |
|---|---|---|---|---|---|
| 6 | utm_campaign_id | campaign_id | Match exact avec la campagne Meta par ID au lieu du nom | 120210987654321 | Recommande |
| 7 | utm_ad_id | ad_id | Match exact avec la publicite Meta par ID au lieu du nom | 120210123456789 | Recommande |
| 8 | utm_adset_id | adset_id | Match exact avec l'adset Meta par ID au lieu du nom | 120210111222333 | Recommande |
Noms vs IDs -- pourquoi les deux?
Les noms (utm_campaign, utm_content, utm_term) sont lisibles et utiles dans les tableaux. Les IDs (utm_campaign_id, utm_ad_id, utm_adset_id) sont fiables meme si vous renommez une campagne. Idealement, envoyez les deux. Si vous ne pouvez envoyer qu'un seul, envoyez les noms.
Les 2 champs de tracking avance
Pour l'attribution first-party et les outils tiers comme Hyros.
| # | Champ | Ce que ca fait dans l'app | Exemple | Priorite |
|---|---|---|---|---|
| 9 | fbc_id | Facebook Click ID -- Identifiant unique du clic publicitaire Meta. Permet l'attribution meme si les cookies sont bloques. Capture par le parametre fbclid dans l'URL. | fb.1.1612345678.abc123def456 | Optionnel (bonus) |
| 10 | h_ad_id | Hyros Ad ID -- Si vous utilisez Hyros pour le tracking, cet ID permet le lien direct. | 120210123456789 | Optionnel (si Hyros) |
Les 3 champs complementaires
| # | Champ | Alias acceptes | Ce que ca fait dans l'app | Exemple | Priorite |
|---|---|---|---|---|---|
| 11 | product_key | product, funnel_key | Identifie le produit ou service. Alimente le funnel par produit, les revenus par produit, et les commissions. | bootcamp_ai | Important |
| 12 | assigned_user_name | assigned_to, Deal_Owner, rep_name | Identifie le rep de vente assigne. Alimente le tableau Ventes Reps et les commissions par rep. | Marie Dupont | Recommande |
| 13 | amount | value, total, Amount, Grand_Total | Montant en dollars de la vente ou du paiement. Sans ce champ, le ROI, ROAS et les revenus sont a $0. | 2500 | Non negociable (ventes/paiements) |
Produits reconnus automatiquement
bootcamp_ai, scaler_vos_ventes, propulsion, club_prive, mastermind_ai, formation_croisiere, accelerateur, acquisition_entreprises. Tout autre nom est accepte et converti en slug (ex : Mon Produit devient mon_produit).
Comment configurer les UTMs dans Meta Ads
Quand vous creez une publicite Meta, configurez les parametres URL au niveau de la publicite (Ad) :
URL Parameters (dans le champ "URL Parameters" de l'ad) :
utm_source=meta&utm_medium=paid&utm_campaign={campaign.name}&utm_content={ad.name}&utm_term={adset.name}&utm_campaign_id={campaign.id}&utm_ad_id={ad.id}&utm_adset_id={adset.id}Dans Meta Ads, les variables dynamiques entre accolades ({campaign.name}, {ad.name}, etc.) sont remplacees automatiquement par les vraies valeurs. Vos outils (GHL, Typeform, Calendly) capturent ensuite ces parametres.
Ou placer les UTMs selon votre outil
| Outil | Ou les mettre | Detail |
|---|---|---|
| GHL | Custom fields du contact | utm_source, utm_campaign, utm_content, utm_term, utm_ad_id, utm_campaign_id, utm_adset_id dans le tableau customFields |
| Typeform | Hidden fields du formulaire | Injectes via l'URL du formulaire (#utm_source=meta&utm_campaign=...) |
| Calendly | Parametres UTM de la page | Calendly capture automatiquement les UTMs de la page ou le lien est affiche |
| Stripe | Metadata du checkout | client_key, product_key, utm_campaign, utm_content dans l'objet metadata |
| Zoho CRM | Champs du deal | UTM_Source, UTM_Campaign, UTM_Content, UTM_Term, utm_ad_id, utm_campaign_id |
| Zoho Books | Custom fields (cf_*) | cf_product_key, cf_source, cf_referent |
| Generique / Make / Zapier | Champs directs dans le JSON | Tous les champs au premier niveau du payload |
Exemple complet avec TOUS les champs d'attribution
{
"email": "jean.tremblay@email.com",
"phone": "+15145551234",
"name": "Jean Tremblay",
"product_key": "bootcamp_ai",
"amount": 2500,
"assigned_user_name": "Marie Dupont",
"utm_source": "meta",
"utm_medium": "paid",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1-ix2",
"utm_term": "adset-lookalike-1pct",
"utm_campaign_id": "120210987654321",
"utm_ad_id": "120210123456789",
"utm_adset_id": "120210111222333",
"fbc_id": "fb.1.1612345678.abc123def456",
"h_ad_id": "120210123456789"
}Les reponses aux questions de vos formulaires
Chaque client pose des questions differentes dans ses formulaires (GHL, Typeform, Calendly). Toutes les reponses sont capturees et stockees, meme si elles ne correspondent pas a des champs standard. Rien n'est perdu.
Ce qui est stocke
Toutes les reponses arrivent dans le champ raw_payload de l'evenement (format JSONB). C'est un stockage complet du payload original -- chaque question, chaque reponse, chaque champ custom.
En plus du stockage brut, certains champs sont extraits automatiquement vers des colonnes dediees (email, telephone, nom, UTMs). Les autres restent dans raw_payload et sont accessibles pour des analyses, des exports ou des filtres avances.
Typeform -- toutes les reponses du formulaire
Chaque reponse est capturee avec la question posee (le titre du champ) et la reponse donnee, quel que soit le type.
Exemples de questions custom que vos clients posent dans leurs formulaires Typeform :
| Question dans le formulaire | Type | Exemple de reponse | Stocke dans |
|---|---|---|---|
| Quel est votre chiffre d'affaires annuel? | number | 500000 | raw_payload |
| Quel est votre secteur d'activite? | choice | E-commerce | raw_payload |
| Quelles plateformes publicitaires utilisez-vous? | choices | ["Facebook Ads", "Google Ads"] | raw_payload |
| Quel est votre objectif principal? | text | Doubler mes ventes en 6 mois | raw_payload |
| Combien d'employes avez-vous? | number | 15 | raw_payload |
| Avez-vous un site web? | url | https://mon-entreprise.com | raw_payload |
| Date souhaitee pour commencer? | date | 2026-04-15 | raw_payload |
| Acceptez-vous d'etre contacte? | boolean | true | raw_payload |
| Votre courriel | email | jean@email.com | raw_payload + contact_email |
| Votre telephone | phone_number | +15145551234 | raw_payload + contact_phone |
| Votre nom complet | text (si le titre contient "nom") | Jean Tremblay | raw_payload + contact_name |
Structure dans le payload -- chaque reponse est stockee comme ceci :
{
"field_ref": {
"label": "Quel est votre chiffre d'affaires annuel?",
"type": "number",
"value": 500000
}
}Vous pouvez ajouter autant de questions que vous voulez dans votre Typeform. Elles seront toutes la.
GHL -- tous les custom fields du contact
GHL envoie les custom fields dans un tableau customFields. Tout le tableau est lu et stocke.
Les champs UTM et produit sont extraits vers des colonnes dediees (voir section precedente). Tous les autres custom fields sont conserves dans raw_payload.
Exemples de custom fields que vos clients configurent dans GHL :
| Custom Field GHL | Description | Exemple |
|---|---|---|
ville | Ville du prospect | Montreal |
entreprise | Nom de l'entreprise | Tremblay Inc. |
chiffre_affaires | CA annuel | 500000 |
nb_employes | Taille de l'equipe | 15 |
budget_mensuel | Budget marketing | 5000 |
secteur_activite | Secteur | E-commerce |
objectif_principal | Objectif | Augmenter mes ventes de 50% |
comment_avez_vous_entendu | Source declaree | Publicite Facebook |
qualification_score | Score attribue par le rep | 8 |
revenue_attendu | Revenue estime de la vente | 2500 |
type_entreprise | B2B, B2C, D2C | B2C |
experience_pub | Experience publicitaire | Debutant |
outil_crm_actuel | CRM utilise | HubSpot |
delai_decision | Urgence | Ce mois-ci |
Comment les envoyer :
{
"contact": {
"email": "jean@email.com",
"customFields": [
{ "field_name": "ville", "value": "Montreal" },
{ "field_name": "entreprise", "value": "Tremblay Inc." },
{ "field_name": "chiffre_affaires", "value": "500000" },
{ "field_name": "nb_employes", "value": "15" },
{ "field_name": "objectif_principal", "value": "Augmenter mes ventes" },
{ "field_name": "budget_mensuel", "value": "5000" },
{ "field_name": "qualification_score", "value": "8" }
]
}
}Pas de limite
Vous pouvez ajouter autant de custom fields que necessaire. Il n'y a pas de liste predeterminee -- tout ce que vous envoyez dans customFields est stocke et accessible.
Calendly -- les questions de reservation
Calendly permet de poser des questions custom quand quelqu'un reserve un rendez-vous. Elles arrivent dans le tableau questions_and_answers.
Exemples de questions configurees dans Calendly :
| Question Calendly | Reponse type |
|---|---|
| Quel est le nom de votre entreprise? | Tremblay Inc. |
| Quel est votre chiffre d'affaires annuel? | 500 000$ |
| Quel est votre objectif principal pour cet appel? | Valider si le bootcamp est pour moi |
| Comment avez-vous entendu parler de nous? | Publicite Facebook |
| Nombre d'employes? | 15 |
| Avez-vous deja fait de la publicite en ligne? | Oui, Facebook Ads depuis 6 mois |
| Quel est votre budget mensuel en publicite? | 3000-5000$ |
Structure dans le payload Calendly :
{
"questions_and_answers": [
{
"question": "Quel est le nom de votre entreprise?",
"answer": "Tremblay Inc."
},
{
"question": "Quel est votre chiffre d'affaires annuel?",
"answer": "500 000$"
},
{
"question": "Objectif principal pour cet appel?",
"answer": "Valider si le bootcamp est pour moi"
}
]
}Zoho Books -- custom fields et line items
Zoho Books envoie les custom fields (prefixes cf_) et les line items (produits factures).
| Custom Field Zoho | Description |
|---|---|
cf_product_key | Identifiant du produit |
cf_source | Source de la vente (DURUM, ORGANIC) |
cf_referent | Vendeur/referent |
cf_af_contact_id | ID GHL du contact (via ActiveFunnel) |
Tout autre cf_* | Stocke dans raw_payload |
Les line items (produits factures) sont aussi captures :
{
"line_items": [
{
"name": "Bootcamp IA - Session Mars 2026",
"rate": 2500,
"quantity": 1,
"item_total": 2500
},
{
"name": "Materiel supplementaire",
"rate": 200,
"quantity": 1,
"item_total": 200
}
]
}Le systeme identifie automatiquement le produit principal (item avec le plus gros montant, en excluant les frais bancaires comme Stripe Processing Fees ou Compte Stripe).
Generique / Make / Zapier -- champs libres
Si vous construisez le JSON vous-meme, ajoutez vos champs custom directement dans le payload. Ils seront tous stockes :
{
"email": "jean@email.com",
"client_key": "avego",
"utm_campaign": "bootcamp-mars-2026",
"entreprise": "Tremblay Inc.",
"chiffre_affaires": 500000,
"nb_employes": 15,
"secteur": "E-commerce",
"objectif": "Augmenter mes ventes de 50%",
"budget_pub": 5000,
"source_declaree": "Publicite Facebook",
"questions_custom": {
"experience_pub": "Facebook Ads depuis 6 mois",
"outil_actuel": "HubSpot",
"delai": "Ce mois-ci"
}
}Tout est conserve dans raw_payload. Les champs standard (email, utm_campaign, etc.) sont en plus extraits vers des colonnes dediees.
Par type d'evenement -- quoi envoyer
Lead ou Application
Un prospect montre de l'interet ou remplit un formulaire.
POST /api/webhook/lead?client_key=VOTRE_CLE
Content-Type: application/json{
"email": "jean.tremblay@email.com",
"phone": "+15145551234",
"name": "Jean Tremblay",
"product_key": "bootcamp_ai",
"utm_source": "meta",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1"
}| Champ | Statut | Pourquoi |
|---|---|---|
email | Essentiel | Identifie le contact et permet la deduplication |
utm_campaign | Essentiel | Attribution a la campagne |
utm_content | Essentiel | Attribution a la publicite |
phone | Recommande | Backup d'identification + enrichissement |
name | Recommande | Affichage dans les tableaux |
product_key | Recommande | Classification par produit/funnel |
utm_source | Recommande | Source du trafic |
utm_ad_id | Optionnel | Lien direct avec Meta |
Booking (rendez-vous)
Un prospect reserve un rendez-vous.
POST /api/webhook/booking?client_key=VOTRE_CLE{
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"calendar_name": "Appel Decouverte",
"booking_date": "2026-04-05",
"booking_time": "14:00",
"assigned_user_name": "Marie Dupont",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1"
}| Champ | Statut | Pourquoi |
|---|---|---|
email | Essentiel | Relie le booking au lead original |
booking_date | Essentiel | Distingue "date de creation" vs "date du RDV" |
booking_time | Recommande | Analyse des creneaux no-show |
calendar_name | Recommande | Type de rendez-vous dans les tableaux |
assigned_user_name | Recommande | Associe au rep pour le suivi de performance |
| UTMs | Important | Si pas deja sur le lead, c'est la derniere chance de les capturer |
Booking date vs event date
DURUM.ai distingue la date de creation du booking (quand le prospect a reserve) de la date du rendez-vous (quand le meeting aura lieu). C'est critique pour calculer correctement les taux de no-show et le pipeline.
No-show
Un prospect ne se presente pas a son rendez-vous.
POST /api/webhook/no-show?client_key=VOTRE_CLE{
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"calendar_name": "Appel Decouverte",
"booking_date": "2026-04-05",
"booking_time": "14:00"
}Vente
Un deal est conclu (gagne ou perdu).
POST /api/webhook/sale?client_key=VOTRE_CLE{
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"amount": 2500,
"product_key": "bootcamp_ai",
"status": "won",
"assigned_user_name": "Marie Dupont",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1"
}| Champ | Statut | Pourquoi |
|---|---|---|
email | Essentiel | Relie la vente au lead et au booking |
amount | Essentiel | Calcul du revenu, ROI, ticket moyen |
status | Important | won = vente, lost = perdue. Par defaut : vente. |
product_key | Recommande | Revenu par produit, commissions |
assigned_user_name | Recommande | Performance par rep |
| UTMs | Important | Attribution de la vente a la publicite |
Sans montant
La vente apparait dans le funnel mais avec $0. Le ROI, le ROAS et les revenus seront fausses.
Paiement
Un paiement est recu (facture payee).
POST /api/webhook/payment?client_key=VOTRE_CLE{
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"amount": 2500,
"product_key": "bootcamp_ai",
"invoice_number": "INV-001234",
"payment_status": "paid"
}| Champ | Statut | Pourquoi |
|---|---|---|
email | Essentiel | Relie le paiement au client |
amount | Essentiel | Montant encaisse |
invoice_number | Recommande | Deduplication (evite de compter 2 fois si le webhook est renvoye) |
payment_status | Recommande | paid = encaisse, overdue = en retard |
product_key | Recommande | Revenu par produit |
Remboursement
POST /api/webhook/refund?client_key=VOTRE_CLE{
"email": "jean.tremblay@email.com",
"amount": 2500
}Recapitulatif -- hierarchie d'importance
| Niveau | Champs | Impact si absent |
|---|---|---|
| Non negociable | client_key (URL ou payload) | Evenement en quarantaine, pas dans vos KPIs |
| Non negociable | email ou phone | Pas de deduplication, pas de lien entre les etapes du funnel |
| Non negociable | utm_campaign + utm_content | Pas d'attribution. Impossible de savoir quel ad a genere le lead/vente. CPA, ROAS et ROI non calculables. |
| Non negociable | amount (ventes et paiements) | Revenus a $0, ROI et ROAS fausses |
| Important | utm_source + utm_medium | Impossible de distinguer Meta vs Google vs organique |
| Important | product_key | Pas de funnel par produit, pas de commissions par produit |
| Recommande | utm_term | Pas d'analyse par adset/audience |
| Recommande | utm_campaign_id + utm_ad_id + utm_adset_id | Match par nom au lieu d'ID exact (fragile si vous renommez) |
| Recommande | name, assigned_user_name | Moins de details dans les tableaux, pas de perf par rep |
| Bonus | fbc_id, h_ad_id | Attribution avancee first-party et Hyros |
Ce que DURUM.ai fait automatiquement
Vous n'avez pas besoin d'envoyer toutes les donnees dans chaque webhook. Le systeme fait un travail important en arriere-plan.
Enrichissement UTM automatique
Si un webhook arrive sans UTMs (par exemple un paiement Zoho Books), DURUM.ai cherche automatiquement les UTMs dans cet ordre :
- Custom fields GHL -- Si le contact existe dans GHL avec des champs UTM configures, ils sont recuperes
- Tracker navigateur -- Si le prospect a visite votre site avec le tracker DURUM.ai installe, ses UTMs ont ete captures automatiquement (premier clic)
- Events precedents -- Si le meme email a deja un lead ou un booking avec des UTMs, ils sont herites
Concretement : si un prospect remplit un formulaire avec les bons UTMs, puis reserve un booking, puis paie via Stripe -- meme si Stripe n'envoie aucun UTM, la vente sera attribuee a la bonne publicite grace au lead original.
TIP
C'est pourquoi les UTMs sur le premier point de contact (lead ou application) sont si importants. Meme si les etapes suivantes n'en ont pas, l'attribution fonctionnera.
Deduplication intelligente
DURUM.ai empeche automatiquement les doublons. Vous n'avez pas a vous en soucier si un webhook est envoye 2 fois.
| Source | Methode de dedup | Ce qui est verifie |
|---|---|---|
| Typeform | Token de soumission | Chaque soumission a un token unique |
| Calendly | URI de l'invite | Chaque invite a une URI unique |
| Zoho Books | Numero de facture | Meme invoice_number = meme evenement |
| GHL / Generique | Email + type + fenetre temps | Meme email + meme type dans les 24h (leads) ou 2 min (autres) |
Rep assigne automatiquement
Si vous n'envoyez pas le nom du rep (assigned_user_name), le systeme le cherche automatiquement :
- Dans le contact GHL (champ
assigned_to) - Dans les events precedents du meme contact
- Via le ID utilisateur GHL mappe a un rep dans DURUM.ai
Client identifie automatiquement
Si le client_key n'est pas dans l'URL, le systeme tente de l'identifier via :
- L'email du contact (s'il existe deja dans un compte)
- Le numero de telephone
- L'ID de contact GHL
- Le numero de facture
- L'ID client Zoho ou Stripe Connect
Alias acceptes par champ
DURUM.ai accepte plusieurs noms pour le meme champ. Utilisez celui qui correspond a votre outil.
| Ce que DURUM.ai stocke | Noms acceptes |
|---|---|
contact_email | email, contact_email, customer_email |
contact_phone | phone, contact_phone, customer_phone |
contact_name | name, contact_name, customer_name |
client_key | client_key, clientKey |
product_key | product_key, product, funnel_key |
utm_source | utm_source, utmsource, UTM_Source |
utm_campaign | utm_campaign, utmcampaign, UTM_Campaign |
utm_content | utm_content, utmcontent, UTM_Content |
utm_term | utm_term, utmterm, UTM_Term, utm_adset_name |
meta_ad_id | utm_ad_id, ad_id |
meta_campaign_id | utm_campaign_id, campaign_id |
meta_adset_id | utm_adset_id, adset_id |
value (montant) | amount, value, total, Amount, Grand_Total |
assigned_user_name | assigned_user_name, assigned_to, Deal_Owner, rep_name |
Specificites par plateforme
Chaque outil envoie les donnees dans un format different. Voici ou placer les champs importants selon votre outil.
GHL (GoHighLevel)
Les UTMs et le produit vont dans les custom fields du contact :
{
"contact": {
"email": "jean@email.com",
"customFields": [
{ "field_name": "utm_campaign", "value": "bootcamp-mars-2026" },
{ "field_name": "utm_content", "value": "ad-temoignage-tx1" },
{ "field_name": "product_key", "value": "bootcamp_ai" }
]
}
}L'URL doit inclure ?client_key=VOTRE_CLE&source=ghl.
Vous pouvez ajouter n'importe quel custom field supplementaire (ville, entreprise, chiffre_affaires, etc.). Ils seront tous conserves dans les donnees brutes.
Voir le payload GHL complet (lead)
{
"contact": {
"id": "abc123",
"firstName": "Jean",
"lastName": "Tremblay",
"email": "jean.tremblay@email.com",
"phone": "+15145551234",
"dateAdded": "2026-03-30T14:30:00.000Z",
"tags": ["lead", "bootcamp-ai"],
"assignedTo": "rep-user-id",
"customFields": [
{ "field_name": "utm_source", "value": "meta" },
{ "field_name": "utm_campaign", "value": "bootcamp-mars-2026" },
{ "field_name": "utm_content", "value": "ad-temoignage-tx1" },
{ "field_name": "utm_term", "value": "adset-lookalike-1pct" },
{ "field_name": "utm_ad_id", "value": "120210123456789" },
{ "field_name": "utm_campaign_id", "value": "120210987654321" },
{ "field_name": "product_key", "value": "bootcamp_ai" },
{ "field_name": "ville", "value": "Montreal" },
{ "field_name": "entreprise", "value": "Tremblay Inc." }
]
},
"locationId": "ghl-location-abc123",
"form": {
"id": "form-xyz-789",
"name": "Formulaire Bootcamp IA"
}
}Voir le payload GHL complet (booking)
{
"id": "appt-abc123",
"contactId": "contact-xyz789",
"contact": {
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"customFields": [
{ "field_name": "utm_campaign", "value": "bootcamp-mars-2026" }
]
},
"calendarName": "Appel Decouverte",
"startTime": "2026-04-05T14:00:00.000Z",
"appointmentStatus": "scheduled",
"assignedUserId": "user-rep-123",
"locationId": "ghl-location-abc123"
}Voir le payload GHL complet (vente)
{
"opportunity": {
"id": "opp-abc123",
"status": "won",
"monetaryValue": 2500
},
"contact": {
"id": "contact-xyz789",
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"customFields": [
{ "field_name": "product_key", "value": "bootcamp_ai" }
]
},
"locationId": "ghl-location-abc123"
}Typeform
Les UTMs et le client_key vont dans les hidden fields du formulaire :
https://form.typeform.com/to/XXXXX#client_key=VOTRE_CLE&utm_source=meta&utm_campaign=bootcamp-mars-2026&utm_content=ad-temoignage-tx1&product_key=bootcamp_aiLes reponses du formulaire (email, telephone, nom, questions custom) sont extraites automatiquement depuis le tableau answers.
Voir le payload Typeform complet
{
"form_response": {
"form_id": "sJ5lztlq",
"token": "unique-submission-token",
"definition": { "title": "Formulaire Bootcamp IA" },
"hidden": {
"client_key": "VOTRE_CLE",
"utm_source": "meta",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1",
"utm_ad_id": "120210123456789",
"product_key": "bootcamp_ai"
},
"answers": [
{ "type": "email", "email": "jean@email.com", "field": { "title": "Votre courriel" } },
{ "type": "phone_number", "phone_number": "+15145551234", "field": { "title": "Telephone" } },
{ "type": "text", "text": "Jean Tremblay", "field": { "title": "Votre nom" } },
{ "type": "choice", "choice": { "label": "E-commerce" }, "field": { "title": "Secteur" } },
{ "type": "number", "number": 500000, "field": { "title": "Chiffre d'affaires" } }
]
}
}Calendly
Les UTMs sont captures automatiquement dans l'objet tracking si l'URL de la page de reservation contient les parametres UTM. Les questions personnalisees sont dans questions_and_answers.
L'URL doit inclure ?client_key=VOTRE_CLE.
Voir le payload Calendly complet
{
"event": "invitee.created",
"payload": {
"event_type": { "name": "Appel Decouverte" },
"invitee": {
"email": "jean.tremblay@email.com",
"name": "Jean Tremblay",
"text_reminder_number": "+15145551234",
"uri": "https://api.calendly.com/scheduled_events/xxx/invitees/yyy"
},
"scheduled_event": {
"start_time": "2026-04-05T14:00:00.000Z",
"event_memberships": [{ "user_name": "Marie Dupont" }]
},
"tracking": {
"utm_source": "meta",
"utm_campaign": "bootcamp-mars-2026",
"utm_content": "ad-temoignage-tx1"
},
"questions_and_answers": [
{ "question": "Votre entreprise?", "answer": "Tremblay Inc." },
{ "question": "Chiffre d'affaires?", "answer": "500 000$" }
]
}
}Stripe
Le client_key et le product_key vont dans les metadata du checkout session ou de la facture. Les montants sont en cents (divises automatiquement par 100).
Pas besoin de client_key dans l'URL -- Stripe est detecte par sa signature.
Voir le payload Stripe complet
{
"type": "checkout.session.completed",
"data": {
"object": {
"customer_email": "jean.tremblay@email.com",
"amount_total": 250000,
"payment_status": "paid",
"customer_details": {
"name": "Jean Tremblay",
"email": "jean.tremblay@email.com"
},
"metadata": {
"client_key": "VOTRE_CLE",
"product_key": "bootcamp_ai",
"utm_campaign": "bootcamp-mars-2026"
}
}
}
}Zoho CRM
Les UTMs sont dans des champs du deal (UTM_Source, UTM_Campaign, UTM_Content). Le client_key doit etre dans l'URL.
Voir le payload Zoho CRM complet
{
"data": [{
"Deal_Name": "Jean Tremblay - Bootcamp AI",
"Stage": "Closed Won",
"Amount": 2500,
"Email": "jean.tremblay@email.com",
"Contact_Name": "Jean Tremblay",
"Owner": { "name": "Marie Dupont" },
"Product": "bootcamp_ai",
"UTM_Source": "meta",
"UTM_Campaign": "bootcamp-mars-2026",
"UTM_Content": "ad-temoignage-tx1"
}]
}Zoho Books
Le client_key doit etre dans l'URL (Zoho Books ne l'envoie pas dans le payload). Les custom fields Zoho sont prefixes par cf_.
Voir le payload Zoho Books complet
{
"payment": {
"amount": 2500,
"payment_status": "paid",
"customer_name": "Jean Tremblay",
"customer_email": "jean.tremblay@email.com",
"invoices": [{ "invoice_number": "INV-001234", "amount_applied": 2500 }],
"custom_fields": [
{ "api_name": "cf_client_key", "value": "VOTRE_CLE" },
{ "api_name": "cf_product_key", "value": "bootcamp_ai" },
{ "api_name": "cf_source", "value": "DURUM" },
{ "api_name": "cf_referent", "value": "Marie Dupont" }
]
}
}Pipedrive
L'URL doit inclure ?client_key=VOTRE_CLE&source=pipedrive. Les emails et telephones sont des tableaux avec primary: true.
Voir le payload Pipedrive complet (deal gagne)
{
"meta": { "action": "updated", "object": "deal", "company_id": 12345 },
"current": {
"title": "Jean Tremblay - Bootcamp IA",
"status": "won",
"value": 2500,
"person_id": {
"name": "Jean Tremblay",
"email": [{ "value": "jean@email.com", "primary": true }],
"phone": [{ "value": "+15145551234", "primary": true }]
},
"user_id": { "name": "Marie Dupont" },
"won_time": "2026-03-30T15:00:00Z"
},
"previous": { "status": "open" }
}Tester votre webhook
Copiez-collez cette commande dans votre terminal pour envoyer un lead de test :
curl -X POST "https://app.durum.ai/api/webhook/lead?client_key=VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"email": "test-webhook@votredomaine.com",
"name": "Test Webhook",
"utm_source": "test",
"utm_campaign": "test-webhook",
"utm_content": "test-ad"
}'Puis verifiez dans DURUM.ai > Logs Data que l'evenement apparait.
Depannage rapide
| Symptome | Cause | Solution |
|---|---|---|
| Evenement absent de l'app | client_key manquant ou invalide | Ajoutez ?client_key=VOTRE_CLE a l'URL |
Statut quarantined | Formulaire ou client non reconnu | Normal pour un nouveau formulaire. L'agence le categorise. |
Reponse deduped: true | Evenement deja recu | Normal. Le doublon a ete detecte. |
| UTMs vides dans le dashboard | Pas d'UTMs dans le webhook | Configurez les hidden fields (Typeform), custom fields (GHL) ou tracking (Calendly) |
| Montant a $0 sur une vente | Champ amount absent | Ajoutez le montant dans le payload |
| Reponse 401 | Authentification echouee | Pour GHL : ajoutez &source=ghl. Pour Stripe : verifiez la signature. |
| Reponse 429 | Trop de requetes | Maximum 60 par minute par IP |
| Reponse 202 | Serveur temporairement occupe | L'evenement est en file d'attente et sera traite sous quelques minutes |