# UKP — Notion API & CRM

> Source : NotebookLM "70-Notion-API-CRM" (9 sources) — https://notebooklm.google.com/notebook/e07da247-fee9-477e-98fd-cf1da8b6fe56
> Généré le : 2026-06-10
> Agents consommateurs : 70 (Automatisation)

---

Guide opérationnel pour l'agent IA chargé de la maintenance et de la configuration du CRM Fidulia sur Notion. Compile les spécifications techniques de l'API et les structures de données nécessaires pour une automatisation via n8n.

---

## AXE 1 — STRUCTURE DES PROPRIÉTÉS NOTION & USAGES CRM

Les propriétés d'une page dépendent de son parent (base de données) et doivent respecter le schéma défini.

| Propriété | Type API | Usage CRM Fidulia | Particularités / Pièges |
|---|---|---|---|
| **Nom** | `title` | Nom du contact ou titre du post | Obligatoire et unique par base |
| **Email** | `email` | Email pro du prospect | Doit être une chaîne valide ou `null` |
| **Statut** | `status` | Pipeline (Prospect, Signé) | Les couleurs ne sont pas modifiables via API |
| **Date** | `date` | Date de relance / publication | Format ISO 8601 uniquement |
| **LinkedIn** | `url` | URL du profil ou du post | Pas de chaînes vides — utiliser `null` pour vider |
| **Client** | `relation` | Lien Contact ↔ Contenu | Nécessite l'ID de la page liée |
| **Calculs** | `formula` | Score de priorité / KPIs | Lecture seule. Limité à 25 références par ligne |
| **Agrégat** | `rollup` | Total impressions par client | Lecture seule via API — ne supporte pas l'écriture |
| **ID Unique** | `unique_id` | Identifiant client Fidulia | Auto-incrémenté, non modifiable par l'API |

---

## AXE 2 — ENDPOINTS API ESSENTIELS & EXEMPLES JSON

L'API Notion utilise des conventions RESTful avec des corps de requête en JSON.

### Créer une fiche Contact — POST `/v1/pages`

Pour créer une page, spécifier le `parent` (ID de la base) et les `properties`.

```json
{
  "parent": { "database_id": "ID_BASE_CONTACTS" },
  "properties": {
    "Nom": { "title": [{ "text": { "content": "Jean Dupont" } }] },
    "Email": { "email": "jean.dupont@agence.com" },
    "Statut": { "status": { "name": "Qualifié" } },
    "LinkedIn": { "url": "https://linkedin.com/in/jdupont" }
  }
}
```

### Mettre à jour un statut — PATCH `/v1/pages/{page_id}`

Seules les propriétés spécifiées dans `properties` seront mises à jour.

```json
{
  "properties": {
    "Statut": { "status": { "name": "Connecté" } },
    "Date message 2": { "date": { "start": "2026-06-15" } }
  }
}
```

### Requête de déduplication — POST `/v1/databases/{id}/query`

Avant toute création, vérifier l'existence du contact par URL LinkedIn.

```json
{
  "filter": {
    "property": "LinkedIn",
    "url": { "equals": "https://linkedin.com/in/jdupont" }
  }
}
```
→ Si `results` non vide : récupérer l'ID existant. Ne pas créer de doublon.

---

## AXE 3 — SCHÉMA DES BASES DE DONNÉES FIDULIA

**Règle critique :** Chaque base doit être explicitement partagée avec la "Connection" Notion pour être accessible (erreur 404 sinon).

### Base Contacts (Prospection)

| Propriété | Type | Valeurs |
|---|---|---|
| Nom | `title` | Prénom + Nom |
| Entreprise | `rich_text` | Nom de la société |
| Statut | `status` | `File` / `Invité` / `Connecté` / `Message 2` / `Qualifié` / `Archivé` |
| LinkedIn | `url` | URL du profil |
| Date invitation | `date` | Date d'envoi de l'invitation |
| Variante A/B | `select` | `A — Sans note` / `B — Avec note` |
| Note invitation | `rich_text` | Texte de la note (si variante B) |
| Tags niche | `multi_select` | CGP, Expert-comptable, Avocat... |

### Base Contenu (Ghostwriting)

| Propriété | Type | Valeurs |
|---|---|---|
| Titre | `title` | Accroche ou titre de travail |
| Client | `relation` | Lien vers la base Contacts |
| Statut | `status` | `Brouillon` / `À valider` / `Planifié` / `Publié` |
| Impressions | `number` | Donnée saisie par n8n |
| Pilier | `select` | Les 4 piliers éditoriaux |
| Date publication | `date` | Date de publication LinkedIn |

### Base KPIs (Reporting)

| Propriété | Type | Valeurs |
|---|---|---|
| Mois | `date` | Début du mois concerné |
| Client | `relation` | Liaison pour Rollups |
| RDV générés | `number` | Meetings issus du CRM |
| SSI début | `number` | Score SSI en début de mois |
| SSI fin | `number` | Score SSI en fin de mois |
| Posts publiés | `number` | Volume mensuel |

---

## AXE 4 — RATE LIMITS & GESTION DES ERREURS

| Limite | Valeur | Correction |
|---|---|---|
| **Débit** | Erreur 429 si trop de requêtes | Files d'attente asynchrones — ne pas batcher sans délai |
| **Pagination** | 100 résultats max par appel | Utiliser `next_cursor` si `has_more: true` |
| **Relation/Rollup** | 25 premiers items seulement via endpoint page standard | Utiliser `retrieve a page property item` pour la liste complète |
| **Propriétés par base** | 500 max recommandé | Au-delà : performances dégradées — partitionner |

**Logique de retry en n8n :**
- Activer **Retry on Fail** sur tous les nœuds Notion : 3 tentatives, délai 2 secondes
- Ajouter un nœud **IF** après chaque appel critique pour vérifier le code HTTP retourné

---

## AXE 5 — OPÉRATIONS N8N + NOTION

### Opérations natives du nœud Notion dans n8n

| Ressource | Opérations disponibles | Usage Fidulia |
|---|---|---|
| **Database Page** | Create, Update, Get, Get Many | Gestion contacts + contenu |
| **Database** | Search | Vérification existence base |
| **Block** | Append After | Ajout notes/commentaires dans le corps de page |

### Template n8n — mise à jour de statut automatisée

```
1. Schedule Trigger (Cron) → chaque matin 8h
2. Notion: Database Page → Get Many
   Filtre : "Date message 2" = aujourd'hui ET Statut = "Connecté"
3. Loop Over Items (Batch Size: 1)
4. [Action manuelle Fabien — pas d'envoi DM automatique]
5. Notion: Database Page → Update
   Statut = "Message 2 envoyé"
```

**Note :** Si une opération n'est pas supportée nativement par le nœud n8n Notion, utiliser le nœud **HTTP Request** avec l'API directe + Bearer token Notion.

---

## AXE 6 — DÉDUPLICATION & BONNES PRATIQUES

### Règle de déduplication (obligatoire avant toute création)

```
POST /v1/databases/{contacts_id}/query
→ filter sur LinkedIn URL
→ if results.length > 0 → PATCH sur results[0].id
→ if results.length = 0 → POST /v1/pages (création)
```

### Bonnes pratiques opérationnelles

| Règle | Détail |
|---|---|
| Toujours travailler avec l'ID UUID | `1429989f-e8ac-4eff-bc8f-57f56486db54` — jamais le nom de page |
| Propriétés vs Contenu | Données structurées → propriétés / Notes libres → blocks |
| `null` pas chaîne vide | Pour vider un champ URL ou email : passer `null`, pas `""` |
| Partage Integration | Chaque base doit être partagée manuellement avec la connection Notion |
| Nommage cohérent | Même nom de propriété dans toutes les bases client (ex: toujours "Statut" pas "Status") |
