En résumé : Ce guide vous montre comment connecter Rodz a HubSpot pour synchroniser automatiquement vos signaux d’affaires dans votre CRM. Vous apprendrez a configurer un webhook Rodz, a créer un middleware (ou un scénario Make) pour transformer les données, puis a créer ou mettre a jour des contacts, entreprises et deals dans HubSpot via son API. Résultat : vos commerciaux disposent des signaux directement dans leur CRM, sans saisie manuelle — et Rodz peut lire l’historique HubSpot pour personnaliser chaque message à l’échelle.
Pourquoi connecter Rodz a HubSpot ?
Les signaux d’affaires détectés par Rodz (levées de fonds, recrutements, déménagements, changements de dirigeant) sont des informations précieuses pour vos équipes commerciales. Mais leur valeur diminue si elles restent isolées dans un outil séparé. Le véritable levier, c’est de les injecter dans le CRM que vos commerciaux utilisent au quotidien.
En connectant Rodz a HubSpot, vous obtenez quatre bénéfices concrets. Premièrement, vous centralisez l’intelligence commerciale. Chaque signal enrichit automatiquement la fiche entreprise ou contact correspondante dans HubSpot. Vos commerciaux n’ont plus besoin de basculer entre deux interfaces. Deuxièmement, vous pouvez déclencher des workflows automatisés. Un signal de levée de fonds peut automatiquement créer une tâche de rappel, assigner un commercial ou démarrer une séquence d’emails. Troisièmement, vous enrichissez votre CRM avec des données fraîches et contextuelles que HubSpot seul ne peut pas fournir. Quatrièmement — et c’est le bénéfice le moins visible mais souvent le plus puissant — la connexion est bidirectionnelle : Rodz peut lire l’activité passée enregistrée dans HubSpot pour générer des messages hyper-personnalisés, comme si votre commercial connaissait parfaitement le prospect depuis des mois.
L’intégration repose sur une architecture simple : Rodz envoie un webhook a chaque nouveau signal, un middleware transforme et route les données, puis l’API HubSpot crée ou met a jour les enregistrements. Ce guide couvre chaque étape en détail.
Pour comprendre comment Rodz détecte et structure ses signaux, consultez le guide des signaux RH et recrutement ou l’article sur les workflows commerciaux dans le CRM.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
- Un compte Rodz actif avec accès API. Vous aurez besoin de votre clé API pour configurer les webhooks. Consultez la documentation de l’API Rodz si vous ne l’avez pas encore.
- Un compte HubSpot avec accès API. Un compte HubSpot Pro ou Enterprise est recommandé pour bénéficier des propriétés personnalisées et des workflows. Générez une clé d’accès privée (Private App) depuis les paramètres de votre portail.
- Au moins un signal Rodz configuré. L’intégration n’a de sens que si vous recevez des signaux. Suivez le guide de configuration des webhooks Rodz pour les activer.
- Un middleware pour recevoir et transformer les données. Vous avez deux options : un endpoint custom (Node.js, Python, etc.) ou un outil no-code comme Make. Ce guide couvre les deux approches.
- Des connaissances de base en HTTP et JSON. Vous devez comprendre les requêtes POST, les headers d’authentification et les corps JSON.
- Un outil de test HTTP. cURL, Postman ou Insomnia pour tester vos appels API.
Architecture de l’intégration
L’intégration suit un flux en trois étapes :
Rodz (webhook) → Middleware (transformation) → HubSpot (API)
Rodz envoie un payload JSON a chaque nouveau signal. Ce payload contient les données de l’entreprise, du contact associé et les métadonnées du signal (montant de la levée, poste recruté, etc.). Le middleware reçoit ce payload, le transforme pour correspondre au format attendu par HubSpot, puis appelle l’API HubSpot pour créer ou mettre a jour les enregistrements.
Pourquoi un middleware ? Parce que les formats de données de Rodz et de HubSpot sont différents. Les noms de propriétés ne correspondent pas, la structure des objets est différente, et certaines logiques métier (déduplication, enrichissement complémentaire, routage par équipe) doivent être appliquées avant l’écriture dans le CRM.
Pour une référence complète des endpoints et des formats de l’API Rodz, consultez la documentation de référence.
Les deux scénarios de synchronisation : enrichissement vs création
Avant de plonger dans l’implémentation technique, il est essentiel de comprendre que l’intégration Rodz–HubSpot couvre deux cas d’usage bien distincts. Les traiter de la même façon est l’erreur la plus courante, et la plus coûteuse en termes de qualité de données.
Scénario 1 : Enrichissement d’un enregistrement existant
Un signal Rodz est détecté sur une entreprise déja présente dans votre CRM. Vous avez peut-être déja eu des échanges avec ce prospect, ou il est client depuis plusieurs mois. Dans ce cas, l’objectif n’est pas de créer un nouvel enregistrement, mais d’enrichir l’existant avec les données fraîches du signal.
Ce scénario est le plus sensible : si vous créez un doublon ou déclenchez une séquence de prospection automatique sur un client actif, vous dégradez l’expérience et la relation commerciale. La règle est simple, enrichir, ne jamais écraser, et vérifier les exclusions avant toute action.
Concrètement, votre middleware doit :
- Identifier l’enregistrement existant dans HubSpot (par domaine pour les entreprises, par email pour les contacts).
- Mettre a jour uniquement les propriétés liées au signal (
rodz_last_signal_type,rodz_last_signal_date, etc.) sans toucher aux données saisies manuellement par vos commerciaux. - Créer un événement timeline pour tracer le signal dans l’historique.
- Vérifier les exclusions (deals actifs, statut client, listes de suppression) avant de déclencher la moindre action automatisée.
Scénario 2 : Création d’un nouvel enregistrement
Un signal Rodz est détecté sur une entreprise absente de votre CRM. Rodz vous révèle un compte que vous n’aviez pas encore identifié, une levée de fonds d’une scale-up que vous ne suiviez pas, un recrutement massif dans un secteur cible, un déménagement vers une zone géographique clé. C’est une opportunité nette.
Dans ce cas, votre middleware doit créer l’entreprise, le contact associé, les lier entre eux, et potentiellement initier un workflow de prospection. Mais même ici, une vérification de déduplication préalable est obligatoire : l’absence de l’entreprise dans HubSpot ne signifie pas qu’elle est inconnue de vos équipes. Elle peut exister sous un domaine légèrement différent, avec une variation de nom, ou dans une instance HubSpot distincte.
Arbre de décision
Signal Rodz reçu
│
├── Vérification déduplication (domaine + SIREN)
│ │
│ ├── Enregistrement trouvé dans HubSpot
│ │ ├── Mettre à jour les propriétés signal
│ │ ├── Créer un événement timeline
│ │ └── Vérifier exclusions → déclencher actions (ou non)
│ │
│ └── Aucun enregistrement trouvé
│ ├── Créer l'entreprise
│ ├── Créer le contact et l'associer
│ ├── Créer un événement timeline
│ └── Déclencher workflow de prospection
Ce double flux doit être implémenté explicitement dans votre middleware ou votre scénario Make. Les étapes suivantes détaillent chaque branche.
Étape 0 : La déduplication comme prérequis absolu
Aucune écriture dans HubSpot ne doit se faire sans vérification de déduplication préalable. C’est la règle fondamentale de cette intégration. Créer des doublons dans un CRM est l’un des problèmes les plus difficiles a résoudre a posteriori, et HubSpot n’est pas natif sur ce point.
La déduplication dans ce contexte s’opère sur deux niveaux :
Déduplication entreprise
Utilisez le domaine web comme identifiant principal. C’est la propriété la plus fiable et la plus stable. En complément, le SIREN (pour les entreprises françaises) offre une précision maximale lorsqu’il est disponible dans HubSpot.
async function findExistingCompany(domain, siren) {
// 1. Chercher par domaine (priorité haute)
const byDomain = await hubspotSearch('companies', [{ propertyName: 'domain', operator: 'EQ', value: domain }]);
if (byDomain.total > 0) return byDomain.results[0];
// 2. Chercher par SIREN si le domaine ne donne rien
if (siren) {
const bySiren = await hubspotSearch('companies', [{ propertyName: 'rodz_siren', operator: 'EQ', value: siren }]);
if (bySiren.total > 0) return bySiren.results[0];
}
// 3. Aucun enregistrement trouvé → création autorisée
return null;
}
Si vous gérez un volume important de données et que la déduplication native de HubSpot vous pose des problèmes, l’outil Dedupe.ly est conçu spécifiquement pour nettoyer et prévenir les doublons dans HubSpot.
Déduplication contact
Utilisez l’adresse email comme identifiant principal. HubSpot l’utilise lui-même comme clé d’unicité native. Si l’email n’est pas disponible (ce qui arrive parfois avec les données LinkedIn), utilisez la combinaison prénom + nom + entreprise comme fallback, mais avec prudence.
async function findExistingContact(email, firstName, lastName, companyId) {
// 1. Chercher par email
if (email) {
const byEmail = await hubspotSearch('contacts', [{ propertyName: 'email', operator: 'EQ', value: email }]);
if (byEmail.total > 0) return byEmail.results[0];
}
// 2. Fallback : prénom + nom + association entreprise
const byName = await hubspotSearch('contacts', [
{ propertyName: 'firstname', operator: 'EQ', value: firstName },
{ propertyName: 'lastname', operator: 'EQ', value: lastName },
{ propertyName: 'associatedcompanyid', operator: 'EQ', value: companyId },
]);
if (byName.total > 0) return byName.results[0];
return null;
}
Intégrer la déduplication dans le flux principal
Voici la structure globale du middleware avec la déduplication comme première étape :
app.post('/rodz-to-hubspot', async (req, res) => {
if (!verifySignature(req, process.env.RODZ_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Signature invalide' });
}
const signal = req.body;
try {
// ÉTAPE 0 : Déduplication obligatoire avant toute écriture
const existingCompany = await findExistingCompany(signal.company.domain, signal.company.siren);
let company;
let isNewRecord = false;
if (existingCompany) {
// SCÉNARIO 1 : Enrichissement d'un enregistrement existant
company = await enrichHubSpotCompany(existingCompany.id, signal);
} else {
// SCÉNARIO 2 : Création d'un nouvel enregistrement
company = await createHubSpotCompany(signal.company, signal);
isNewRecord = true;
}
// Même logique pour le contact
const existingContact = await findExistingContact(
signal.contact.email,
signal.contact.first_name,
signal.contact.last_name,
company.id,
);
let contact;
if (existingContact) {
contact = await enrichHubSpotContact(existingContact.id, signal.contact);
} else {
contact = await createHubSpotContact(signal.contact, company.id);
}
// Tracer le signal dans la timeline (toujours)
await createTimelineEvent(signal, company.id);
// Actions automatisées uniquement si conditions remplies
const shouldExclude = await shouldExcludeContact(contact.id);
if (!shouldExclude) {
if (isNewRecord) {
// Déclencher workflow de prospection pour nouveau compte
await triggerProspectionWorkflow(signal, company.id, contact.id);
} else {
// Notifier le commercial en charge du compte existant
await notifyAccountOwner(signal, company.id, contact.id);
}
}
res.status(200).json({ received: true, scenario: isNewRecord ? 'creation' : 'enrichment' });
} catch (error) {
console.error('Erreur HubSpot:', error.message);
res.status(500).json({ error: 'Erreur de traitement' });
}
});
Ce flux garantit que chaque signal est traité selon le bon scénario, sans risque de doublon ni d’action automatisée intempestive sur un compte existant.
Étape 1 : Configurer le webhook Rodz
La première étape consiste a créer un webhook dans Rodz pour recevoir les signaux en temps réel. Si vous avez déja suivi le guide de configuration des webhooks, vous pouvez passer a l’étape suivante.
Enregistrez votre webhook via l’API Rodz :
curl -X POST https://api.rodz.io/webhooks \
-H "Authorization: Bearer VOTRE_CLE_API_RODZ" \
-H "Content-Type: application/json" \
-d '{
"url": "https://votre-middleware.com/rodz-to-hubspot",
"events": ["signal.new", "signal.updated"],
"secret": "votre_secret_hmac_256"
}'
L’URL pointe vers votre middleware (votre serveur custom ou votre endpoint Make). Le paramètre events filtre les types d’événements que vous souhaitez recevoir. Pour une intégration CRM, signal.new et signal.updated couvrent la majorité des cas.
Le paramètre secret est facultatif mais fortement recommandé. Il vous permet de vérifier la signature HMAC-SHA256 de chaque requête entrante pour garantir qu’elle provient bien de Rodz.
Payload reçu
Chaque notification contient un payload structuré. Voici un exemple pour un signal de type “levée de fonds” :
{
"event_id": "evt_20260310_xyz789",
"event_type": "signal.new",
"signal_type": "fundraising",
"timestamp": "2026-03-10T09:15:00Z",
"company": {
"id": "comp_123abc",
"name": "DataFlow SAS",
"domain": "dataflow.io",
"siren": "987654321",
"industry": "SaaS",
"size": "50-200",
"location": {
"city": "Lyon",
"country": "FR"
}
},
"contact": {
"id": "cont_456def",
"first_name": "Julien",
"last_name": "Martin",
"title": "CEO",
"email": "julien.martin@dataflow.io",
"linkedin_url": "https://linkedin.com/in/julienmartin"
},
"metadata": {
"amount": 8000000,
"currency": "EUR",
"round": "Series A",
"investors": ["VC Capital", "Growth Partners"],
"source_url": "https://example.com/dataflow-levee"
}
}
C’est ce payload que votre middleware va transformer avant de l’envoyer a HubSpot.
Étape 2 : Créer le middleware de transformation
Vous avez deux options pour le middleware : un endpoint custom ou un scénario Make. Commençons par l’approche custom.
Option A : Middleware custom (Node.js)
Créez un serveur Express.js qui reçoit le webhook Rodz, transforme les données et appelle l’API HubSpot :
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Vérification de la signature HMAC
function verifySignature(req, secret) {
const signature = req.headers['x-rodz-signature'];
const computed = crypto.createHmac('sha256', secret).update(JSON.stringify(req.body)).digest('hex');
return signature === computed;
}
app.post('/rodz-to-hubspot', async (req, res) => {
// 1. Vérifier la signature
if (!verifySignature(req, process.env.RODZ_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Signature invalide' });
}
const signal = req.body;
try {
// 2. Créer ou mettre a jour l'entreprise dans HubSpot
const company = await upsertHubSpotCompany(signal.company, signal);
// 3. Créer ou mettre a jour le contact
const contact = await upsertHubSpotContact(signal.contact, company.id);
// 4. Créer un événement timeline
await createTimelineEvent(signal, company.id);
res.status(200).json({ received: true });
} catch (error) {
console.error('Erreur HubSpot:', error.message);
res.status(500).json({ error: 'Erreur de traitement' });
}
});
app.listen(3000, () => {
console.log('Middleware Rodz-HubSpot actif sur le port 3000');
});
Ce squelette gère la vérification de signature, la création des enregistrements HubSpot et la gestion des erreurs. Les fonctions upsertHubSpotCompany, upsertHubSpotContact et createTimelineEvent sont détaillées dans les étapes suivantes.
Option B : Scénario Make (no-code)
Si vous préférez une approche sans code, Make est une excellente alternative. Voici le scénario a créer :
- Module Webhook (déclencheur). Créez un webhook custom dans Make. Copiez l’URL générée et utilisez-la comme URL de webhook dans Rodz.
- Module Router. Ajoutez un routeur pour gérer différents types de signaux (levée de fonds, recrutement, changement de poste) avec des traitements spécifiques.
- Module HTTP (recherche HubSpot, déduplication). Pour chaque branche, commencez obligatoirement par chercher si l’entreprise existe déja dans HubSpot via une requête GET sur
/crm/v3/objects/companies/search(par domaine, puis par SIREN). C’est le pré-requis absolu avant toute écriture. - Module Router (bifurcation enrichissement / création). Selon le résultat de la déduplication, orientez le flux vers la branche “Enrichissement” (PATCH sur l’enregistrement existant) ou la branche “Création” (POST sur un nouvel enregistrement).
- Module HTTP (contact). Répétez la logique déduplication/création ou enrichissement pour le contact, en l’associant a l’entreprise.
- Module HTTP (timeline event). Créez un événement timeline pour tracer le signal dans l’historique de l’entreprise.
- Module Router (actions post-traitement). Selon que l’enregistrement est nouveau ou existant, déclenchez des actions différentes : workflow de prospection pour les nouveaux comptes, notification au commercial en charge pour les comptes existants.
Ce scénario Make se déclenche a chaque réception de webhook Rodz et exécute toute la chaîne de transformation en quelques secondes. L’avantage : pas de serveur a maintenir, pas de code a déployer.
Étape 3 : Mapper les données Rodz vers HubSpot
Le mapping des champs est la clé d’une intégration réussie. Voici la correspondance entre les champs du payload Rodz et les propriétés HubSpot.
Mapping entreprise
| Champ Rodz | Propriété HubSpot | Notes |
|---|---|---|
company.name | name | Nom de l’entreprise |
company.domain | domain | Domaine web, utilisé comme clé de déduplication |
company.industry | industry | Secteur d’activité |
company.size | numberofemployees | Convertir la plage en nombre (ex. “50-200” → 125) |
company.location.city | city | Ville du siège |
company.location.country | country | Code pays ISO |
company.siren | rodz_siren (custom) | Propriété personnalisée a créer dans HubSpot |
signal_type | rodz_last_signal_type (custom) | Dernier type de signal détecté |
timestamp | rodz_last_signal_date (custom) | Date du dernier signal |
metadata.amount | rodz_fundraising_amount (custom) | Montant de la levée (si applicable) |
Mapping contact
| Champ Rodz | Propriété HubSpot | Notes |
|---|---|---|
contact.first_name | firstname | Prénom |
contact.last_name | lastname | Nom |
contact.email | email | Email, utilisé comme clé de déduplication |
contact.title | jobtitle | Intitulé de poste |
contact.linkedin_url | hs_linkedinid | URL LinkedIn |
Créer les propriétés personnalisées dans HubSpot
Avant de pouvoir écrire les données de signaux dans HubSpot, vous devez créer les propriétés personnalisées. Voici l’appel API pour créer la propriété rodz_last_signal_type sur l’objet Company :
curl -X POST https://api.hubapi.com/crm/v3/properties/companies \
-H "Authorization: Bearer VOTRE_TOKEN_HUBSPOT" \
-H "Content-Type: application/json" \
-d '{
"name": "rodz_last_signal_type",
"label": "Dernier signal Rodz",
"type": "enumeration",
"fieldType": "select",
"groupName": "companyinformation",
"options": [
{ "label": "Levée de fonds", "value": "fundraising" },
{ "label": "Recrutement", "value": "hiring" },
{ "label": "Déménagement", "value": "relocation" },
{ "label": "Changement de dirigeant", "value": "leadership_change" },
{ "label": "Appel d offres", "value": "tender" }
]
}'
Répétez cette opération pour chaque propriété personnalisée : rodz_last_signal_date (type date), rodz_siren (type string), rodz_fundraising_amount (type number).
Étape 4 : Créer et mettre a jour les enregistrements HubSpot
Rechercher une entreprise existante
Avant de créer une entreprise, vérifiez si elle existe déja dans HubSpot en cherchant par domaine :
curl -X POST https://api.hubapi.com/crm/v3/objects/companies/search \
-H "Authorization: Bearer VOTRE_TOKEN_HUBSPOT" \
-H "Content-Type: application/json" \
-d '{
"filterGroups": [{
"filters": [{
"propertyName": "domain",
"operator": "EQ",
"value": "dataflow.io"
}]
}],
"properties": ["name", "domain", "rodz_last_signal_type"]
}'
Enrichir un enregistrement existant (Scénario 1)
Si la recherche retourne un résultat, vous êtes dans le scénario d’enrichissement. Mettez a jour uniquement les propriétés liées au signal. Ne touchez pas aux champs renseignés manuellement par vos commerciaux :
curl -X PATCH https://api.hubapi.com/crm/v3/objects/companies/COMPANY_ID \
-H "Authorization: Bearer VOTRE_TOKEN_HUBSPOT" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"rodz_last_signal_type": "fundraising",
"rodz_last_signal_date": "2026-03-10",
"rodz_fundraising_amount": "8000000"
}
}'
La règle d’or : lors d’un enrichissement, limitez l’écriture aux propriétés préfixées rodz_. Les propriétés natives HubSpot (name, city, industry) peuvent avoir été corrigées manuellement par vos équipes, les écraser serait destructeur.
Créer un nouvel enregistrement (Scénario 2)
Si la recherche ne retourne aucun résultat, vous êtes dans le scénario de création. Créez l’entreprise avec l’ensemble des données disponibles :
curl -X POST https://api.hubapi.com/crm/v3/objects/companies \
-H "Authorization: Bearer VOTRE_TOKEN_HUBSPOT" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"name": "DataFlow SAS",
"domain": "dataflow.io",
"industry": "SaaS",
"numberofemployees": "125",
"city": "Lyon",
"country": "FR",
"rodz_siren": "987654321",
"rodz_last_signal_type": "fundraising",
"rodz_last_signal_date": "2026-03-10",
"rodz_fundraising_amount": "8000000"
}
}'
Créer ou mettre a jour un contact
La logique est identique pour les contacts. Cherchez par email, puis enrichissez ou créez :
curl -X POST https://api.hubapi.com/crm/v3/objects/contacts/search \
-H "Authorization: Bearer VOTRE_TOKEN_HUBSPOT" \
-H "Content-Type: application/json" \
-d '{
"filterGroups": [{
"filters": [{
"propertyName": "email",
"operator": "EQ",
"value": "julien.martin@dataflow.io"
}]
}]
}'
Si le contact n’existe pas (Scénario 2) :
curl -X POST https://api.hubapi.com/crm/v3/objects/contacts \
-H "Authorization: Bearer VOTRE