> For the complete documentation index, see [llms.txt](https://cmp.docs.sirdata.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cmp.docs.sirdata.net/faq/conditionnement/sirdata-extra-purposes/lier-le-consentement-au-contact-dans-hubspot.md).

# Lier le consentement au contact dans HubSpot

## Lier le consentement au contact dans HubSpot

Conditionner le pixel email à la **finalité Sirdata 7** garantit qu'il ne se déclenche que si l'utilisateur a consenti (voir la page Conditionnement par finalités Sirdata). Mais ce conditionnement vit côté navigateur / email : il ne laisse **aucune trace dans votre CRM**.

Cette page explique comment **propager** l'état du consentement à la **finalité 7** vers une **propriété personnalisée** de la fiche contact HubSpot. Objectif : pour chaque contact, savoir s'il a accepté le suivi d'ouverture des emails, **quand** et **sur quelle base**, directement dans HubSpot.

{% hint style="info" %}
**Pourquoi le faire ?** Le RGPD exige de pouvoir **démontrer** le consentement (article 7.1). Stocker l'état du consentement au niveau du contact donne une preuve horodatée, exploitable dans vos workflows email (n'envoyer le pixel qu'aux contacts consentants, par exemple).
{% endhint %}

***

#### 1. Vue d'ensemble du flux

1. L'utilisateur fait son choix dans la CMP Sirdata ; il **accepte** (ou non) la finalité Sirdata **7 — pixels de suivi d'ouverture et d'interaction des emails**.
2. Un **script conditionné** à cette finalité (via `data-cmp-extra-purposes="7"`) ne s'exécute que si le consentement est accordé.
3. Ce script transmet la valeur à HubSpot, qui l'écrit dans une **propriété personnalisée** du contact.
4. La fiche contact HubSpot reflète l'état du consentement, avec date et source.

{% hint style="warning" %}
Pour rattacher un consentement à **un contact**, il faut pouvoir **identifier** l'utilisateur (le plus souvent par son **email**). Tant que l'email n'est pas connu (visiteur anonyme), conservez l'information côté navigateur et synchronisez-la dès que le contact est identifié (soumission d'un formulaire, connexion…).
{% endhint %}

***

#### 2. Créer la propriété personnalisée dans HubSpot

Dans HubSpot : **Paramètres → Gestion des données → Propriétés → Créer une propriété**.

Renseignez :

* **Type d'objet** : `Contact`
* **Groupe** : un groupe dédié, p. ex. `Informations de conformité`
* **Libellé** : `Consentement pixel email (finalité Sirdata 7)`
* **Nom interne** : `consentement_pixel_email` *(c'est ce nom que vous utiliserez dans l'API)*
* **Type de champ** : `Choix unique (radio)` avec deux options, **valeurs internes `Oui` et `Non`**

{% hint style="danger" %}
**La valeur envoyée doit correspondre exactement au type de champ.**

* Champ **Choix unique / Liste déroulante** avec options `Oui`/`Non` → envoyez `"Oui"` (ou `"Non"`).
* Champ **Case à cocher unique** (booléen) → envoyez `"true"` (ou `"false"`).

Si vous envoyez `true` à un champ dont les options internes sont `Oui`/`Non`, **la valeur est rejetée** et la fiche n'est pas mise à jour. Les exemples de cette page utilisent un champ radio `Oui`/`Non`.
{% endhint %}

Pour une traçabilité complète, créez aussi quelques propriétés d'appui :

| Nom interne                       | Type de champ          | Rôle                                                        |
| --------------------------------- | ---------------------- | ----------------------------------------------------------- |
| `consentement_pixel_email`        | Choix unique (Oui/Non) | État du consentement.                                       |
| `consentement_pixel_email_date`   | Sélecteur de date      | Horodatage du recueil.                                      |
| `consentement_pixel_email_base`   | Liste déroulante       | Base légale (`Consentement` / `Intérêt légitime`).          |
| `consentement_pixel_email_source` | Texte sur une ligne    | Origine (`CMP Sirdata`, identifiant ou TC String tronquée). |

{% hint style="info" %}
Le **nom interne** est figé après création et insensible à la casse. Notez-le : c'est la clé attendue dans le `properties` / `fields` des appels API.
{% endhint %}

***

#### 3. Lire le consentement à la finalité 7 côté CMP

Le pixel lui-même reste conditionné par les attributs `data-cmp-*` (voir la page dédiée). Pour **déclencher l'écriture vers HubSpot uniquement lorsque la finalité 7 est consentie**, utilisez le conditionnement Sirdata avec `data-cmp-src` pointant vers une **fonction JavaScript** (et non une URL).

```markup
<script
  data-cmp-src="pushConsentToHubSpot"
  data-cmp-extra-vendor="6"
  data-cmp-extra-purposes="7">
</script>
```

* `data-cmp-extra-vendor` : l'ID du **partenaire Sirdata** responsable du pixel (votre extra-vendorlist).
* `data-cmp-extra-purposes="7"` : la fonction n'est appelée **que si** l'utilisateur a consenti à la finalité Sirdata 7.
* `data-cmp-src="pushConsentToHubSpot"` : nom de la fonction JS exécutée une fois la condition remplie.

***

#### 4. Écrire la valeur dans HubSpot

{% hint style="danger" %}
**N'utilisez pas `_hsq.push(["identify", …])` pour écrire cette propriété.** La méthode `identify` du code de suivi ne fixe de façon fiable que l'**email** : elle **ignore les propriétés custom** (comportement confirmé, la requête part bien, mais HubSpot n'écrit pas la propriété). Utilisez l'une des deux méthodes ci-dessous.
{% endhint %}

{% hint style="info" %}
**Quelle méthode choisir ?** L'**API CRM serveur** est la plus robuste : elle n'est pas soumise au filtre anti-spam des formulaires et fonctionne depuis n'importe quel domaine (y compris un domaine de test). La **Forms API** est pratique sans back-end, mais elle exige que le domaine émetteur soit **déclaré dans HubSpot** — ce qui est impossible pour un domaine mutualisé (voir section 5).
{% endhint %}

{% tabs %}
{% tab title="Forms API (navigateur) — sans back-end" %}
On soumet à un **formulaire HubSpot** contenant le champ `consentement_pixel_email` via l'**API de soumission de formulaire**. Elle est publique (pas de jeton exposé), écrit les propriétés custom et rattache le cookie de suivi au contact.

Prérequis : créer un formulaire HubSpot avec les champs `email` et `consentement_pixel_email`, puis récupérer son **portalId** et son **formGuid**.

```javascript
async function pushConsentToHubSpot() {
  var email = getCurrentUserEmail();       // l'email connu du contact
  if (!email) return;                      // pas d'identité : on diffère

  var portalId = "VOTRE_PORTAL_ID";
  var formGuid = "VOTRE_FORM_GUID";
  var hutk = (document.cookie.match(/hubspotutk=([^;]+)/) || [])[1];

  await fetch(
    "https://api.hsforms.com/submissions/v3/integration/submit/" + portalId + "/" + formGuid,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        fields: [
          { name: "email", value: email },
          { name: "consentement_pixel_email", value: "Oui" }
        ],
        context: {
          pageUri: location.href,
          pageName: document.title,
          ...(hutk ? { hutk } : {})   // rattache la soumission au contact suivi
        }
      })
    }
  );
}
```

{% hint style="warning" %}
**Le domaine émetteur doit être déclaré dans HubSpot** (voir section 5), sinon les soumissions sont bloquées comme spam et la fiche n'est pas mise à jour.
{% endhint %}
{% endtab %}

{% tab title="API CRM v3 (serveur) — recommandé" %}
La fonction côté navigateur transmet l'email et l'état du consentement à **votre back-end**, qui appelle l'API HubSpot avec un **jeton d'application privée** (jamais exposé au client). Cette voie n'est **pas** soumise au filtre anti-spam des formulaires.

```javascript
// Navigateur : on relaie vers notre propre endpoint
function pushConsentToHubSpot() {
  var email = getCurrentUserEmail();
  if (!email) return;
  fetch("/api/consent/email-pixel", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email: email, consent: true })
  });
}
```

```bash
# Serveur : upsert du contact par email (PATCH idempotent)
curl --request PATCH \
  --url 'https://api.hubapi.com/crm/v3/objects/contacts/camille.martin@exemple.com?idProperty=email' \
  --header 'Authorization: Bearer VOTRE_JETON_PRIVE' \
  --header 'Content-Type: application/json' \
  --data '{
    "properties": {
      "consentement_pixel_email": "Oui",
      "consentement_pixel_email_date": "2026-07-01",
      "consentement_pixel_email_base": "Consentement",
      "consentement_pixel_email_source": "CMP Sirdata"
    }
  }'
```

{% hint style="info" %}
`idProperty=email` identifie le contact par son email plutôt que par son Record ID. Le contact doit déjà exister ; sinon utilisez `POST /crm/v3/objects/contacts/batch/upsert`. Le scope requis du jeton est `crm.objects.contacts.write`.
{% endhint %}
{% endtab %}
{% endtabs %}

***

#### 5. Déclarer le domaine émetteur (méthode Forms API uniquement)

Par défaut, HubSpot **bloque comme spam** les soumissions Forms API provenant d'un domaine qu'il ne reconnaît pas — motif *« Domaine de site non enregistré »*. La fiche contact n'est alors **pas** mise à jour.

Pour l'éviter, déclarez votre domaine dans **Paramètres → Suivi et analyse → Suivi avancé → Domaines de sites supplémentaires → Ajouter un domaine**.

{% hint style="danger" %}
**Un domaine mutualisé ne peut pas être déclaré.** Les hôtes en *suffixe public* (par ex. `mon-site.netlify.app`, `*.github.io`, `*.vercel.app`) sont **refusés silencieusement** par HubSpot : ils semblent ajoutés puis disparaissent après rechargement. Vous ne pouvez déclarer qu'un **domaine que vous possédez** (ex. `www.tonsite.com`). Sur un domaine de test mutualisé, la Forms API restera donc en spam → utilisez plutôt l'**API CRM serveur**.
{% endhint %}

{% hint style="info" %}
Les soumissions déjà bloquées se retrouvent dans **Formulaires → (votre formulaire) → Soumissions de spam** ; pour un test ponctuel vous pouvez les valider manuellement via **Retrait du filtre antispam** — elles créent alors les fiches et déclenchent les automatisations.
{% endhint %}

Cette étape ne concerne **pas** la méthode API CRM serveur, qui n'est pas filtrée et reste la voie recommandée en production comme en test.

***

#### 6. Vérifier le résultat sur la fiche contact

Après synchronisation, la propriété apparaît dans le groupe **Informations clés / de conformité** de la fiche contact.

Vous pouvez ensuite exploiter cette propriété pour :

* **Segmenter** une liste active des contacts ayant consenti au suivi email ;
* **Conditionner un workflow** d'envoi (n'inclure le pixel que pour `consentement_pixel_email = Oui`) ;
* **Produire une preuve** de consentement lors d'un contrôle ou d'une demande d'accès.

***

#### 7. Bonnes pratiques

* **Une seule source de vérité.** La CMP Sirdata reste l'autorité du recueil ; HubSpot en est le **reflet**, pas l'inverse. Ne modifiez pas la valeur manuellement.
* **Aligner valeur et type de champ.** Radio/Liste `Oui`/`Non` → `"Oui"` ; case à cocher → `"true"`. Une valeur non conforme est silencieusement rejetée.
* **Horodater systématiquement.** Une preuve de consentement sans date a peu de valeur juridique : remplissez toujours `consentement_pixel_email_date`.
* **Gérer le retrait.** Si l'utilisateur retire son consentement, repassez la propriété à `Non` (même mécanisme, valeur inversée).
* **Ne jamais exposer un jeton API côté client.** Pour la voie serveur, gardez le jeton privé côté back-end.
* **Différer si l'identité est inconnue.** Pas d'email = pas d'écriture contact. Stockez l'état localement et synchronisez à l'identification.
* **Valider juridiquement.** Le choix de la base légale (consentement vs intérêt légitime) et la durée de conservation relèvent de votre DPO.

{% hint style="warning" %}
Les libellés et chemins d'écran HubSpot peuvent varier selon votre édition et la langue de l'interface. Reportez-vous à votre instance pour les intitulés exacts
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cmp.docs.sirdata.net/faq/conditionnement/sirdata-extra-purposes/lier-le-consentement-au-contact-dans-hubspot.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
