Obtenir des leads depuis votre site web
Instructions pour intégrer le formulaire de votre site web avec ReactiveCRM : capture des soumissions de formulaire comme leads, envoi d'événements d'attribution marketing et vérification du résultat.
1. Aperçu
Le flux recommandé consiste en deux requêtes :
- Le site envoie les données du formulaire à son propre backend.
- Le backend du site crée un lead dans le CRM via
POST /api/leads/create. - Après la création réussie, le backend envoie un événement marketing
lead_submittedviaPOST /api/dashboard/marketing/events, en passant leleadIdreçu. - Le CRM stocke les balises UTM, les identifiants publicitaires et le référent pour l'attribution marketing.
Formulaire du site web
|
v
Backend du site / proxy côté serveur
| POST /api/leads/create
v
ReactiveCRM -> leadId
| POST /api/dashboard/marketing/events
v
Attribution marketing et tableau de bord
N'envoyez pas le JWT CRM et les secrets directement depuis le navigateur. Utilisez le backend du site ou une fonction serverless pour que le token CRM et les identifiants de service ne soient jamais exposés au visiteur.
2. Authentification et URL de base
Toutes les requêtes s'exécutent dans le contexte du locataire concerné et nécessitent une autorisation CRM :
Authorization: Bearer <CRM_ACCESS_TOKEN>
Content-Type: application/json
Les exemples utilisent :
CRM_BASE_URL=https://crm.example.com
Remplacez-le par l'URL de votre environnement.
3. Données à collecter sur le site
Données du lead
Pour créer un lead, l'API prend en charge :
| Champ | Requis | Description |
|---|---|---|
message | non | Message ou texte de la demande du formulaire |
ownerId | oui | UUID de l'utilisateur CRM responsable du lead |
authorId | oui | UUID de l'utilisateur CRM qui a créé le lead |
clientId | non | UUID d'un client existant |
contactId | non | UUID d'un contact existant |
leadSourceId | non | UUID d'un nœud dans l'arbre des sources de leads |
statusId | non | UUID du statut initial |
quality | non | HOT, WARM, COOL ou COLD |
ownerId et authorId sont des UUID d'utilisateurs CRM. Pour un formulaire public sur le site web, ne laissez pas le visiteur définir ces valeurs lui-même : le backend doit les fournir à partir de la configuration d'intégration.
Données de la visite marketing
Avant que le formulaire ne soit soumis, stockez les éléments suivants dans les cookies, le stockage de session ou sur le backend :
utm_source→utmSourceutm_medium→utmMediumutm_campaign→utmCampaignutm_content→utmContentutm_term→utmTermgclid— identifiant Google Adsfbclid— identifiant Meta/Facebook- URL de la page de destination →
landingUrl - URL de la page précédente →
referrer - Vos propres identifiants de visiteur et de session →
visitorId,sessionId
Enregistrez les valeurs lors de la première visite et ne les remplacez pas par des paramètres vides lors de la navigation sur le site.
4. Création d'un lead
Endpoint
POST /api/leads/create
Exemple de requête
curl -X POST "$CRM_BASE_URL/api/leads/create" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Demande site web : demande de consultation",
"ownerId": "11111111-1111-1111-1111-111111111111",
"authorId": "11111111-1111-1111-1111-111111111111",
"quality": "WARM"
}'
Exemple de réponse 201 Created
{
"id": "22222222-2222-2222-2222-222222222222",
"message": "Demande site web : demande de consultation",
"quality": "WARM",
"dealId": null,
"createdAt": "2026-09-05T20:00:00Z",
"updatedAt": "2026-09-05T20:00:00Z",
"version": 0,
"author": {
"id": "11111111-1111-1111-1111-111111111111",
"firstName": "CRM",
"lastName": "Bot"
},
"owner": {
"id": "11111111-1111-1111-1111-111111111111",
"firstName": "CRM",
"lastName": "Bot"
}
}
Enregistrez le id de la réponse : cette valeur est passée dans le champ leadId de l'événement marketing.
5. Envoi de l'événement de lead soumis
Endpoint
POST /api/dashboard/marketing/events
Exemple de requête
curl -X POST "$CRM_BASE_URL/api/dashboard/marketing/events" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"eventType": "lead_submitted",
"occurredAt": "2026-09-05T20:00:00Z",
"visitorId": "visitor-8b7f",
"sessionId": "session-31ac",
"leadId": "22222222-2222-2222-2222-222222222222",
"externalId": "site-form-submit-20260905-000123",
"source": "website",
"channel": "paid",
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "summer-consulting",
"utmContent": "banner-a",
"utmTerm": "crm consultation",
"gclid": "EAIaIQobChMI-example",
"landingUrl": "https://www.example.com/consultation",
"referrer": "https://www.google.com/",
"metadata": {
"formName": "consultation",
"pageType": "landing"
}
}'
Exemple de réponse
{
"accepted": true,
"duplicate": false,
"eventId": "33333333-3333-3333-3333-333333333333"
}
Si le même externalId a déjà été traité pour cette paire source et locataire, l'API renvoie une réponse de succès avec duplicate: true. Considérez cela comme un succès, pas comme une erreur, et ne créez pas de second lead.
6. Exemple de gestionnaire côté serveur
Voici un exemple simplifié en Node.js. Les données du formulaire doivent aller au backend du site, pas directement au CRM depuis le navigateur.
async function createWebsiteLead(form, attribution) {
const headers = {
Authorization: `Bearer ${process.env.CRM_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
};
const leadResponse = await fetch(
`${process.env.CRM_BASE_URL}/api/leads/create`,
{
method: 'POST',
headers,
body: JSON.stringify({
message: form.message || `Demande site web : ${form.subject || 'sans sujet'}`,
ownerId: process.env.CRM_LEAD_OWNER_ID,
authorId: process.env.CRM_LEAD_AUTHOR_ID,
quality: 'WARM',
}),
},
);
if (!leadResponse.ok) {
throw new Error(`La création du lead CRM a échoué : ${leadResponse.status}`);
}
const lead = await leadResponse.json();
const externalId = `website-${form.requestId}`;
const eventResponse = await fetch(
`${process.env.CRM_BASE_URL}/api/dashboard/marketing/events`,
{
method: 'POST',
headers,
body: JSON.stringify({
eventType: 'lead_submitted',
occurredAt: new Date().toISOString(),
visitorId: attribution.visitorId,
sessionId: attribution.sessionId,
leadId: lead.id,
externalId,
source: 'website',
channel: attribution.channel || 'direct',
utmSource: attribution.utmSource,
utmMedium: attribution.utmMedium,
utmCampaign: attribution.utmCampaign,
utmContent: attribution.utmContent,
utmTerm: attribution.utmTerm,
gclid: attribution.gclid,
fbclid: attribution.fbclid,
landingUrl: attribution.landingUrl,
referrer: attribution.referrer,
metadata: { formName: form.formName || 'website' },
}),
},
);
if (!eventResponse.ok) {
// Le lead est déjà créé. Mettez l'événement en file d'attente et réessayez
// avec le même externalId au lieu de créer un second lead.
throw new Error(`L'événement marketing CRM a échoué : ${eventResponse.status}`);
}
return { leadId: lead.id, marketingEvent: await eventResponse.json() };
}
7. Idempotence et nouvelles tentatives
- Générez un
externalIdstable pour chaque soumission de formulaire. Par exemple, utilisez un UUID créé avant la première requête, ou unrequestIdunique du formulaire. - En cas d'erreur réseau, réessayez la requête d'événement marketing avec le même
externalId. - Ne générez pas de nouveau
externalIdlors d'une nouvelle tentative : cela créerait un événement en double. - Si la requête de création de lead se termine par un résultat inconnu en raison d'un délai d'attente, ne créez pas aveuglément un nouveau lead. Utilisez d'abord votre propre
requestIdet un mécanisme de déduplication sur le backend du site, ou trouvez le lead créé dans le CRM. - Une erreur d'envoi d'événement ne doit pas amener l'utilisateur à renvoyer le formulaire sans vérifier le résultat de la création du lead.
8. Données personnelles et metadata
Il est interdit de transmettre des données personnelles et le contenu du formulaire dans metadata :
- téléphone
- prénom et nom
- adresse
- texte du message
- cookies contenant des identifiants avec des données personnelles
Les données personnelles doivent être transmises uniquement dans les entités CRM prévues à cet effet — par exemple, dans un contactId/clientId pré-créé. Conservez uniquement des attributs techniques dans metadata : nom du formulaire, type de page, variante de bannière, etc.
9. Réponses et erreurs typiques
| HTTP | Situation | Que faire |
|---|---|---|
201 | Lead créé | Enregistrez le id et envoyez lead_submitted |
200 + duplicate: false | Événement accepté | Enregistrez le eventId dans le journal d'intégration |
200 + duplicate: true | L'événement a déjà été accepté | Considérez comme traité ; ne renvoyez pas |
400 | Données invalides ou PII dans metadata | Corrigez la charge utile ; réessayer sans changements n'aidera pas |
401 | Token invalide ou manquant | Rafraîchissez le token CRM sur le backend |
403 | Le token n'a pas la permission pour l'opération | Vérifiez le rôle et le locataire |
5xx / timeout | Erreur CRM ou réseau transitoire | Réessayez avec le même externalId ; pour les leads, utilisez une file d'attente |
10. Vérification des résultats dans le CRM
Après l'intégration, vérifiez :
- Le lead apparaît via
GET /api/leads/{id}ou dans la listeGET /api/leads/paged. - Le propriétaire, l'auteur et la date de création du lead sont corrects.
- La réponse de l'événement marketing a
duplicateégal àfalselors du premier envoi. - Le renvoi de la même soumission retourne
duplicate: true. - Dans le tableau de bord marketing, les données apparaissent dans la bonne période, le bon canal et la bonne campagne.
Récupération du lead créé
curl "$CRM_BASE_URL/api/leads/$LEAD_ID" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
Récupération des leads pour une liste ou une réconciliation
curl "$CRM_BASE_URL/api/leads/paged?page=0&size=20&createdAtFrom=2026-09-05T00:00:00Z&createdAtTo=2026-09-05T23:59:59Z&sort=createdAt,desc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
Le paramètre page commence à 0 ; le size par défaut est 20. Pour récupérer les leads du site web, utilisez également les filtres message, createdAtFrom/createdAtTo, contactEmail ou search si les données pertinentes sont déjà stockées dans le CRM.
Reactive CRM