Votre tableau de bord Instantly s'ouvre avec 200 leads en attente, des templates préparés, et cette même sensation creuse — un autre lot de « Bonjour {firstName}, j'ai remarqué votre entreprise... » sur le point d'être envoyé. Chaque agence déteste le cold email. Nous aussi. Pas parce que l'outreach ne fonctionne pas, mais parce que chaque plateforme payante nécessitait toujours des heures de recherche manuelle, envoyait toujours du contenu qui semblait écrit par un bot, et coûtait toujours 300 $/mois pour faire ce que nous savions que Claude pouvait faire mieux en quelques secondes. Nous avons donc arrêté de louer. Nous avons câblé Claude, Hunter, Instantly et Supabase dans un système qui écrit des ouvertures contextuelles à partir de scrapes web en direct, évalue les réponses par intention, et enregistre chaque interaction sans la taxe SaaS. L'architecture n'est pas sorcière — mais le taux de réponse a augmenté, le travail fastidieux a disparu, et nous possédons toute la pile.

Ce n'est pas un post d'architecture théorique. Nous exécutons ce système en production depuis des mois, en envoyant des milliers d'emails personnalisés qui obtiennent réellement des réponses. Je vais vous expliquer exactement pourquoi nous l'avons construit, comment les pièces s'assemblent, et ce que nous avons appris à la dure.

Table des matières

Pourquoi nous avons construit notre propre système de cold email avec Claude, Instantly et Supabase

Le problème avec les outils d'outreach prêts à l'emploi

Nous avons essayé les suspects habituels. Lemlist. Apollo. Woodpecker. Ce sont de bons outils pour beaucoup de cas d'usage. Mais en tant qu'agence de développement web headless, nos besoins en outreach étaient spécifiques d'une manière que ces plateformes ne pouvaient pas gérer.

Voici ce qui s'est continuellement cassé :

Les champs de personnalisation génériques ne sont pas de la personnalisation. Insérer le nom de l'entreprise et le titre du poste de quelqu'un dans un template ne trompe personne en 2026. Nous avions besoin d'emails qui fassent référence à la pile technologique réelle d'un prospect, ses problèmes de performance du site, ou des décisions architecturales spécifiques visibles sur son site public.

L'étape de recherche était le goulot d'étranglement. Notre meilleur outreach a toujours impliqué que quelqu'un de l'équipe regarde réellement le site d'un prospect, le fasse passer par PageSpeed Insights, vérifie leur framework, et écrive quelque chose de spécifique. Cela prenait 10-15 minutes par lead. À l'échelle, c'est un travail à temps plein.

Les données étaient dispersées dans trop d'endroits. Les leads dans une feuille de calcul, les séquences d'emails dans une autre plateforme, les résultats dans un troisième tableau de bord. Nous ne pouvions pas construire des boucles de rétroaction parce que rien ne communiquait avec rien d'autre.

Les intégrations IA étaient superficielles. Certaines plateformes ont ajouté des fonctionnalités « d'écriture IA », mais ce n'étaient essentiellement que des emballages GPT qui générant le même contenu insipide que tout le monde envoyait. Aucune capacité à intégrer un contexte personnalisé, aucun contrôle sur les prompts, aucun moyen de construire des chaînes de raisonnement multi-étapes.

Nous avions besoin d'un système où l'IA faisait la recherche, pas seulement l'écriture.

Notre stack technologique et pourquoi nous l'avons choisi

Voici ce sur quoi nous nous sommes arrêtés après quelques itérations :

Composant Outil Rôle Coût mensuel
Recherche de leads et vérification d'email Hunter.io Trouver et vérifier les adresses email 49 $ (Starter)
Recherche et copywriting par IA Claude (API Anthropic) Analyser les prospects, générer des emails personnalisés ~30-60 $
Base de données et orchestration Supabase Stocker les leads, gérer l'état, déclencher les workflows 25 $ (Pro)
Envoi d'email et warmup Instantly.ai Livrabilité, infrastructure d'envoi, warmup 30 $ (Growth)
Colle d'automatisation Edge Functions personnalisées + Cron Connecter tout ensemble 0 $ (inclus dans Supabase)

Nous avons évalué beaucoup d'alternatives. Voici la version courte de pourquoi nous avons choisi ce que nous avons choisi :

Claude plutôt que GPT-4 : Nous avons testé les deux extensivement. Claude 3.5 Sonnet (et maintenant Claude 4 Sonnet en 2025) produit consistamment des emails qui sondent plus naturels et moins « générés par IA ». C'était aussi meilleur pour suivre les system prompts complexes sans dériver. Les prix étaient comparables, mais la fenêtre de contexte plus longue de Claude signifiait que nous pouvions intégrer plus de données de recherche par prospect.

Supabase plutôt qu'Airtable ou une configuration Postgres personnalisée : Nous avions besoin d'une vraie base de données avec sécurité au niveau des lignes, mais nous ne voulions pas gérer l'infrastructure. Supabase nous a donné Postgres, Edge Functions, Cron jobs, et un tableau de bord décent — tout en un endroit. Nous utilisons Supabase intensivement pour les projets clients aussi, donc l'équipe le connaissait déjà bien.

Instantly plutôt que Lemlist ou Smartlead : Le réseau de warmup d'Instantly est véritablement bon, leur API est propre, et la tarification avait du sens pour notre volume. Nous n'avons pas besoin du générateur de séquences intégré d'Instantly parce que nous gérons nous-mêmes la logique de séquençage.

Hunter plutôt qu'Apollo ou Snov.io : La vérification d'email de Hunter est constamment la plus précise que nous avons testée. Leur API de recherche de domaine est rapide et la qualité des données est élevée. Apollo a plus de points de données, mais nous avons trouvé que leur précision d'email était inférieure, ce qui tue la livrabilité.

Vue d'ensemble de l'architecture

Le système fonctionne en cinq étapes, chacune s'exécutant indépendamment :

[Sources de leads] → [Enrichissement Hunter] → [Base de données Supabase] → [Recherche Claude + Copywriting] → [Envoi Instantly]
     ↑                                       ↑                                           |
     |                                       |                                           |
     +----------- Boucle de rétroaction -----+-------------------------------------------+
  1. Ingestion : Nous intégrons les domaines de prospects provenant de diverses sources (listes manuelles, scrapers, données de parrainage)
  2. Enrichissement : Hunter trouve les contacts et vérifie les emails
  3. Stockage : Tout atterrit dans Supabase avec suivi du statut
  4. Recherche + Écriture : Claude analyse chaque prospect et génère du contenu personnalisé
  5. Envoi : Les emails approuvés vont aux campagnes Instantly
  6. Apprentissage : Les données de réponse reviennent à Supabase, informant la personnalisation future

Chaque étape est découplée. Si l'API de Hunter tombe en panne, la file d'enrichissement s'accumule simplement — cela n'interrompt pas l'envoi. Si nous voulons remplacer Claude par un modèle différent, nous changeons une fonction.

Pourquoi nous avons construit notre propre système de cold email avec Claude, Instantly et Supabase - architecture

Trouver et enrichir les leads avec Hunter

Hunter.io remplit deux tâches critiques : trouver la bonne personne dans une entreprise et vérifier que son email fonctionne réellement.

Voici une version simplifiée de notre fonction d'enrichissement :

import { createClient } from '@supabase/supabase-js';

const HUNTER_API_KEY = Deno.env.get('HUNTER_API_KEY');

async function enrichLead(domain: string) {
  // Recherche de domaine pour trouver des décideurs
  const searchRes = await fetch(
    `https://api.hunter.io/v2/domain-search?domain=${domain}&department=executive,it&api_key=${HUNTER_API_KEY}`
  );
  const searchData = await searchRes.json();
  
  const contacts = searchData.data.emails
    .filter((e: any) => e.confidence > 70)
    .slice(0, 3); // Top 3 contacts par domaine
  
  // Vérifier chaque email
  for (const contact of contacts) {
    const verifyRes = await fetch(
      `https://api.hunter.io/v2/email-verifier?email=${contact.value}&api_key=${HUNTER_API_KEY}`
    );
    const verifyData = await verifyRes.json();
    
    if (verifyData.data.status === 'valid') {
      await supabase.from('leads').insert({
        domain,
        email: contact.value,
        first_name: contact.first_name,
        last_name: contact.last_name,
        position: contact.position,
        confidence: contact.confidence,
        status: 'enriched',
        enriched_at: new Date().toISOString()
      });
    }
  }
}

Nous filtrons par les départements executive et it parce que ce sont nos acheteurs — CTOs, VPs of Engineering, fondateurs techniques. Le filtrage de département de Hunter n'est pas parfait, mais cela élimine beaucoup de bruit.

Une chose que nous avons apprise : ne jamais ignorer la vérification d'email. Même avec les scores de confiance de Hunter, nous vérifions quand même chaque adresse. Un taux de rebond supérieur à 3 % ruinera la réputation de votre domaine d'envoi. Nous avons vu des domaines passer de 95 % de placement en boîte de réception à 40 % de dossier spam après un seul mauvais lot.

Nous exécutons environ 500 crédits de recherches Hunter par semaine, ce qui rentre confortablement dans leur plan Starter.

Personnalisation par IA avec Claude

C'est ici que les choses deviennent intéressantes. L'intégration Claude n'est pas juste « écris-moi un cold email ». C'est un pipeline de recherche et d'écriture multi-étapes.

Étape 1 : Analyse du site web

Avant que Claude n'écrive quoi que ce soit, nous lui intégrons des données sur le site du prospect. Nous effectuons un scrape basique en utilisant une fonction légère :

async function analyzeProspectSite(domain: string) {
  // Récupérer la page d'accueil et les pages clés
  const homepage = await fetch(`https://${domain}`);
  const html = await homepage.text();
  
  // Extraire les signaux technologiques du HTML
  const signals = {
    hasNextJs: html.includes('__next') || html.includes('_next/static'),
    hasReact: html.includes('react') || html.includes('__REACT'),
    hasWordPress: html.includes('wp-content') || html.includes('wp-includes'),
    hasShopify: html.includes('shopify') || html.includes('cdn.shopify'),
    hasGatsby: html.includes('gatsby'),
    usesJQuery: html.includes('jquery'),
    metaGenerator: extractMeta(html, 'generator'),
    pageSize: html.length,
    // ... plus de signaux
  };
  
  // Exécuter une vérification PageSpeed via API
  const psiData = await fetchPageSpeedInsights(domain);
  
  return {
    ...signals,
    performanceScore: psiData.lighthouseResult.categories.performance.score * 100,
    lcp: psiData.lighthouseResult.audits['largest-contentful-paint'].numericValue,
    cls: psiData.lighthouseResult.audits['cumulative-layout-shift'].numericValue,
    fid: psiData.lighthouseResult.audits['max-potential-fid'].numericValue
  };
}

Ceci donne à Claude des données réelles avec lesquelles travailler. Pas « Bonjour, j'ai remarqué que votre entreprise fait X » — plus comme « Votre page d'accueil LCP est de 4,2 secondes et vous exécutez toujours jQuery aux côtés de React, ce qui ajoute 90 KB à votre bundle initial ».

Étape 2 : Prompt de recherche Claude

Nous utilisons l'API Claude avec un system prompt soigneusement rédigé. Voici une version simplifiée :

const researchPrompt = `Vous êtes un développeur web senior analysant le site web d'un prospect pour une agence de développement headless. Compte tenu des données techniques suivantes sur son site, identifiez :

1. Leur pile technologique actuelle (soyez spécifique)
2. 2-3 problèmes concrets de performance ou d'architecture
3. Ce qu'une migration vers une architecture headless moderne pourrait améliorer
4. Une observation spécifique et non évidente qui montre une véritable analyse

Ne soyez PAS générique. Si vous ne pouvez pas trouver quelque chose de spécifique, dites-le.
Ne mentionnez PAS « dans le paysage numérique d'aujourd'hui » ou des expressions similaires.
Soyez direct et technique.

Données du site :
${JSON.stringify(siteAnalysis, null, 2)}

Prospect : ${lead.first_name} ${lead.last_name}, ${lead.position} à ${lead.domain}`;

const research = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1000,
  messages: [{ role: 'user', content: researchPrompt }]
});

Étape 3 : Génération d'email

La sortie de recherche alimente un deuxième appel Claude qui écrit l'email réel. Séparer la recherche de l'écriture était une perspicacité clé — quand nous avons essayé de faire les deux dans un seul prompt, les emails étaient pires. Claude sauterait la recherche pour arriver à l'écriture plus vite.

const emailPrompt = `Écrivez un cold email d'un développeur senior dans une agence web headless.

Notes de recherche :
${research.content[0].text}

Règles :
- 4-6 phrases max. Chaque phrase doit justifier sa place.
- Commencez par l'observation technique la plus spécifique.
- Pas de flaterie. Pas « j'aime ce que vous faites ».
- Un CTA clair : demander s'ils voudraient voir un audit de performance.
- Sonnez comme un développeur, pas comme un vendeur.
- Utilisez son prénom. Pas de nom de famille dans la salutation.
- Ligne d'objet : courte, spécifique à son problème technique, minuscules.`;

Le résultat ? Des emails qui s'ouvrent avec des choses comme « Votre boutique Shopify Plus rend côté serveur des pages de produit qui pourraient être générées statiquement — cela ajoute 2+ secondes à chaque vue de produit » au lieu de « J'ai remarqué votre impressionnante entreprise et j'ai voulu vous contacter ».

Supabase comme couche d'orchestration

Supabase est le cerveau de l'opération. Voici notre schéma de base :

create table leads (
  id uuid primary key default gen_random_uuid(),
  domain text not null,
  email text,
  first_name text,
  last_name text,
  position text,
  confidence int,
  status text default 'new', -- new, enriched, researched, drafted, approved, sent, replied, bounced
  site_analysis jsonb,
  research_notes text,
  email_subject text,
  email_body text,
  instantly_campaign_id text,
  sent_at timestamptz,
  opened_at timestamptz,
  replied_at timestamptz,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

create index idx_leads_status on leads(status);
create index idx_leads_domain on leads(domain);

Le champ status pilote tout. Les tâches Cron de Supabase s'exécutent toutes les 15 minutes, récupérant les leads à chaque étape et les poussant vers la suivante :

-- Cron : Traiter les leads enrichis par le recherche Claude
select cron.schedule(
  'process-research',
  '*/15 * * * *',
  $$select net.http_post(
    'https://your-project.supabase.co/functions/v1/process-research',
    '{}',
    '{"Authorization": "Bearer your-service-key"}'::jsonb
  )$$
);

Nous traitons par lots 20 leads par exécution pour rester dans les limites de taux de Claude et garder les coûts prévisibles.

La colonne site_analysis JSONB est incroyablement utile. Nous pouvons interroger tous nos leads pour trouver des modèles — comme « montrez-moi tous les leads exécutant WordPress avec un score de performance inférieur à 50 » — et construire des campagnes ciblées à partir de ces segments.

Envoi à l'échelle avec Instantly

Instantly gère la livraison réelle d'email. Nous poussons les emails approuvés via leur API :

async function pushToInstantly(lead: Lead) {
  const response = await fetch('https://api.instantly.ai/api/v1/lead/add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      api_key: INSTANTLY_API_KEY,
      campaign_id: lead.instantly_campaign_id,
      skip_if_in_workspace: true,
      leads: [{
        email: lead.email,
        first_name: lead.first_name,
        last_name: lead.last_name,
        company_name: lead.domain,
        personalization_1: lead.email_subject,
        personalization_2: lead.email_body
      }]
    })
  });
  
  if (response.ok) {
    await supabase
      .from('leads')
      .update({ status: 'sent', sent_at: new Date().toISOString() })
      .eq('id', lead.id);
  }
}

Les templates de campagne d'Instantly utilisent les variables {{personalization_1}} et {{personalization_2}}, qui correspondent à notre sujet et corps générés par Claude. La campagne elle-même est juste une coquille — toute l'intelligence vit dans notre système.

Nous exécutons 3 comptes d'envoi via le warmup d'Instantly pendant au moins 2 semaines avant d'envoyer tout outreach. Le warmup de domaine n'est pas optionnel. Nous avons appris cela à la dure avec notre premier domaine qui a été signalé en une semaine.

Configuration de livrabilité

Notre infrastructure d'envoi :

  • 3 domaines (variantes de notre marque, pas notre domaine principal)
  • SPF, DKIM et DMARC configurés sur tous
  • Comptes Google Workspace (pas Outlook — Google gère mieux le cold email dans nos tests)
  • Warmup Instantly s'exécutant continuellement, même les jours d'envoi actifs
  • Max 35 emails par compte par jour
  • Intervalles d'envoi aléatoires entre 3-7 minutes

La colle d'automatisation

Les Edge Functions de Supabase connectent tout ensemble. Voici le flux en pseudocode :

Toutes les 15 minutes :
  1. Récupérer les leads avec status='new', exécuter enrichissement Hunter → status='enriched'
  2. Récupérer les leads avec status='enriched', exécuter analyse du site → status='analyzed'
  3. Récupérer les leads avec status='analyzed', exécuter recherche Claude + génération d'email → status='drafted'
  4. (Un humain examine les emails ébauche dans le tableau de bord Supabase)
  5. Récupérer les leads avec status='approved', pousser vers Instantly → status='sent'
  6. Récupérer les données d'engagement de l'API Instantly → mettre à jour opened_at, replied_at

L'étape 4 est importante. Nous n'automatisons pas complètement l'envoi. Chaque email reçoit un examen humain avant d'être envoyé. Cela capture l'hallucination occasionnelle (Claude a une fois prétendu qu'un site était construit avec Remix quand c'était clairement Next.js) et nous permet d'ajouter des touches personnelles.

L'étape de révision prend environ 2-3 secondes par email puisque Claude fait 95 % du travail correctement. Nous approuvons par lots en utilisant une simple vue du tableau de bord Supabase.

Résultats et ce que nous avons appris

Nous exécutons ce système depuis Q1 2025. Voici des chiffres réels :

Métrique Notre système Moyenne de l'industrie (2026)
Taux d'ouverture 62 % 24 %
Taux de réponse 8,4 % 1-3 %
Taux de réponse positive 4,1 % 0,5-1 %
Taux de rebond 0,8 % 3-5 %
Coût par lead contacté 0,18 $ 0,50-2,00 $
Temps par lead (humain) ~5 secondes (révision) 10-15 minutes

Le taux d'ouverture est élevé parce que les lignes d'objet sont spécifiques. « votre shopify lcp est 4.2s » s'ouvre. « Question rapide » ne s'ouvre pas.

Le taux de réponse est élevé parce que les emails démontrent une véritable connaissance technique. Quand un CTO lit un email qui identifie correctement sa pile technologique et un vrai problème de performance, il est plus susceptible d'engager — même s'il sait que c'est de l'outreach.

Ce qui n'a pas fonctionné

Envoi entièrement automatisé (sans révision humaine) : Nous avons essayé cela pendant deux semaines. Claude hallucine les détails de la pile technologique environ 5 % du temps. C'est un taux d'erreur faible pour un LLM, mais envoyer un email qui dit « votre application React » à quelqu'un exécutant Vue est pire qu'envoyer un email générique. Le dommage à la confiance est réel.

Emails longs : Nos premiers prompts Claude généraient des emails de 8-10 phrases. Les taux de réponse étaient la moitié de ce que nous voyons maintenant avec 4-6 phrases. Plus court c'est mieux. Toujours.

Envoyer plus de 40 emails par jour par compte : La livrabilité tombe à pic. 30-35 est le sweet spot en 2026.

Utiliser Claude pour les suivis basés sur les ouvertures : Nous avons essayé de générer des emails de suivi déclenchés par les ouvertures. Les suivis semblaient agressifs et la conversion ne valait pas le coût. Nous envoyons maintenant un simple suivi non-IA trois jours plus tard.

Répartition des coûts

Voici ce que cela nous coûte mensuellement, en traitant environ 2 000 leads :

Service Coût mensuel Notes
Hunter.io (Starter) 49 $ 500 recherches + vérifications
API Anthropic (Claude) 45 $ ~2 000 recherches + générations d'email
Supabase (Pro) 25 $ Base de données, Edge Functions, Cron
Instantly (Growth) 30 $ Envoi, warmup, analyses
Google Workspace (3 comptes) 21 $ Infrastructure d'envoi
Domaines (3) 10 $ Coût annuel amorti
Total ~180 $ 0,09 $ par lead traité

Comparez cela à la plan 79 $/mois d'Apollo (enrichissement limité, séquences basiques) ou aux 69 $/mois par siège de Lemlist. Nous dépensons moins et obtenons des résultats dramatiquement meilleurs parce que la personnalisation est réelle, pas basée sur template.

Pour le contexte, ce système a directement généré des leads qui se sont transformés en projets de développement Next.js et développement Astro valant 50-100x le coût mensuel. Le ROI est absurde.

FAQ

Combien de temps a-t-il fallu pour construire ce système ?

La première version fonctionnelle a pris environ deux semaines d'effort à temps partiel — peut-être 40 heures au total. Nous avons continué à l'itérer depuis, principalement en peaufinant les prompts Claude et en ajoutant la gestion des cas limites. Si vous êtes à l'aise avec les Edge Functions de Supabase et les API REST, vous pouvez avoir une version basique fonctionnelle en un week-end.

N'est-ce pas juste du spam avec des étapes supplémentaires ?

Bonne question. La différence est que chaque email contient une véritable observation technique sur le site web du destinataire. Nous ne blasting pas « sautons sur un appel » à 10 000 personnes. Nous envoyons des insights spécifiques et utiles à une liste ciblée de personnes qui ont réellement les problèmes que nous résolvons. Notre taux de désinscription est inférieur à 0,5 %, ce qui suggère que les destinataires ne le voient pas comme du spam.

Pourquoi Claude plutôt que GPT-4 ou Gemini ?

Nous avons tous testés. Claude a suivi nos system prompts de manière plus fiable — en particulier les contraintes comme « ne pas être générique » et « ne pas utiliser des expressions toutes faites ». GPT-4 dérivait vers un langage de vente même avec des instructions explicites de ne pas le faire. Gemini était rapide mais la qualité de sortie était incohérente. Cela peut changer à mesure que les modèles évoluent, et notre système est conçu pour échanger les modèles facilement.

Comment gérez-vous la conformité RGPD et CAN-SPAM ?

Tous nos outreach ciblent les emails professionnels (pas personnels), incluent notre adresse physique, et ont une désinscription claire dans chaque email. Pour le RGPD, nous traitons les données sous intérêt légitime pour l'outreach B2B, maintenons des enregistrements des activités de traitement, et honorons les demandes de suppression immédiatement via un webhook automatisé. Nous supprimons également les leads de plus de 90 jours de notre base de données automatiquement. Consultez un avocat pour votre situation spécifique — ce n'est pas un conseil juridique.

Que se passe-t-il quand un lead répond ?

Les réponses reviennent de l'API d'Instantly à Supabase. Nous recevons une notification Slack pour chaque réponse, et un humain reprend immédiatement la conversation. Nous n'utilisons jamais l'IA pour la gestion des réponses. Une fois que quelqu'un s'engage, il mérite une vraie personne. Les prospects intéressés sont dirigés vers notre page de contact ou directement vers un lien de réservation d'appel.

Cette approche peut-elle fonctionner pour des services non techniques ?

La partie analyse du site est spécifique au développement web, mais le modèle d'architecture — enrichir les leads, utiliser l'IA pour rechercher et personnaliser, envoyer via un outil dédié — fonctionne pour tout outreach B2B. Vous auriez juste besoin d'entrées de recherche différentes. Une agence de design pourrait analyser la conception visuelle et les modèles UX. Une agence de marketing pourrait tirer les métriques SEO. La clé est de donner à Claude des données réelles, pas lui demander d'inventer des choses.

Quelle est la partie la plus difficile à maintenir ce système ?

La maintenance des prompts. Comme les modèles Claude se mettent à jour, les prompts qui fonctionnaient parfaitement ont parfois besoin d'ajustement. Nous passons aussi du temps à surveiller la livrabilité d'email — en vérifiant Google Postmaster Tools, en observant les pics de taux de spam, en alternant les comptes d'envoi. C'est peut-être 2-3 heures par semaine de maintenance au total.

Vendriez-vous cela comme produit ?

Nous y avons pensé, mais honnêtement l'avantage concurrentiel est trop précieux. Si chaque agence exécutait exactement ce système, l'efficacité chuterait parce que les destinataires commenceraient à voir des emails générés par IA-recherche partout. Pour le moment, nous le gardons comme un outil interne. Si vous voulez de l'aide pour construire quelque chose de similaire pour votre entreprise, contactez-nous — nous avons aidé quelques clients à mettre en place des systèmes similaires dans le cadre de notre développement de CMS headless.