Capturia mesure ses publicités et la fréquentation du site avec le pixel Meta et Google Analytics. Tu peux refuser en tout temps. En savoir plus

EN
GoHighLevelGuide d'intégration

GoHighLevel

Envoie à Capturia les leads d'un formulaire, d'une opportunité ou d'un rendez-vous GoHighLevel par l'action Webhook d'un workflow, pas à pas.

Configuration

Crée un workflow GHL avec un trigger (Form Submitted, Contact Created, Calendar Booked) et l'action Webhook native.

Créer un workflow GHL

Dans GoHighLevel, va dans Automation > Workflows et clique Create Workflow. Choisis le trigger (Form Submitted, Contact Created, Calendar Booked — selon ce qui doit pousser le lead vers Capturia).

Ajouter l'action Webhook

Comme action, choisis Webhook. C'est l'action native qui permet d'appeler une URL externe avec un payload custom. Ne pas confondre avec Custom Webhook, une action premium de HighLevel : l'action Webhook suffit ici.

Configurer URL et méthode

URL : https://api.capturia.io/v1/leads/capture

Method : POST

Encoding : JSON (option en haut du modal)

Custom Headers : ajoute une ligne Authorization avec valeur Bearer cap_live_xxxxxxxx.

Construire le payload

Dans Custom Data, ajoute des paires clé/valeur (GHL sérialise en JSON automatiquement quand Encoding=JSON). Utilise les Custom Values GHL ({{contact.phone}}, {{contact.first_name}}, etc.) pour les valeurs.

Exemple :

  • phone → {{contact.phone}}
  • first_name → {{contact.first_name}}
  • last_name → {{contact.last_name}}
  • email → {{contact.email}}
  • sms_consent → true (valeur fixe — voir l'étape 5)
  • source_label → ghl_workflow
  • pipeline.pipeline_slug → l'identifiant du pipeline visé, copié dans Capturia (optionnel)
  • pipeline.stage_slug → l'identifiant de l'étape visée, copié au même endroit (optionnel ; sans pipeline.pipeline_slug, l'étape est cherchée dans ton pipeline par défaut)

Capturer le consentement SMS

Recommandé : crée un Custom Field GHL de type "Checkbox" intitulé SMS Consent, ajoute-le au formulaire de capture, puis ajoute une condition If/Else dans le workflow (« SMS Consent is checked »). Dans la branche cochée seulement, place l'action Webhook avec sms_consent → true (valeur fixe).

Si le client a déjà un Custom Field différent (ex. Marketing Opt-in), utiliser celui-ci dans la condition. Hardcoder sms_consent: true sans condition n'est acceptable que si le formulaire en amont a une attestation explicite documentée.

Tester et publier

Sélectionne d'abord un contact de test portant ton propre cellulaire et un courriel de test, puis clique Test Webhook dans le modal d'action : GHL envoie le payload à Capturia avec les valeurs de ce contact. Une réponse 200 = un vrai lead créé dans Capturia — il n'existe pas de mode d'essai : la fiche apparaît dans Prospects et l'agent SMS texte le numéro envoyé si le consentement est en ordre. Archive la fiche de test une fois la vérification faite, puis sauvegarde le workflow et bascule-le sur Publish.

Mapping des champs

Le mapping ci-dessous utilise les Custom Values GHL pour les valeurs dynamiques. Adapter selon les Custom Fields disponibles côté client.

Champ CapturiaObligatoireChamp sourceNotes
phoneOui{{contact.phone}}E.164 (+15145551234), NANP 10 ou 11 chiffres, ou formatés (514) 555-1234 / 514-555-1234. Les 10 chiffres sont auto-préfixés +1.
sms_consentOuitrue (valeur fixe, derrière la condition de l'étape 5)Boolean true OU string 'true' / 'yes' / 'oui' / 'vrai' / '1' / 'on' / 'checked' (insensible à la casse). Accepté à la racine du body ou dans l'objet customData (webhooks GoHighLevel).
first_nameNon{{contact.first_name}}Prénom du lead
last_nameNon{{contact.last_name}}Nom de famille
emailNon{{contact.email}}Email valide RFC 5322
source_labelNon"ghl_workflow"Étiquette libre (ex. 'webflow_form', 'fb_lead_ads')
utm.sourceNonton champ personnalisé, ou une valeur fixeObjet utm imbriqué, ou clé à plat utm.source
utm.mediumNonton champ personnalisé, ou une valeur fixeObjet utm imbriqué, ou clé à plat utm.medium
utm.campaignNonton champ personnalisé, ou une valeur fixeObjet utm imbriqué, ou clé à plat utm.campaign
tagsNon"tag1, tag2" (s'ajoutent aux étiquettes du contact que GHL envoie déjà)Tableau de strings, ou une chaîne à virgules
pipeline.pipeline_slugNonidentifiant copié dans Capturia (valeur fixe)Identifiant texte du pipeline cible (pas son UUID). À copier dans Capturia : Administration, Clés API, section « Identifiants de tes pipelines et étapes ». Sans lui, le pipeline par défaut est visé. Objet pipeline imbriqué, ou clé à plat.
pipeline.stage_slugNonidentifiant copié dans Capturia (valeur fixe)Identifiant texte de l'étape cible, à copier au même endroit. Sans lui, l'étape marquée « Étape par défaut » à côté des identifiants. Envoyé sans pipeline_slug, il est cherché dans ton pipeline par défaut. Objet pipeline imbriqué, ou clé à plat.

Consentement SMS — LCAP / Loi 25

Le champ sms_consent est obligatoire. La loi canadienne anti-pourriel (LCAP/CASL) et la Loi 25 québécoise exigent un consentement explicite avant tout SMS commercial. Capturia conserve une trace horodatée de cette attestation pour ta protection légale.

Pattern recommandé — consentement capturé à la source

Ajoute une question custom de consentement directement dans le formulaire source (FB Lead Form custom question, champ Typeform, case GHL form). Mappe ce champ vers sms_consent. Le consentement est explicite, daté, et lié au lead qui l'a donné.

Pattern alternatif — case sur la landing page

Si le formulaire source ne permet pas de question custom, ajoute une case à cocher de consentement sur la landing page qui précède la pub. Conserve une copie de la page (Wayback Machine, screenshot daté) en preuve.

Zone grise légale

Hardcoder sms_consent: true sans attestation réelle du lead = risque légal. En cas de plainte, Capturia peut être tenue de fournir la preuve du consentement. Sans preuve, la responsabilité revient à l'entreprise qui envoie le lead.

Tester pas à pas

Sélectionne d'abord un contact de test portant ton propre cellulaire et un courriel de test, puis clique Test Webhook dans le modal d'action : GHL envoie le payload à Capturia avec les valeurs de ce contact. Une réponse 200 = un vrai lead créé dans Capturia (aucun mode d'essai) : la fiche apparaît dans Prospects et l'agent SMS texte le numéro envoyé si le consentement est en ordre. Ne teste jamais avec la fiche d'un vrai client. Archive la fiche de test, puis sauvegarde le workflow et bascule-le sur Publish.

Catalogue d'erreurs

CodeErreurCauseCorrection
400invalid_payloadBody vide ou JSON mal formé (virgule en trop, guillemet manquant)Valider le JSON envoyé, puis renvoyer
401missing_api_keyHeader Authorization absent ou mal forméAjouter le header Authorization: Bearer cap_live_...
401invalid_api_keyClé révoquée, expirée ou mal copiéeVérifier la clé dans Capturia, en générer une nouvelle si nécessaire
403terms_acceptance_requiredConditions d'utilisation de l'API pas acceptées (ou nouvelle version à accepter)Le propriétaire du compte accepte les conditions dans Capturia, à la page Clés API
403insufficient_scopeLa clé n'a pas le scope leads:captureCréer une nouvelle clé avec le preset « Capture de leads »
415invalid_content_typeBody envoyé en formulaire (Form, x-www-form-urlencoded) au lieu de JSONRégler l'envoi en JSON (Payload Type = JSON, Encoding = JSON, Body content type = application/JSON)
422invalid_phoneTéléphone absent ou format non reconnuUtiliser E.164 (+15145551234) ou NANP 10 chiffres (5145551234)
422invalid_emailCourriel mal forméEnvoyer une adresse valide, ou ne pas envoyer le champ
422missing_consentsms_consent absent, false, ou valeur non reconnue — le champ est cherché à la racine du body ET dans l'objet customData (GHL)Mapper le champ de consentement vers sms_consent (true / yes / oui). Depuis GHL : valeur fixe true derrière une condition sur la checkbox de consentement
422invalid_payloadAutre champ refusé (texte trop long, date mal formée, valeur négative, etc.) — details nomme le champCorriger le champ nommé dans details, puis renvoyer
422pipeline_not_foundpipeline.pipeline_slug ne correspond à aucun pipeline du compteRecopier l'identifiant texte du pipeline depuis la page Clés API (ce n'est pas son UUID)
422stage_not_foundpipeline.stage_slug ne correspond à aucune étape du pipeline viséRecopier l'identifiant texte de l'étape depuis la page Clés API, sous le bon pipeline
429rate_limit_exceededQuota de requêtes de la clé dépasséEspacer les envois côté source (l'en-tête Retry-After donne le délai)
429rate_limited_ipPlus de 100 requêtes par minute depuis la même adresse IPRéduire le débit ou contacter le support

FAQ — pièges récurrents

SymptômeCause
Test plateforme vert (200 OK) mais le lead n'apparaît pas dans le pipelineLe même contact a déjà été envoyé dans les 5 dernières minutes — réponse status: idempotent_replay, aucun doublon (les tests réutilisent souvent le même numéro). Si la fiche existait déjà, elle garde sa colonne : voir l'entrée « pas dans le bon pipeline » plus bas.
415 « Unsupported Content-Type » ou 400 « Body is not valid JSON »415 : l'outil envoie un formulaire (Payload Type sur Form, Encoding form-encoded) au lieu de JSON. 400 : le JSON est mal formé, souvent une virgule en trop ou un guillemet manquant autour d'une variable.
Réponse 200 OK mais pas de SMS envoyé au leadsms_consent: true mais agent IA non configuré, ou agent IA SMS désactivé, ou pas de numéro Twilio provisionné côté client.
Réponse 200 OK mais le lead n'est pas dans le bon pipeline ou la bonne colonneLis ignored_fields dans la réponse : elle nomme chaque champ reçu qui n'a pas été pris. unknown_field : le champ porte un nom que l'API ne connaît pas (pipeline.id au lieu de pipeline.pipeline_slug, par exemple). existing_contact_kept : la fiche existait déjà, elle garde son pipeline et son étape. duplicate_field : le même champ est arrivé deux fois (racine et Custom Data, par exemple) et l'autre valeur a été retenue.
Lead créé sans tracking UTMChamp envoyé sous un nom que l'API ne connaît pas (utm_source). Envoie l'objet utm imbriqué ou la clé à plat utm.source ; ignored_fields nomme le champ qui n'a pas été pris.
403 terms_acceptance_required après une mise à jour qui marchait avantUne nouvelle version des conditions d'utilisation de l'API est à accepter : le propriétaire du compte l'accepte dans Capturia, à la page Clés API, et la clé refonctionne.
422 missing_consent alors que sms_consent est bien dans Custom DataGHL enveloppe Custom Data dans un objet customData, que Capturia déplie automatiquement (aucune configuration requise). Si l'erreur survient quand même, vérifier que la valeur envoyée est true (fixe), pas une interpolation {{contact...}} de checkbox.
422 missing_consent avec sms_consent → {{contact.ma_checkbox}}GHL interpole le libellé de l'option cochée (ex. « SMS Consent »), jamais true. Utiliser une condition If/Else sur la checkbox et envoyer la valeur fixe true dans la branche cochée (étape 5).
Le contact a un champ personnalisé « SMS Consent » — conflit avec le sms_consent du Custom Data ?Aucun. Le webhook GHL envoie de lui-même tous les champs personnalisés du contact sous leur nom d'affichage, en plus de tes paires Custom Data. Capturia donne préséance à ton sms_consent du Custom Data sur ces champs automatiques — c'est le montage exact prescrit à l'étape 5, aucun renommage de champ requis. Un champ standard du contact (courriel, prénom, téléphone) que tu remappes en Custom Data garde la valeur du contact ; si les deux diffèrent, la réponse nomme ta copie dans ignored_fields (duplicate_field).
Mon sous-compte est relié par le connecteur et j'envoie aussi ce webhook : le lead ne change pas de colonneAvec le connecteur, la fiche existe souvent déjà dans Capturia quand le webhook arrive. Une fiche existante garde son pipeline et son étape : le bloc pipeline du webhook n'est pas appliqué, et la réponse le nomme dans ignored_fields (existing_contact_kept). Le placement suit alors tes correspondances de pipeline du connecteur.