> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanova.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Référence du modèle d'événements

> Référence complète des champs des événements navigateur et serveur : quoi envoyer, à quoi sert chaque champ et comment les événements sont stockés et enrichis.

Tous les événements que vous envoyez au suivi des conversions de Scanova — depuis le navigateur comme depuis votre serveur — suivent une structure commune. Cette page décrit chaque champ que vous pouvez inclure et ce que la chaîne de traitement en fait.

## Événements du navigateur (`POST /ct`)

Les événements du navigateur sont envoyés automatiquement par le SDK, ou manuellement via `scanova('track', ...)`. Ils représentent des actions qui se produisent dans le navigateur du visiteur.

### Les champs que vous pouvez envoyer

| Champ             | Type            | Obligatoire | Description                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ----------------- | --------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event_id`        | Chaîne UUID     | Non         | Identifiant unique de cet événement. Généré par le SDK si vous l'omettez. Envoyez un identifiant stable depuis votre code si vous voulez relancer sans risque.                                                                                                                                                                                                                                                                                          |
| `site_id`         | Chaîne          | Oui         | Identifiant de votre site de suivi, disponible dans le tableau de bord.                                                                                                                                                                                                                                                                                                                                                                                 |
| `event_type`      | Chaîne          | Oui         | Le type d'événement. Utilisez le snake\_case (par exemple `page_view`, `cta_click` ou `signup_completed`).                                                                                                                                                                                                                                                                                                                                              |
| `scan_session_id` | Chaîne UUID     | Non         | Renseigné automatiquement par le SDK à partir du paramètre d'URL `scnv`. Indispensable à l'attribution au QR Code.                                                                                                                                                                                                                                                                                                                                      |
| `web_session_id`  | Chaîne UUID     | Non         | Renseigné automatiquement par le SDK à chaque session de navigation (délai de 30 minutes).                                                                                                                                                                                                                                                                                                                                                              |
| `visitor_id`      | Chaîne UUID     | Non         | Renseigné automatiquement par le SDK. Conservé un an dans un cookie.                                                                                                                                                                                                                                                                                                                                                                                    |
| `page_url`        | Chaîne          | Non         | URL complète de la page en cours, chaîne de requête comprise.                                                                                                                                                                                                                                                                                                                                                                                           |
| `page_title`      | Chaîne          | Non         | Titre de la page. Le SDK navigateur ne l'envoie pas ; utile seulement pour les intégrations directes à l'API.                                                                                                                                                                                                                                                                                                                                           |
| `referrer`        | Chaîne          | Non         | L'URL de provenance.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `event_time`      | Chaîne ISO 8601 | Non         | Heure de l'événement en UTC. Sans valeur, l'heure de réception par le serveur est utilisée. Une valeur explicite est conservée plutôt que remplacée par l'heure de réception : un événement antidaté se range donc dans la période qu'il indique, ce qui est utile pour amorcer ou migrer des données. À noter : le SDK navigateur envoie une clé `timestamp`, qui est un champ interne distinct — pour un appel direct à l'API, utilisez `event_time`. |
| `device`          | Objet           | Non         | Contexte du navigateur et de l'appareil — voir plus bas.                                                                                                                                                                                                                                                                                                                                                                                                |
| `metadata`        | Objet           | Non         | Données clé-valeur libres. 10 Ko et 5 niveaux de profondeur au maximum. Aucune adresse e-mail en clair.                                                                                                                                                                                                                                                                                                                                                 |

**Champs de l'objet `device` :**

| Champ           | Description                                |
| --------------- | ------------------------------------------ |
| `user_agent`    | Chaîne user-agent du navigateur            |
| `screen_width`  | Largeur de l'écran en pixels               |
| `screen_height` | Hauteur de l'écran en pixels               |
| `language`      | Langue du navigateur (par exemple `en-US`) |

### Exemple de contenu d'un événement navigateur

```json theme={null}
{
  "event_id": "f9ac7db6-f900-4d8e-8918-c846834195a8",
  "site_id": "N74rwgykxCwUe7SDFb2BMVN8Kc0aCQvKajiUKz9MSk3Bldn70jw8uLE3dUTgeS6r",
  "event_type": "cta_click",
  "scan_session_id": "7ad26d4f-3181-4ef8-b6ca-b8f59499dd43",
  "page_url": "https://yoursite.com/?scnv=7ad26d4f-3181-4ef8-b6ca-b8f59499dd43",
  "referrer": "",
  "timestamp": "2026-05-13T10:00:00.000Z",
  "device": {
    "user_agent": "Mozilla/5.0 ...",
    "screen_width": 1680,
    "screen_height": 1050,
    "language": "en-US"
  },
  "metadata": {
    "button_text": "Start Free Trial",
    "section": "pricing"
  }
}
```

***

## Événements serveur (`POST /server-events`)

Les événements serveur sont envoyés depuis votre backend avec une clé d'API. Ils représentent des actions qui se produisent sur votre serveur : achats finalisés, inscriptions confirmées ou leads créés dans votre CRM.

### Les champs que vous pouvez envoyer

| Champ              | Type            | Obligatoire | Description                                                                                                                     |
| ------------------ | --------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `event_id`         | Chaîne UUID     | Recommandé  | Identifiant unique de l'événement pour relancer sans risque. Générez-le une fois, conservez-le, réutilisez-le à chaque relance. |
| `site_id`          | Chaîne          | Oui         | Identifiant de votre site de suivi. Il doit correspondre au site autorisé par la clé d'API.                                     |
| `event_name`       | Chaîne          | Oui         | Nom parlant de l'événement (par exemple `purchase`, `signup` ou `lead`).                                                        |
| `scan_session_id`  | Chaîne UUID     | Oui         | Relie cet événement serveur au scan qui l'a déclenché. Transmettez-le du navigateur à votre serveur.                            |
| `web_session_id`   | Chaîne UUID     | Non         | L'identifiant de session web du navigateur — transmettez-le s'il est disponible, pour mieux relier les sessions.                |
| `visitor_id`       | Chaîne UUID     | Non         | L'identifiant de visiteur durable du navigateur — transmettez-le s'il est disponible.                                           |
| `event_time`       | Chaîne ISO 8601 | Non         | Le moment où l'événement s'est produit. Par défaut, l'heure de réception.                                                       |
| `conversion_value` | Objet           | Non         | `{ "amount": 99.99, "currency": "USD" }`. La devise doit être un code ISO 4217 à trois lettres.                                 |
| `user_identifiers` | Objet           | Non         | Identifiants hachés du visiteur — voir plus bas. N'envoyez jamais d'e-mail ni de téléphone en clair.                            |
| `properties`       | Objet           | Non         | Métadonnées clé-valeur libres. 10 Ko au maximum. Aucun e-mail en clair.                                                         |
| `consent`          | Chaîne          | Non         | `granted`, `denied` ou `pending`.                                                                                               |

**Champs de l'objet `user_identifiers` (tous hachés) :**

| Champ         | Description                                                        |
| ------------- | ------------------------------------------------------------------ |
| `email_hash`  | Hachage SHA-256 de l'adresse e-mail du visiteur en minuscules      |
| `phone_hash`  | Hachage SHA-256 du numéro de téléphone du visiteur au format E.164 |
| `external_id` | Votre identifiant interne de client ou d'utilisateur               |

### Exemple de contenu d'un événement serveur

```json theme={null}
{
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "site_id": "N74rwgykxCwUe7SDFb2BMVN8Kc0aCQvKajiUKz9MSk3Bldn70jw8uLE3dUTgeS6r",
  "event_name": "purchase",
  "scan_session_id": "7ad26d4f-3181-4ef8-b6ca-b8f59499dd43",
  "conversion_value": { "amount": 49.99, "currency": "USD" },
  "user_identifiers": {
    "email_hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576fc583c381f2d9c5d",
    "external_id": "usr_1234"
  },
  "properties": {
    "order_id": "ord_9876",
    "plan": "pro"
  }
}
```

***

## Conventions de nommage des événements

Utilisez des noms cohérents et parlants en `snake_case`. Un schéma clair rend les rapports plus lisibles.

| À faire            | À éviter                     |
| ------------------ | ---------------------------- |
| `page_view`        | `pageView`, `PageView`, `pv` |
| `cta_click`        | `click1`, `btnClick`         |
| `signup_completed` | `signup`, `reg`              |
| `purchase`         | `buy`, `order_placed_final`  |

## Idempotence

Les événements du navigateur comme ceux du serveur acceptent un champ `event_id` pour la déduplication :

* Si le même `event_id` arrive plusieurs fois, le doublon est stocké mais marqué `is_duplicate = 1`
* Les doublons sont automatiquement exclus des vues analytiques
* **Réutilisez toujours le même `event_id` lorsque vous relancez un événement serveur en échec**

## Confidentialité et RGPD

* **N'envoyez jamais d'adresse e-mail en clair** dans `metadata` ni dans `properties`. Utilisez `user_identifiers` avec des valeurs hachées.
* Le champ `consent` détermine le traitement des données personnelles dans la chaîne :
  * `granted` — tous les champs sont stockés normalement
  * `denied` ou `pending` — `page_url`, `referrer`, `city` et `metadata` sont retirés avant le stockage
  * La valeur de `consent` elle-même est toujours conservée, à titre de trace

### Envoyer le consentement depuis le navigateur

Le SDK navigateur n'a pas d'API de consentement intégrée. L'approche recommandée consiste à **charger le SDK sous condition**, selon la décision de votre plateforme de gestion du consentement :

```html theme={null}
<script>
  // Only load the SDK after the user grants consent
  if (userHasGrantedConsent()) {
    (function(w,d,s,o,f,js,fjs){
      w['ScanovaTrackingObject']=o;w[o]=w[o]||function(){(w[o].q=w[o].q||[]).push(arguments)};
      js=d.createElement(s),fjs=d.getElementsByTagName(s)[0];
      js.id=o;js.src=f;js.async=1;fjs.parentNode.insertBefore(js,fjs);
    })(window,document,'script','scanova','https://cdn.scanova.io/ct/js/qcg.min.js');
    scanova('init', 'YOUR_SITE_ID', { autoPageview: true });
  }
</script>
```

### Envoyer le consentement depuis le serveur

Pour les événements serveur, transmettez la valeur de `consent` directement dans le contenu de chaque requête, à côté de vos autres champs.
