[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fUtkxvaVNNjoBWkGh7dbYx-tzWLCrduEJOiiVbrjy6io":3,"$ftyggnmjaN6yK6SdTbQLHgczNaypj2NLmc1IaOBcv428":25},{"_id":4,"slug":5,"__v":6,"author":7,"body":8,"canonical":9,"category":10,"createdAt":11,"date":12,"description":13,"htmlContent":14,"image":15,"imageAlt":15,"readingTime":16,"tags":17,"title":23,"updatedAt":24},"69e2055faa6b273b0caa9ce6","machine-first-architecture-ai-agents-are-here-and-your-website-isn-t-ready-says-no-hacks-podcast-host-via-sejournal-theshelleywalsh",0,"Equipe Seogard","Googlebot indexe vos pages. Un AI agent les *consomme* — il extrait un prix, compare une disponibilité, déclenche un achat. La distinction est fondamentale : l'un construit un index, l'autre exécute une tâche pour un utilisateur. Et la majorité des sites sont architecturés exclusivement pour le premier cas.\n\nSlobodan Manic, dans le podcast [NoHacks relayé par Search Engine Journal](https://www.searchenginejournal.com/machine-first-architecture-ai-agents-are-here-and-your-website-isnt-ready-says-nohacks-podcast-host/571898/), pose un diagnostic clair : les sites web sont construits pour des humains qui naviguent et des crawlers qui indexent, pas pour des agents autonomes qui exécutent des workflows. Ce constat ouvre un chantier d'architecture technique que la plupart des équipes SEO n'ont pas encore entamé.\n\n## Le décalage entre l'architecture web actuelle et les besoins des AI agents\n\nUn crawler classique — Googlebot, Bingbot — suit un schéma prévisible : il découvre des URLs via le sitemap ou les liens internes, fetch le HTML (et éventuellement exécute le JavaScript), extrait le contenu textuel et les métadonnées, puis passe à l'URL suivante. Le rythme est séquentiel, patient, tolérant.\n\nUn AI agent fonctionne différemment. Il reçoit une instruction de l'utilisateur (\"trouve-moi un vol Paris-Lisbonne le 15 mai sous 200€ avec bagage cabine inclus\"), décompose cette instruction en sous-tâches, et interroge potentiellement des dizaines de sources en parallèle. Il n'a pas le temps de parser du HTML sémantiquement ambigu. Il a besoin de données structurées, d'endpoints prévisibles, de réponses machine-readable.\n\nLe problème concret : la plupart des sites e-commerce servent leurs données produit dans du HTML templated avec des classes CSS comme `product-price`, `product-title`, etc. Un humain voit la page et comprend. Googlebot extrait le contenu textuel et s'en sort grâce à des heuristiques puissantes. Un AI agent, lui, cherche une donnée structurée normalisée — et si votre JSON-LD est incomplet ou absent, il passe son tour.\n\n### Ce que les AI agents attendent réellement\n\nD'après les patterns observés dans les logs des bots d'[OpenAI, Meta et ByteDance](/blog/openai-meta-bytedance-lead-ai-bot-traffic-in-publishing-via-sejournal-mattgsouthern), les AI agents montrent trois comportements distincts des crawlers classiques :\n\n1. **Extraction ciblée** : ils ne crawlent pas tout le site. Ils ciblent des pages spécifiques correspondant à la requête de l'utilisateur.\n2. **Parsing structuré d'abord** : ils cherchent JSON-LD, microdata, ou des API endpoints avant de tenter un parsing HTML.\n3. **Vitesse d'exécution** : un agent qui compare 40 sites ne peut pas attendre 3 secondes de rendering JavaScript par page.\n\nCe dernier point rejoint directement la problématique du [rendering budget](/blog/rendering-budget-de-google-combien-de-javascript-est-trop) : si Googlebot alloue déjà un budget limité au rendering JS, imaginez un AI agent qui doit traiter des centaines de pages en quelques secondes.\n\n## Structurer vos données pour la consommation machine\n\nLe JSON-LD n'est pas nouveau. Mais l'exigence de complétude change radicalement quand le consommateur est un agent autonome plutôt qu'un moteur de recherche.\n\n### Au-delà du minimum syndical Schema.org\n\nLa plupart des implémentations Schema.org en production sont minimalistes : `Product` avec `name`, `price`, `availability`. Suffisant pour les rich snippets Google. Insuffisant pour un AI agent qui doit prendre une décision d'achat.\n\nVoici un exemple de JSON-LD complet orienté machine-first pour une page produit e-commerce :\n\n```html\n\u003Cscript type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Product\",\n  \"name\": \"Casque Sony WH-1000XM5\",\n  \"sku\": \"WH1000XM5B\",\n  \"gtin13\": \"4548736132597\",\n  \"brand\": {\n    \"@type\": \"Brand\",\n    \"name\": \"Sony\"\n  },\n  \"description\": \"Casque sans fil à réduction de bruit active, Bluetooth 5.2, autonomie 30h\",\n  \"image\": [\n    \"https://audioshop.fr/images/wh1000xm5-front.webp\",\n    \"https://audioshop.fr/images/wh1000xm5-side.webp\"\n  ],\n  \"offers\": {\n    \"@type\": \"Offer\",\n    \"url\": \"https://audioshop.fr/casques/sony-wh-1000xm5\",\n    \"priceCurrency\": \"EUR\",\n    \"price\": \"349.00\",\n    \"priceValidUntil\": \"2026-06-30\",\n    \"availability\": \"https://schema.org/InStock\",\n    \"itemCondition\": \"https://schema.org/NewCondition\",\n    \"seller\": {\n      \"@type\": \"Organization\",\n      \"name\": \"AudioShop\"\n    },\n    \"shippingDetails\": {\n      \"@type\": \"OfferShippingDetails\",\n      \"shippingRate\": {\n        \"@type\": \"MonetaryAmount\",\n        \"value\": \"0.00\",\n        \"currency\": \"EUR\"\n      },\n      \"deliveryTime\": {\n        \"@type\": \"ShippingDeliveryTime\",\n        \"handlingTime\": {\n          \"@type\": \"QuantitativeValue\",\n          \"minValue\": 0,\n          \"maxValue\": 1,\n          \"unitCode\": \"DAY\"\n        },\n        \"transitTime\": {\n          \"@type\": \"QuantitativeValue\",\n          \"minValue\": 1,\n          \"maxValue\": 3,\n          \"unitCode\": \"DAY\"\n        }\n      },\n      \"shippingDestination\": {\n        \"@type\": \"DefinedRegion\",\n        \"addressCountry\": \"FR\"\n      }\n    },\n    \"hasMerchantReturnPolicy\": {\n      \"@type\": \"MerchantReturnPolicy\",\n      \"applicableCountry\": \"FR\",\n      \"returnPolicyCategory\": \"https://schema.org/MerchantReturnFiniteReturnWindow\",\n      \"merchantReturnDays\": 30,\n      \"returnMethod\": \"https://schema.org/ReturnByMail\",\n      \"returnFees\": \"https://schema.org/FreeReturn\"\n    }\n  },\n  \"aggregateRating\": {\n    \"@type\": \"AggregateRating\",\n    \"ratingValue\": \"4.7\",\n    \"reviewCount\": \"2847\"\n  },\n  \"additionalProperty\": [\n    {\n      \"@type\": \"PropertyValue\",\n      \"name\": \"Autonomie\",\n      \"value\": \"30h\"\n    },\n    {\n      \"@type\": \"PropertyValue\",\n      \"name\": \"Connectivité\",\n      \"value\": \"Bluetooth 5.2, NFC\"\n    },\n    {\n      \"@type\": \"PropertyValue\",\n      \"name\": \"Poids\",\n      \"value\": \"250g\"\n    }\n  ]\n}\n\u003C/script>\n```\n\nLa différence avec une implémentation classique : `shippingDetails`, `hasMerchantReturnPolicy`, `additionalProperty` pour les specs techniques, `gtin13` pour l'identification univoque. Un AI agent qui compare des casques audio peut maintenant extraire programmatiquement le prix, le délai de livraison, la politique de retour et les specs — sans parser un seul élément HTML.\n\n### Valider et monitorer la complétude\n\nLe piège classique : votre JSON-LD est complet au déploiement, puis une mise à jour du CMS casse silencieusement le champ `availability` ou supprime le bloc `shippingDetails`. Vous ne le découvrez que quand votre trafic AI chute.\n\nUtilisez le [Rich Results Test](https://search.google.com/test/rich-results) de Google pour la validation initiale, mais ce n'est pas suffisant pour un monitoring continu sur un catalogue de milliers de pages. Un outil de monitoring comme Seogard détecte ce type de régression dès qu'elle se produit — un champ JSON-LD qui disparaît sur 500 pages produit après un déploiement, c'est le genre de signal qu'aucun audit manuel ne capte à temps.\n\n## L'architecture API-first : exposer vos données aux agents\n\nLe JSON-LD dans le HTML est une première étape. Mais l'architecture machine-first va plus loin : elle expose des endpoints dédiés que les agents peuvent consommer directement, sans avoir à parser du HTML.\n\n### Le cas des product feeds revisité\n\nLes [product feeds en e-commerce](/blog/why-product-feeds-shouldn-t-be-the-most-ignored-seo-system-in-ecommerce) sont historiquement utilisés pour Google Merchant Center. Dans une architecture machine-first, ils deviennent un point d'entrée primaire pour les AI agents.\n\nMais le feed XML classique n'est pas idéal pour la consommation par agents. Un endpoint JSON paginé, filtrable, et documenté via une spécification OpenAPI est nettement plus exploitable :\n\n```typescript\n// Exemple d'endpoint Next.js API Route pour exposition machine-first\n// /pages/api/products/[category].ts\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { getProductsByCategory } from '@/lib/products';\n\ninterface MachineProduct {\n  sku: string;\n  gtin: string;\n  name: string;\n  price: { amount: number; currency: string };\n  availability: 'in_stock' | 'out_of_stock' | 'preorder';\n  shipping: {\n    free: boolean;\n    estimatedDays: { min: number; max: number };\n    countries: string[];\n  };\n  returnPolicy: {\n    days: number;\n    freeReturn: boolean;\n  };\n  specs: Record\u003Cstring, string>;\n  url: string;\n  lastUpdated: string; // ISO 8601\n}\n\nexport default async function handler(\n  req: NextApiRequest,\n  res: NextApiResponse\n) {\n  const { category } = req.query;\n  const page = parseInt(req.query.page as string) || 1;\n  const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);\n  \n  // Identifier l'agent pour le logging\n  const userAgent = req.headers['user-agent'] || '';\n  const isAIAgent = /GPTBot|ChatGPT|ClaudeBot|PerplexityBot|Applebot-Extended/i.test(userAgent);\n  \n  if (isAIAgent) {\n    // Log pour analyse — combien d'agents consomment vos données ?\n    console.log(`AI Agent request: ${userAgent} — ${category} page ${page}`);\n  }\n\n  const { products, total } = await getProductsByCategory(\n    category as string, \n    page, \n    limit\n  );\n\n  const machineProducts: MachineProduct[] = products.map(p => ({\n    sku: p.sku,\n    gtin: p.gtin13,\n    name: p.name,\n    price: { amount: p.price, currency: 'EUR' },\n    availability: p.stock > 0 ? 'in_stock' : 'out_of_stock',\n    shipping: {\n      free: p.price >= 50,\n      estimatedDays: { min: 1, max: 3 },\n      countries: ['FR', 'BE', 'CH']\n    },\n    returnPolicy: { days: 30, freeReturn: true },\n    specs: p.specifications,\n    url: `https://audioshop.fr/produits/${p.slug}`,\n    lastUpdated: p.updatedAt.toISOString()\n  }));\n\n  res.setHeader('Cache-Control', 'public, s-maxage=3600, stale-while-revalidate=600');\n  res.status(200).json({\n    data: machineProducts,\n    pagination: { page, limit, total, pages: Math.ceil(total / limit) },\n    _links: {\n      self: `/api/products/${category}?page=${page}&limit=${limit}`,\n      next: page * limit \u003C total \n        ? `/api/products/${category}?page=${page + 1}&limit=${limit}` \n        : null\n    }\n  });\n}\n```\n\nCe pattern offre plusieurs avantages : les AI agents n'ont pas besoin de parser du HTML, la réponse est typée et prévisible, la pagination permet de consommer de gros catalogues sans surcharger le serveur, et le header `Cache-Control` évite que 50 agents en parallèle ne fassent tomber votre infra.\n\n### Déclarer vos endpoints aux agents\n\nUn AI agent ne va pas deviner qu'un endpoint `/api/products/casques` existe. Deux mécanismes émergent pour la découverte :\n\nLe fichier `/.well-known/ai-plugin.json` (inspiré du format OpenAI) et le `robots.txt` enrichi. En attendant qu'un standard se stabilise, le plus pragmatique reste de lier votre documentation API depuis votre sitemap et vos pages HTML via un `\u003Clink>` :\n\n```html\n\u003Chead>\n  \u003C!-- Découverte machine de l'API produits -->\n  \u003Clink rel=\"alternate\" type=\"application/json\" \n        href=\"https://audioshop.fr/api/products/casques\" \n        title=\"Machine-readable product data\" />\n  \n  \u003C!-- Schéma OpenAPI pour la documentation -->\n  \u003Clink rel=\"describedby\" type=\"application/openapi+json\"\n        href=\"https://audioshop.fr/api/openapi.json\" />\n\u003C/head>\n```\n\nCe n'est pas encore un standard universel, mais les agents qui implémentent la découverte de sources cherchent précisément ce type de signaux.\n\n## Scénario concret : un e-commerce de 12 000 pages face aux AI agents\n\nPrenons AudioShop, un e-commerce spécialisé audio avec 12 000 pages produit, 800 pages catégories, et 200 pages de contenu éditorial. Le site tourne sur Next.js avec SSR, hébergé sur Vercel.\n\n### Le diagnostic initial\n\nL'équipe SEO analyse ses [logs serveur](/blog/why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility) sur les 90 derniers jours et découvre :\n\n- **GPTBot** : 45 000 requêtes/mois, concentrées sur les pages catégories\n- **ClaudeBot** : 12 000 requêtes/mois, principalement les pages produit\n- **PerplexityBot** : 8 000 requêtes/mois, les guides d'achat éditoriaux\n- **Applebot-Extended** : 3 500 requêtes/mois (Apple Intelligence)\n\nTotal : ~68 500 requêtes AI agents par mois, soit environ 15% du volume total de crawl. Ce ratio est cohérent avec ce que rapportent les éditeurs dans le secteur publishing.\n\nLe problème : le JSON-LD des pages produit ne contient que `name`, `price`, et `availability`. Pas de `shippingDetails`, pas de `gtin`, pas de specs techniques structurées. Les AI agents récupèrent le prix, mais n'ont aucun moyen machine-readable de comparer les délais de livraison ou les politiques de retour — des critères déterminants dans la décision d'achat que l'agent exécute pour l'utilisateur.\n\n### Le plan d'action\n\n**Phase 1 (semaine 1-2)** : enrichissement JSON-LD sur les 2 000 pages produit à plus fort trafic AI (identifiées via les logs). Le template JSON-LD est mis à jour dans le composant `ProductPage.tsx` avec le schéma complet montré plus haut. Coût : 3 jours de développement.\n\n**Phase 2 (semaine 3-4)** : déploiement de l'endpoint API `/api/products/[category]` avec documentation OpenAPI. Configuration du rate-limiting à 100 requêtes/minute par IP pour les bots identifiés, avec un burst de 200.\n\n**Phase 3 (semaine 5-8)** : extension du JSON-LD aux 10 000 pages produit restantes via un script de migration batch. Monitoring continu des champs structurés pour détecter toute régression post-déploiement.\n\n### Les résultats après 60 jours\n\nLe volume de requêtes AI agents passe de 68 500 à 112 000/mois (+63%). Plus intéressant : les requêtes se concentrent désormais sur les endpoints API plutôt que les pages HTML, réduisant la charge serveur par requête. Le taux de rebond des visites référées par des plateformes AI (identifiable via le referrer ou l'UTM) baisse de 45% — les agents envoient des utilisateurs sur la bonne page du premier coup.\n\nCe scénario illustre un point clé de ce que décrit Slobodan Manic : rendre votre site machine-readable n'est pas un projet cosmétique. C'est un avantage compétitif mesurable quand [la recherche devient agentique](/blog/google-s-task-based-agentic-search-is-disrupting-seo-today-not-tomorrow-via-sejournal-martinibuster).\n\n## Contrôler l'accès : robots.txt et rate-limiting pour les AI agents\n\nL'ouverture aux agents ne signifie pas l'ouverture totale et inconditionnelle. Vous devez contrôler qui accède à quoi, à quelle fréquence.\n\n### Configuration robots.txt granulaire\n\n```nginx\n# robots.txt — contrôle granulaire par type de bot\n\n# Googlebot — accès complet, comportement connu\nUser-agent: Googlebot\nAllow: /\n\n# AI Agents — accès aux pages produit et à l'API, pas au back-office\nUser-agent: GPTBot\nAllow: /produits/\nAllow: /api/products/\nAllow: /guides/\nDisallow: /compte/\nDisallow: /panier/\nDisallow: /admin/\nCrawl-delay: 2\n\nUser-agent: ClaudeBot\nAllow: /produits/\nAllow: /api/products/\nAllow: /guides/\nDisallow: /compte/\nDisallow: /panier/\nCrawl-delay: 2\n\nUser-agent: PerplexityBot\nAllow: /produits/\nAllow: /api/products/\nAllow: /guides/\nDisallow: /compte/\nDisallow: /panier/\nCrawl-delay: 3\n\n# Bots AI non identifiés ou non souhaités\nUser-agent: CCBot\nDisallow: /\n\nUser-agent: Bytespider\nDisallow: /\n```\n\nLe `Crawl-delay` n'est pas respecté par tous les bots (Googlebot l'ignore), mais les agents d'OpenAI et Anthropic le respectent généralement. C'est votre premier levier de protection.\n\n### Rate-limiting côté serveur\n\nLe `robots.txt` est une convention, pas une contrainte technique. Pour une protection réelle, configurez un rate-limiting au niveau de votre reverse proxy. Exemple avec Nginx :\n\n```nginx\n# /etc/nginx/conf.d/ai-agents-ratelimit.conf\n\n# Définition des zones de rate-limiting par type de bot\nmap $http_user_agent $ai_agent_zone {\n    default          \"\";\n    \"~*GPTBot\"       \"gptbot\";\n    \"~*ClaudeBot\"    \"claudebot\";\n    \"~*PerplexityBot\" \"perplexitybot\";\n}\n\n# 2 requêtes/seconde par bot, burst de 20\nlimit_req_zone $ai_agent_zone zone=ai_agents:10m rate=2r/s;\n\nserver {\n    listen 443 ssl http2;\n    server_name audioshop.fr;\n\n    # Rate-limiting sur les endpoints exposés aux agents\n    location /api/products/ {\n        limit_req zone=ai_agents burst=20 nodelay;\n        limit_req_status 429;\n        \n        # Headers pour signaler les limites aux agents bien élevés\n        add_header X-RateLimit-Limit \"120\" always;\n        add_header X-RateLimit-Remaining $limit_req_status always;\n        add_header Retry-After \"30\" always;\n        \n        proxy_pass http://nextjs_upstream;\n    }\n\n    location /produits/ {\n        limit_req zone=ai_agents burst=10 nodelay;\n        limit_req_status 429;\n        proxy_pass http://nextjs_upstream;\n    }\n}\n```\n\nLe `429 Too Many Requests` avec un header `Retry-After` est le signal standard que les agents AI bien implémentés respectent. Sans cette protection, un agent mal configuré peut envoyer des centaines de requêtes par seconde et impacter l'expérience de vos vrais utilisateurs.\n\n## Au-delà du HTML : les signaux machine-first que les agents cherchent\n\nLe HTML structuré et les API sont les fondations. Mais l'architecture machine-first comporte d'autres couches que beaucoup d'équipes négligent.\n\n### Le contenu sémantiquement clair\n\nUn AI agent qui doit répondre à \"quel est le meilleur casque à réduction de bruit sous 300€ ?\" va chercher des pages qui contiennent une réponse structurée à cette question — pas un mur de texte SEO-optimisé avec le mot-clé répété 47 fois.\n\nLe travail d'[optimisation pour les moteurs de réponse IA](/blog/optimiser-pour-les-moteurs-de-reponse-ia) converge ici avec l'architecture machine-first : des réponses factuelles, des comparaisons tabulaires, des données chiffrées accessibles.\n\nCela veut dire concrètement : vos pages de comparatif doivent contenir des `\u003Ctable>` avec des headers clairs, pas des listes à puces visuellement jolies mais sémantiquement ambiguës. Vos FAQs doivent utiliser le balisage `FAQPage` de Schema.org. Vos guides d'achat doivent isoler les recommandations dans des structures identifiables.\n\n### La fraîcheur des données comme signal de confiance\n\nUn AI agent confronté à deux sources pour le prix d'un produit choisira celle qui indique une date de dernière mise à jour. Le champ `lastUpdated` dans votre API, le `dateModified` dans votre JSON-LD, le `Last-Modified` dans vos headers HTTP — ces trois signaux convergent pour indiquer à l'agent que vos données sont fiables.\n\nC'est aussi la raison pour laquelle un JSON-LD avec un `priceValidUntil` expiré depuis 6 mois envoie un signal catastrophique. L'agent ne sait pas si le prix est encore valide. Il peut décider de ne pas recommander votre produit.\n\n### Le lien avec la homepage comme hub sémantique\n\nL'importance de la [homepage comme point d'entrée sémantique](/blog/your-homepage-matters-again-for-seo-here-s-why) prend une dimension supplémentaire dans le contexte machine-first. Les AI agents qui découvrent votre site commencent souvent par la homepage pour comprendre votre périmètre d'activité, votre positionnement, et les types de données disponibles. Une homepage qui contient un JSON-LD `Organization` complet avec `sameAs` (liens vers vos profils sociaux et fiches d'entreprise) et un `WebSite` avec `potentialAction` de type `SearchAction` donne aux agents un point d'entrée structuré.\n\n## Ce qui change dans votre workflow SEO technique\n\nL'architecture machine-first ne remplace pas le SEO classique. Elle s'y superpose. Les fondamentaux — crawlabilité, SSR, performance, canonicals — restent indispensables. [Googlebot reste Googlebot](/blog/google-lists-9-scenarios-that-explain-how-it-picks-canonical-urls-via-sejournal-martinibuster).\n\nMais votre checklist technique doit maintenant inclure :\n\n**Audit des données structurées** : pas seulement \"est-ce que le JSON-LD est valide ?\", mais \"est-ce qu'il contient toutes les données qu'un agent autonome aurait besoin pour prendre une décision ?\". Screaming Frog permet d'extraire le JSON-LD à grande échelle via l'extraction custom — configurez une extraction regex pour vérifier la présence de `shippingDetails` et `hasMerchantReturnPolicy` sur vos pages produit.\n\n**Analyse des logs par user-agent AI** : segmentez vos logs pour identifier quels bots AI crawlent quelles sections, à quelle fréquence, et avec quels patterns. C'est votre [analyse de logs adaptée aux crawlers IA](/blog/why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility) — sans elle, vous pilotez à l'aveugle.\n\n**Monitoring des régressions structurées** : un déploiement qui casse votre JSON-LD est invisible dans Google Search Console (le trafic organique ne chute pas immédiatement). Mais les agents AI cessent instantanément de consommer vos données. Seogard détecte ce type de régression en temps réel — un champ structuré qui disparaît ou change de format sur un lot de pages déclenche une alerte avant que l'impact ne soit visible dans vos métriques de trafic.\n\n**Tests multi-agent** : utilisez Chrome DevTools pour simuler différents user-agents AI et vérifier que vos pages servent le même contenu. Certaines configurations CDN ou WAF bloquent par défaut les bots non reconnus — vérifiez que vos endpoints API répondent correctement à GPTBot, ClaudeBot, et PerplexityBot.\n\nLa transition vers le machine-first est un chantier d'infrastructure, pas un one-shot. Les sites qui l'entament maintenant — pendant que [l'agentic AI se structure](/blog/dell-agentic-ai-is-growing-but-search-still-wins) mais n'est pas encore dominante — auront un avantage structurel quand [la recherche agentique de Google](/blog/agentic-engine-optimization-google-ai-director-outlines-new-content-playbook) deviendra le mode par défaut. Le coût de l'inaction, c'est de devenir invisible non pas dans un index, mais dans les décisions que des agents prennent pour vos clients potentiels.","https://seogard.io/blog/machine-first-architecture-ai-agents-are-here-and-your-website-isn-t-ready-says-no-hacks-podcast-host-via-sejournal-theshelleywalsh","Actualités SEO","2026-04-17T10:03:11.013Z","2026-04-17","Les AI agents ne crawlent pas comme Googlebot. Architecture, données structurées, API endpoints : guide technique pour rendre votre site lisible par les machines autonomes.","\u003Cp>Googlebot indexe vos pages. Un AI agent les \u003Cem>consomme\u003C/em> — il extrait un prix, compare une disponibilité, déclenche un achat. La distinction est fondamentale : l'un construit un index, l'autre exécute une tâche pour un utilisateur. Et la majorité des sites sont architecturés exclusivement pour le premier cas.\u003C/p>\n\u003Cp>Slobodan Manic, dans le podcast \u003Ca href=\"https://www.searchenginejournal.com/machine-first-architecture-ai-agents-are-here-and-your-website-isnt-ready-says-nohacks-podcast-host/571898/\">NoHacks relayé par Search Engine Journal\u003C/a>, pose un diagnostic clair : les sites web sont construits pour des humains qui naviguent et des crawlers qui indexent, pas pour des agents autonomes qui exécutent des workflows. Ce constat ouvre un chantier d'architecture technique que la plupart des équipes SEO n'ont pas encore entamé.\u003C/p>\n\u003Ch2>Le décalage entre l'architecture web actuelle et les besoins des AI agents\u003C/h2>\n\u003Cp>Un crawler classique — Googlebot, Bingbot — suit un schéma prévisible : il découvre des URLs via le sitemap ou les liens internes, fetch le HTML (et éventuellement exécute le JavaScript), extrait le contenu textuel et les métadonnées, puis passe à l'URL suivante. Le rythme est séquentiel, patient, tolérant.\u003C/p>\n\u003Cp>Un AI agent fonctionne différemment. Il reçoit une instruction de l'utilisateur (\"trouve-moi un vol Paris-Lisbonne le 15 mai sous 200€ avec bagage cabine inclus\"), décompose cette instruction en sous-tâches, et interroge potentiellement des dizaines de sources en parallèle. Il n'a pas le temps de parser du HTML sémantiquement ambigu. Il a besoin de données structurées, d'endpoints prévisibles, de réponses machine-readable.\u003C/p>\n\u003Cp>Le problème concret : la plupart des sites e-commerce servent leurs données produit dans du HTML templated avec des classes CSS comme \u003Ccode>product-price\u003C/code>, \u003Ccode>product-title\u003C/code>, etc. Un humain voit la page et comprend. Googlebot extrait le contenu textuel et s'en sort grâce à des heuristiques puissantes. Un AI agent, lui, cherche une donnée structurée normalisée — et si votre JSON-LD est incomplet ou absent, il passe son tour.\u003C/p>\n\u003Ch3>Ce que les AI agents attendent réellement\u003C/h3>\n\u003Cp>D'après les patterns observés dans les logs des bots d'\u003Ca href=\"/blog/openai-meta-bytedance-lead-ai-bot-traffic-in-publishing-via-sejournal-mattgsouthern\">OpenAI, Meta et ByteDance\u003C/a>, les AI agents montrent trois comportements distincts des crawlers classiques :\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Extraction ciblée\u003C/strong> : ils ne crawlent pas tout le site. Ils ciblent des pages spécifiques correspondant à la requête de l'utilisateur.\u003C/li>\n\u003Cli>\u003Cstrong>Parsing structuré d'abord\u003C/strong> : ils cherchent JSON-LD, microdata, ou des API endpoints avant de tenter un parsing HTML.\u003C/li>\n\u003Cli>\u003Cstrong>Vitesse d'exécution\u003C/strong> : un agent qui compare 40 sites ne peut pas attendre 3 secondes de rendering JavaScript par page.\u003C/li>\n\u003C/ol>\n\u003Cp>Ce dernier point rejoint directement la problématique du \u003Ca href=\"/blog/rendering-budget-de-google-combien-de-javascript-est-trop\">rendering budget\u003C/a> : si Googlebot alloue déjà un budget limité au rendering JS, imaginez un AI agent qui doit traiter des centaines de pages en quelques secondes.\u003C/p>\n\u003Ch2>Structurer vos données pour la consommation machine\u003C/h2>\n\u003Cp>Le JSON-LD n'est pas nouveau. Mais l'exigence de complétude change radicalement quand le consommateur est un agent autonome plutôt qu'un moteur de recherche.\u003C/p>\n\u003Ch3>Au-delà du minimum syndical Schema.org\u003C/h3>\n\u003Cp>La plupart des implémentations Schema.org en production sont minimalistes : \u003Ccode>Product\u003C/code> avec \u003Ccode>name\u003C/code>, \u003Ccode>price\u003C/code>, \u003Ccode>availability\u003C/code>. Suffisant pour les rich snippets Google. Insuffisant pour un AI agent qui doit prendre une décision d'achat.\u003C/p>\n\u003Cp>Voici un exemple de JSON-LD complet orienté machine-first pour une page produit e-commerce :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#B392F0\"> type\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"application/ld+json\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"@context\": \"https://schema.org\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"@type\": \"Product\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"name\": \"Casque Sony WH-1000XM5\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"sku\": \"WH1000XM5B\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"gtin13\": \"4548736132597\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"brand\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"Brand\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"name\": \"Sony\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"description\": \"Casque sans fil à réduction de bruit active, Bluetooth 5.2, autonomie 30h\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"image\": [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"https://audioshop.fr/images/wh1000xm5-front.webp\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"https://audioshop.fr/images/wh1000xm5-side.webp\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  ],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"offers\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"Offer\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"url\": \"https://audioshop.fr/casques/sony-wh-1000xm5\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"priceCurrency\": \"EUR\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"price\": \"349.00\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"priceValidUntil\": \"2026-06-30\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"availability\": \"https://schema.org/InStock\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"itemCondition\": \"https://schema.org/NewCondition\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"seller\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"Organization\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"name\": \"AudioShop\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"shippingDetails\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"OfferShippingDetails\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"shippingRate\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"@type\": \"MonetaryAmount\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"value\": \"0.00\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"currency\": \"EUR\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"deliveryTime\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"@type\": \"ShippingDeliveryTime\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"handlingTime\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"@type\": \"QuantitativeValue\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"minValue\": 0,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"maxValue\": 1,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"unitCode\": \"DAY\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"transitTime\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"@type\": \"QuantitativeValue\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"minValue\": 1,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"maxValue\": 3,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">          \"unitCode\": \"DAY\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"shippingDestination\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"@type\": \"DefinedRegion\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \"addressCountry\": \"FR\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"hasMerchantReturnPolicy\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"MerchantReturnPolicy\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"applicableCountry\": \"FR\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"returnPolicyCategory\": \"https://schema.org/MerchantReturnFiniteReturnWindow\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"merchantReturnDays\": 30,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"returnMethod\": \"https://schema.org/ReturnByMail\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"returnFees\": \"https://schema.org/FreeReturn\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"aggregateRating\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"AggregateRating\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"ratingValue\": \"4.7\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"reviewCount\": \"2847\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"additionalProperty\": [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"PropertyValue\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"name\": \"Autonomie\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"value\": \"30h\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"PropertyValue\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"name\": \"Connectivité\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"value\": \"Bluetooth 5.2, NFC\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"PropertyValue\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"name\": \"Poids\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"value\": \"250g\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  ]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>La différence avec une implémentation classique : \u003Ccode>shippingDetails\u003C/code>, \u003Ccode>hasMerchantReturnPolicy\u003C/code>, \u003Ccode>additionalProperty\u003C/code> pour les specs techniques, \u003Ccode>gtin13\u003C/code> pour l'identification univoque. Un AI agent qui compare des casques audio peut maintenant extraire programmatiquement le prix, le délai de livraison, la politique de retour et les specs — sans parser un seul élément HTML.\u003C/p>\n\u003Ch3>Valider et monitorer la complétude\u003C/h3>\n\u003Cp>Le piège classique : votre JSON-LD est complet au déploiement, puis une mise à jour du CMS casse silencieusement le champ \u003Ccode>availability\u003C/code> ou supprime le bloc \u003Ccode>shippingDetails\u003C/code>. Vous ne le découvrez que quand votre trafic AI chute.\u003C/p>\n\u003Cp>Utilisez le \u003Ca href=\"https://search.google.com/test/rich-results\">Rich Results Test\u003C/a> de Google pour la validation initiale, mais ce n'est pas suffisant pour un monitoring continu sur un catalogue de milliers de pages. Un outil de monitoring comme Seogard détecte ce type de régression dès qu'elle se produit — un champ JSON-LD qui disparaît sur 500 pages produit après un déploiement, c'est le genre de signal qu'aucun audit manuel ne capte à temps.\u003C/p>\n\u003Ch2>L'architecture API-first : exposer vos données aux agents\u003C/h2>\n\u003Cp>Le JSON-LD dans le HTML est une première étape. Mais l'architecture machine-first va plus loin : elle expose des endpoints dédiés que les agents peuvent consommer directement, sans avoir à parser du HTML.\u003C/p>\n\u003Ch3>Le cas des product feeds revisité\u003C/h3>\n\u003Cp>Les \u003Ca href=\"/blog/why-product-feeds-shouldn-t-be-the-most-ignored-seo-system-in-ecommerce\">product feeds en e-commerce\u003C/a> sont historiquement utilisés pour Google Merchant Center. Dans une architecture machine-first, ils deviennent un point d'entrée primaire pour les AI agents.\u003C/p>\n\u003Cp>Mais le feed XML classique n'est pas idéal pour la consommation par agents. Un endpoint JSON paginé, filtrable, et documenté via une spécification OpenAPI est nettement plus exploitable :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Exemple d'endpoint Next.js API Route pour exposition machine-first\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// /pages/api/products/[category].ts\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#F97583\"> type\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { NextApiRequest, NextApiResponse } \u003C/span>\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'next'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { getProductsByCategory } \u003C/span>\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '@/lib/products'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">interface\u003C/span>\u003Cspan style=\"color:#B392F0\"> MachineProduct\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  sku\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  gtin\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  name\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  price\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { \u003C/span>\u003Cspan style=\"color:#FFAB70\">amount\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> number\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#FFAB70\">currency\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> };\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  availability\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'in_stock'\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'out_of_stock'\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'preorder'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  shipping\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">    free\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> boolean\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">    estimatedDays\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { \u003C/span>\u003Cspan style=\"color:#FFAB70\">min\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> number\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#FFAB70\">max\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> number\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> };\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">    countries\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  };\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  returnPolicy\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">    days\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> number\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">    freeReturn\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> boolean\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  };\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  specs\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> Record\u003C/span>\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#79B8FF\">string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  url\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  lastUpdated\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">// ISO 8601\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#F97583\"> async\u003C/span>\u003Cspan style=\"color:#F97583\"> function\u003C/span>\u003Cspan style=\"color:#B392F0\"> handler\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  req\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> NextApiRequest\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  res\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> NextApiResponse\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { \u003C/span>\u003Cspan style=\"color:#79B8FF\">category\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> } \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> req.query;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> page\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#B392F0\"> parseInt\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(req.query.page \u003C/span>\u003Cspan style=\"color:#F97583\">as\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> limit\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> Math.\u003C/span>\u003Cspan style=\"color:#B392F0\">min\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#B392F0\">parseInt\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(req.query.limit \u003C/span>\u003Cspan style=\"color:#F97583\">as\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  // Identifier l'agent pour le logging\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> userAgent\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> req.headers[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'user-agent'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> isAIAgent\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> /\u003C/span>\u003Cspan style=\"color:#DBEDFF\">GPTBot\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">ChatGPT\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">ClaudeBot\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">PerplexityBot\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">Applebot-Extended\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#F97583\">i\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:#B392F0\">test\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(userAgent);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (isAIAgent) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    // Log pour analyse — combien d'agents consomment vos données ?\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    console.\u003C/span>\u003Cspan style=\"color:#B392F0\">log\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">`AI Agent request: ${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">userAgent\u003C/span>\u003Cspan style=\"color:#9ECBFF\">} — ${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">category\u003C/span>\u003Cspan style=\"color:#9ECBFF\">} page ${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">page\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { \u003C/span>\u003Cspan style=\"color:#79B8FF\">products\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">total\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> } \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#B392F0\"> getProductsByCategory\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    category \u003C/span>\u003Cspan style=\"color:#F97583\">as\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    page, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    limit\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> machineProducts\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> MachineProduct\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[] \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> products.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#FFAB70\">p\u003C/span>\u003Cspan style=\"color:#F97583\"> =>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    sku: p.sku,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    gtin: p.gtin13,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    name: p.name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    price: { amount: p.price, currency: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'EUR'\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    availability: p.stock \u003C/span>\u003Cspan style=\"color:#F97583\">>\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#F97583\"> ?\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'in_stock'\u003C/span>\u003Cspan style=\"color:#F97583\"> :\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'out_of_stock'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    shipping: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      free: p.price \u003C/span>\u003Cspan style=\"color:#F97583\">>=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      estimatedDays: { min: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, max: \u003C/span>\u003Cspan style=\"color:#79B8FF\">3\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      countries: [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'FR'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'BE'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'CH'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    returnPolicy: { days: \u003C/span>\u003Cspan style=\"color:#79B8FF\">30\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, freeReturn: \u003C/span>\u003Cspan style=\"color:#79B8FF\">true\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    specs: p.specifications,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    url: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">`https://audioshop.fr/produits/${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">p\u003C/span>\u003Cspan style=\"color:#9ECBFF\">.\u003C/span>\u003Cspan style=\"color:#E1E4E8\">slug\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    lastUpdated: p.updatedAt.\u003C/span>\u003Cspan style=\"color:#B392F0\">toISOString\u003C/span>\u003Cspan style=\"color:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  res.\u003C/span>\u003Cspan style=\"color:#B392F0\">setHeader\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Cache-Control'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'public, s-maxage=3600, stale-while-revalidate=600'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  res.\u003C/span>\u003Cspan style=\"color:#B392F0\">status\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">200\u003C/span>\u003Cspan style=\"color:#E1E4E8\">).\u003C/span>\u003Cspan style=\"color:#B392F0\">json\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    data: machineProducts,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    pagination: { page, limit, total, pages: Math.\u003C/span>\u003Cspan style=\"color:#B392F0\">ceil\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(total \u003C/span>\u003Cspan style=\"color:#F97583\">/\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> limit) },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    _links: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      self: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">`/api/products/${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">category\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}?page=${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">page\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}&#x26;limit=${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">limit\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      next: page \u003C/span>\u003Cspan style=\"color:#F97583\">*\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> limit \u003C/span>\u003Cspan style=\"color:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> total \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        ?\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> `/api/products/${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">category\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}?page=${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">page\u003C/span>\u003Cspan style=\"color:#F97583\"> +\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}&#x26;limit=${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">limit\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        :\u003C/span>\u003Cspan style=\"color:#79B8FF\"> null\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce pattern offre plusieurs avantages : les AI agents n'ont pas besoin de parser du HTML, la réponse est typée et prévisible, la pagination permet de consommer de gros catalogues sans surcharger le serveur, et le header \u003Ccode>Cache-Control\u003C/code> évite que 50 agents en parallèle ne fassent tomber votre infra.\u003C/p>\n\u003Ch3>Déclarer vos endpoints aux agents\u003C/h3>\n\u003Cp>Un AI agent ne va pas deviner qu'un endpoint \u003Ccode>/api/products/casques\u003C/code> existe. Deux mécanismes émergent pour la découverte :\u003C/p>\n\u003Cp>Le fichier \u003Ccode>/.well-known/ai-plugin.json\u003C/code> (inspiré du format OpenAI) et le \u003Ccode>robots.txt\u003C/code> enrichi. En attendant qu'un standard se stabilise, le plus pragmatique reste de lier votre documentation API depuis votre sitemap et vos pages HTML via un \u003Ccode>&#x3C;link>\u003C/code> :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">head\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  &#x3C;!-- Découverte machine de l'API produits -->\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">link\u003C/span>\u003Cspan style=\"color:#B392F0\"> rel\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"alternate\"\u003C/span>\u003Cspan style=\"color:#B392F0\"> type\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"application/json\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">        href\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"https://audioshop.fr/api/products/casques\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">        title\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"Machine-readable product data\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> />\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  &#x3C;!-- Schéma OpenAPI pour la documentation -->\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">link\u003C/span>\u003Cspan style=\"color:#B392F0\"> rel\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"describedby\"\u003C/span>\u003Cspan style=\"color:#B392F0\"> type\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"application/openapi+json\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">        href\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"https://audioshop.fr/api/openapi.json\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> />\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">head\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce n'est pas encore un standard universel, mais les agents qui implémentent la découverte de sources cherchent précisément ce type de signaux.\u003C/p>\n\u003Ch2>Scénario concret : un e-commerce de 12 000 pages face aux AI agents\u003C/h2>\n\u003Cp>Prenons AudioShop, un e-commerce spécialisé audio avec 12 000 pages produit, 800 pages catégories, et 200 pages de contenu éditorial. Le site tourne sur Next.js avec SSR, hébergé sur Vercel.\u003C/p>\n\u003Ch3>Le diagnostic initial\u003C/h3>\n\u003Cp>L'équipe SEO analyse ses \u003Ca href=\"/blog/why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility\">logs serveur\u003C/a> sur les 90 derniers jours et découvre :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>GPTBot\u003C/strong> : 45 000 requêtes/mois, concentrées sur les pages catégories\u003C/li>\n\u003Cli>\u003Cstrong>ClaudeBot\u003C/strong> : 12 000 requêtes/mois, principalement les pages produit\u003C/li>\n\u003Cli>\u003Cstrong>PerplexityBot\u003C/strong> : 8 000 requêtes/mois, les guides d'achat éditoriaux\u003C/li>\n\u003Cli>\u003Cstrong>Applebot-Extended\u003C/strong> : 3 500 requêtes/mois (Apple Intelligence)\u003C/li>\n\u003C/ul>\n\u003Cp>Total : ~68 500 requêtes AI agents par mois, soit environ 15% du volume total de crawl. Ce ratio est cohérent avec ce que rapportent les éditeurs dans le secteur publishing.\u003C/p>\n\u003Cp>Le problème : le JSON-LD des pages produit ne contient que \u003Ccode>name\u003C/code>, \u003Ccode>price\u003C/code>, et \u003Ccode>availability\u003C/code>. Pas de \u003Ccode>shippingDetails\u003C/code>, pas de \u003Ccode>gtin\u003C/code>, pas de specs techniques structurées. Les AI agents récupèrent le prix, mais n'ont aucun moyen machine-readable de comparer les délais de livraison ou les politiques de retour — des critères déterminants dans la décision d'achat que l'agent exécute pour l'utilisateur.\u003C/p>\n\u003Ch3>Le plan d'action\u003C/h3>\n\u003Cp>\u003Cstrong>Phase 1 (semaine 1-2)\u003C/strong> : enrichissement JSON-LD sur les 2 000 pages produit à plus fort trafic AI (identifiées via les logs). Le template JSON-LD est mis à jour dans le composant \u003Ccode>ProductPage.tsx\u003C/code> avec le schéma complet montré plus haut. Coût : 3 jours de développement.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 2 (semaine 3-4)\u003C/strong> : déploiement de l'endpoint API \u003Ccode>/api/products/[category]\u003C/code> avec documentation OpenAPI. Configuration du rate-limiting à 100 requêtes/minute par IP pour les bots identifiés, avec un burst de 200.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 3 (semaine 5-8)\u003C/strong> : extension du JSON-LD aux 10 000 pages produit restantes via un script de migration batch. Monitoring continu des champs structurés pour détecter toute régression post-déploiement.\u003C/p>\n\u003Ch3>Les résultats après 60 jours\u003C/h3>\n\u003Cp>Le volume de requêtes AI agents passe de 68 500 à 112 000/mois (+63%). Plus intéressant : les requêtes se concentrent désormais sur les endpoints API plutôt que les pages HTML, réduisant la charge serveur par requête. Le taux de rebond des visites référées par des plateformes AI (identifiable via le referrer ou l'UTM) baisse de 45% — les agents envoient des utilisateurs sur la bonne page du premier coup.\u003C/p>\n\u003Cp>Ce scénario illustre un point clé de ce que décrit Slobodan Manic : rendre votre site machine-readable n'est pas un projet cosmétique. C'est un avantage compétitif mesurable quand \u003Ca href=\"/blog/google-s-task-based-agentic-search-is-disrupting-seo-today-not-tomorrow-via-sejournal-martinibuster\">la recherche devient agentique\u003C/a>.\u003C/p>\n\u003Ch2>Contrôler l'accès : robots.txt et rate-limiting pour les AI agents\u003C/h2>\n\u003Cp>L'ouverture aux agents ne signifie pas l'ouverture totale et inconditionnelle. Vous devez contrôler qui accède à quoi, à quelle fréquence.\u003C/p>\n\u003Ch3>Configuration robots.txt granulaire\u003C/h3>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># robots.txt — contrôle granulaire par type de bot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Googlebot — accès complet, comportement connu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: \u003C/span>\u003Cspan style=\"color:#F97583\">Googlebot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># AI Agents — accès aux pages produit et à l'API, pas au back-office\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: \u003C/span>\u003Cspan style=\"color:#F97583\">GPTBot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /produits/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /\u003C/span>\u003Cspan style=\"color:#79B8FF\">api/products\u003C/span>\u003Cspan style=\"color:#E1E4E8\">/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /guides/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /compte/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /panier/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /admin/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Crawl-delay: 2\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: ClaudeBot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /produits/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /api/products/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /guides/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /compte/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /panier/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Crawl-delay: 2\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: PerplexityBot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /produits/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /api/products/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Allow: /guides/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /compte/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /panier/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Crawl-delay: 3\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Bots AI non identifiés ou non souhaités\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: CCBot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">User-agent: Bytespider\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">Disallow: /\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Le \u003Ccode>Crawl-delay\u003C/code> n'est pas respecté par tous les bots (Googlebot l'ignore), mais les agents d'OpenAI et Anthropic le respectent généralement. C'est votre premier levier de protection.\u003C/p>\n\u003Ch3>Rate-limiting côté serveur\u003C/h3>\n\u003Cp>Le \u003Ccode>robots.txt\u003C/code> est une convention, pas une contrainte technique. Pour une protection réelle, configurez un rate-limiting au niveau de votre reverse proxy. Exemple avec Nginx :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># /etc/nginx/conf.d/ai-agents-ratelimit.conf\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Définition des zones de rate-limiting par type de bot\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $\u003C/span>\u003Cspan style=\"color:#FFAB70\">http_user_agent\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $ai_agent_zone {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    default\u003C/span>\u003Cspan style=\"color:#9ECBFF\">          \"\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*GPTBot\"\u003C/span>\u003Cspan style=\"color:#9ECBFF\">       \"gptbot\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*ClaudeBot\"\u003C/span>\u003Cspan style=\"color:#9ECBFF\">    \"claudebot\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*PerplexityBot\"\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"perplexitybot\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># 2 requêtes/seconde par bot, burst de 20\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">limit_req_zone \u003C/span>\u003Cspan style=\"color:#E1E4E8\">$ai_agent_zone zone=ai_agents:10m rate=2r/s;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">443\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ssl http2;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">audioshop.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Rate-limiting sur les endpoints exposés aux agents\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    location\u003C/span>\u003Cspan style=\"color:#B392F0\"> /api/products/ \u003C/span>\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        limit_req \u003C/span>\u003Cspan style=\"color:#E1E4E8\">zone=ai_agents burst=20 nodelay;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        limit_req_status \u003C/span>\u003Cspan style=\"color:#79B8FF\">429\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">        # Headers pour signaler les limites aux agents bien élevés\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">X-RateLimit-Limit \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"120\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> always;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">X-RateLimit-Remaining $limit_req_status always;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">Retry-After \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"30\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> always;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        proxy_pass \u003C/span>\u003Cspan style=\"color:#E1E4E8\">http://nextjs_upstream;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    location\u003C/span>\u003Cspan style=\"color:#B392F0\"> /produits/ \u003C/span>\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        limit_req \u003C/span>\u003Cspan style=\"color:#E1E4E8\">zone=ai_agents burst=10 nodelay;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        limit_req_status \u003C/span>\u003Cspan style=\"color:#79B8FF\">429\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        proxy_pass \u003C/span>\u003Cspan style=\"color:#E1E4E8\">http://nextjs_upstream;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Le \u003Ccode>429 Too Many Requests\u003C/code> avec un header \u003Ccode>Retry-After\u003C/code> est le signal standard que les agents AI bien implémentés respectent. Sans cette protection, un agent mal configuré peut envoyer des centaines de requêtes par seconde et impacter l'expérience de vos vrais utilisateurs.\u003C/p>\n\u003Ch2>Au-delà du HTML : les signaux machine-first que les agents cherchent\u003C/h2>\n\u003Cp>Le HTML structuré et les API sont les fondations. Mais l'architecture machine-first comporte d'autres couches que beaucoup d'équipes négligent.\u003C/p>\n\u003Ch3>Le contenu sémantiquement clair\u003C/h3>\n\u003Cp>Un AI agent qui doit répondre à \"quel est le meilleur casque à réduction de bruit sous 300€ ?\" va chercher des pages qui contiennent une réponse structurée à cette question — pas un mur de texte SEO-optimisé avec le mot-clé répété 47 fois.\u003C/p>\n\u003Cp>Le travail d'\u003Ca href=\"/blog/optimiser-pour-les-moteurs-de-reponse-ia\">optimisation pour les moteurs de réponse IA\u003C/a> converge ici avec l'architecture machine-first : des réponses factuelles, des comparaisons tabulaires, des données chiffrées accessibles.\u003C/p>\n\u003Cp>Cela veut dire concrètement : vos pages de comparatif doivent contenir des \u003Ccode>&#x3C;table>\u003C/code> avec des headers clairs, pas des listes à puces visuellement jolies mais sémantiquement ambiguës. Vos FAQs doivent utiliser le balisage \u003Ccode>FAQPage\u003C/code> de Schema.org. Vos guides d'achat doivent isoler les recommandations dans des structures identifiables.\u003C/p>\n\u003Ch3>La fraîcheur des données comme signal de confiance\u003C/h3>\n\u003Cp>Un AI agent confronté à deux sources pour le prix d'un produit choisira celle qui indique une date de dernière mise à jour. Le champ \u003Ccode>lastUpdated\u003C/code> dans votre API, le \u003Ccode>dateModified\u003C/code> dans votre JSON-LD, le \u003Ccode>Last-Modified\u003C/code> dans vos headers HTTP — ces trois signaux convergent pour indiquer à l'agent que vos données sont fiables.\u003C/p>\n\u003Cp>C'est aussi la raison pour laquelle un JSON-LD avec un \u003Ccode>priceValidUntil\u003C/code> expiré depuis 6 mois envoie un signal catastrophique. L'agent ne sait pas si le prix est encore valide. Il peut décider de ne pas recommander votre produit.\u003C/p>\n\u003Ch3>Le lien avec la homepage comme hub sémantique\u003C/h3>\n\u003Cp>L'importance de la \u003Ca href=\"/blog/your-homepage-matters-again-for-seo-here-s-why\">homepage comme point d'entrée sémantique\u003C/a> prend une dimension supplémentaire dans le contexte machine-first. Les AI agents qui découvrent votre site commencent souvent par la homepage pour comprendre votre périmètre d'activité, votre positionnement, et les types de données disponibles. Une homepage qui contient un JSON-LD \u003Ccode>Organization\u003C/code> complet avec \u003Ccode>sameAs\u003C/code> (liens vers vos profils sociaux et fiches d'entreprise) et un \u003Ccode>WebSite\u003C/code> avec \u003Ccode>potentialAction\u003C/code> de type \u003Ccode>SearchAction\u003C/code> donne aux agents un point d'entrée structuré.\u003C/p>\n\u003Ch2>Ce qui change dans votre workflow SEO technique\u003C/h2>\n\u003Cp>L'architecture machine-first ne remplace pas le SEO classique. Elle s'y superpose. Les fondamentaux — crawlabilité, SSR, performance, canonicals — restent indispensables. \u003Ca href=\"/blog/google-lists-9-scenarios-that-explain-how-it-picks-canonical-urls-via-sejournal-martinibuster\">Googlebot reste Googlebot\u003C/a>.\u003C/p>\n\u003Cp>Mais votre checklist technique doit maintenant inclure :\u003C/p>\n\u003Cp>\u003Cstrong>Audit des données structurées\u003C/strong> : pas seulement \"est-ce que le JSON-LD est valide ?\", mais \"est-ce qu'il contient toutes les données qu'un agent autonome aurait besoin pour prendre une décision ?\". Screaming Frog permet d'extraire le JSON-LD à grande échelle via l'extraction custom — configurez une extraction regex pour vérifier la présence de \u003Ccode>shippingDetails\u003C/code> et \u003Ccode>hasMerchantReturnPolicy\u003C/code> sur vos pages produit.\u003C/p>\n\u003Cp>\u003Cstrong>Analyse des logs par user-agent AI\u003C/strong> : segmentez vos logs pour identifier quels bots AI crawlent quelles sections, à quelle fréquence, et avec quels patterns. C'est votre \u003Ca href=\"/blog/why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility\">analyse de logs adaptée aux crawlers IA\u003C/a> — sans elle, vous pilotez à l'aveugle.\u003C/p>\n\u003Cp>\u003Cstrong>Monitoring des régressions structurées\u003C/strong> : un déploiement qui casse votre JSON-LD est invisible dans Google Search Console (le trafic organique ne chute pas immédiatement). Mais les agents AI cessent instantanément de consommer vos données. Seogard détecte ce type de régression en temps réel — un champ structuré qui disparaît ou change de format sur un lot de pages déclenche une alerte avant que l'impact ne soit visible dans vos métriques de trafic.\u003C/p>\n\u003Cp>\u003Cstrong>Tests multi-agent\u003C/strong> : utilisez Chrome DevTools pour simuler différents user-agents AI et vérifier que vos pages servent le même contenu. Certaines configurations CDN ou WAF bloquent par défaut les bots non reconnus — vérifiez que vos endpoints API répondent correctement à GPTBot, ClaudeBot, et PerplexityBot.\u003C/p>\n\u003Cp>La transition vers le machine-first est un chantier d'infrastructure, pas un one-shot. Les sites qui l'entament maintenant — pendant que \u003Ca href=\"/blog/dell-agentic-ai-is-growing-but-search-still-wins\">l'agentic AI se structure\u003C/a> mais n'est pas encore dominante — auront un avantage structurel quand \u003Ca href=\"/blog/agentic-engine-optimization-google-ai-director-outlines-new-content-playbook\">la recherche agentique de Google\u003C/a> deviendra le mode par défaut. Le coût de l'inaction, c'est de devenir invisible non pas dans un index, mais dans les décisions que des agents prennent pour vos clients potentiels.\u003C/p>",null,12,[18,19,20,21,22],"machine-first architecture","AI agents","SEO technique","données structurées","agentic search","Machine-First Architecture : préparer votre site aux AI agents","Fri Apr 17 2026 10:03:11 GMT+0000 (Coordinated Universal Time)",[26,40,55],{"_id":27,"slug":28,"__v":6,"author":7,"canonical":29,"category":10,"createdAt":30,"date":12,"description":31,"image":15,"imageAlt":15,"readingTime":16,"tags":32,"title":38,"updatedAt":39},"69e1cce1aa6b273b0c7d7064","why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility","https://seogard.io/blog/why-log-file-analysis-matters-for-ai-crawlers-and-search-visibility","2026-04-17T06:02:09.095Z","Analysez vos logs serveur pour tracer les crawlers IA, identifier les pages ignorées et optimiser votre visibilité dans les moteurs de réponse.",[33,34,35,36,37],"log file analysis","AI crawlers","crawl budget","search visibility","bot monitoring","Log file analysis pour AI crawlers : détecter ce que les bots IA ignorent","Fri Apr 17 2026 06:02:09 GMT+0000 (Coordinated Universal Time)",{"_id":41,"slug":42,"__v":6,"author":7,"canonical":43,"category":10,"createdAt":44,"date":45,"description":46,"image":15,"imageAlt":15,"readingTime":16,"tags":47,"title":53,"updatedAt":54},"69e07b73aa6b273b0c6f9b74","google-search-console-glitch-gives-seos-a-scare-via-sejournal-martinibuster","https://seogard.io/blog/google-search-console-glitch-gives-seos-a-scare-via-sejournal-martinibuster","2026-04-16T06:02:27.256Z","2026-04-16","Analyse technique du bug Google Search Console qui a affolé les SEOs. Comment vérifier vos données, automatiser les alertes et éviter les faux positifs.",[48,49,50,51,52],"google search console","glitch","monitoring SEO","API GSC","données search","Bug GSC : quand un glitch déclenche la panique SEO","Thu Apr 16 2026 06:02:27 GMT+0000 (Coordinated Universal Time)",{"_id":56,"slug":57,"__v":6,"author":7,"canonical":58,"category":10,"createdAt":59,"date":45,"description":60,"image":15,"imageAlt":15,"readingTime":16,"tags":61,"title":66,"updatedAt":67},"69e0b3caaa6b273b0c9ca959","march-2026-google-core-update-more-volatile-than-december-here-s-what-changed","https://seogard.io/blog/march-2026-google-core-update-more-volatile-than-december-here-s-what-changed","2026-04-16T10:02:50.898Z","Le core update de mars 2026 a redistribué ~80% des top résultats. Analyse technique, données, code et stratégies de diagnostic pour les SEO avancés.",[62,63,64,20,65],"march 2026 google core update","core update","SERP volatility","Google algorithm","March 2026 Google Core Update : analyse technique des shifts","Thu Apr 16 2026 10:02:50 GMT+0000 (Coordinated Universal Time)"]