Runbooks & opérationsIntelligence / Spy : quelle variable débloque quoi

Intelligence / Spy : quelle variable débloque quoi

Une seule question : « je pose cette clé, qu'est-ce qui se remplit ? »

Une seule question : « je pose cette clé, qu'est-ce qui se remplit ? »

Le record canonique compte 150 champs répartis en 14 sections (src/services/algorithms/intelligence/canonical/sections.ts) : chiffres rendus par node scripts/intelligence-coverage.mjs, à relire là plutôt qu'à recopier ici (cette page a affiché « 128 champs / 13 sections » bien après que le record en compte davantage). Ce document relie chaque variable aux champs qu'elle débloque, à son coût réel, et, c'est le point le plus utile, à l'alternative gratuite quand il en existe une.

La source de vérité machine reste src/services/env-audit.ts (rendue sur /admin/platform/env-audit) et src/services/provider-health.ts (rendue par GET /api/admin/providers). Ce document explique le pourquoi ; ces deux surfaces disent l'état courant. Si les deux divergent, ce sont elles qui ont raison.

Convention de lecture : Socle = rien ne fonctionne sans ; Levier = une section entière s'allume ; Confort = un repli honnête existe déjà.


1. Le socle — sans ça, la DB ne se remplit pas du tout

VariableCe qu'elle débloqueSans elle
DATABASE_URLtoutrien ne démarre
KV_REST_API_URL + KV_REST_API_TOKENcache, budget-breaker providers, runs publicitaires parkéschaque scan repaie tout, aucun garde-fou de budget
QSTASH_TOKEN (+ QSTASH_CURRENT_SIGNING_KEY, QSTASH_NEXT_SIGNING_KEY)le débit de découvertele firehose moissonne des milliers de domaines et en indexe 3 par tick (repli inline borné) — voir intelligence-runtime-checklist.md §1

KV_* est injecté par l'intégration Vercel « Upstash ». QStash est un produit Upstash séparé : ses clés ne sont PAS injectées automatiquement. C'est le piège numéro un.


2. La couche de rendu, le multiplicateur silencieux

VariableCe qu'elle débloqueCoût
FIRECRAWL_API_KEY9 sondes qui exigent du HTML rendu : social-handles, reviews-vendor, pixel-detector, app-detector, emails, popup-detector, analytics, reviews-aggregation, traffic-provider~1 crédit par rendu, 5 sur un hôte muré : le mode anti-bot (proxy: "auto", posé quand la sonde demande stealth) paie d'abord le fetch à 1 crédit et ne rejoue par le pool résidentiel qu'après détection d'un blocage

Sans elle ces sondes lisent la coquille non-hydratée : pixels, apps, handles sociaux et avis reviennent vides sur un store qui les expose pourtant. C'est le mode de panne le plus trompeur du pipeline, parce qu'il ressemble à « ce store n'a rien ».

Le chaînage direct → brightdata → firecrawl → brightdata-browser vit dans src/lib/fetch-providers/. Un cache de 90 s (response-cache.ts) fait qu'un scan ne paie qu'un seul rendu de la home, pas neuf.

VariableCe qu'elle débloqueCoût
BRIGHTDATA_UNLOCKER_TOKEN + BRIGHTDATA_UNLOCKER_ZONE ou BRIGHTDATA_PROXY_URLdéblocage anti-bot (IP résidentielle) devant Firecrawlfacturé par requête réussie
BRIGHT_DATA_USERNAME + BRIGHT_DATA_PASSWORDScraping Browser tier-3, dernier recoursplafonné par INTELLIGENCE_TIER3_BUDGET_CENTS_PER_MONTH

À ne poser que si le diagnostic dit traffic.scrape_challenged ou si des sondes remontent looksLikeChallenge: true. Un 404 n'est pas un blocage (§6).

Le seul cas où ces clés sont la SEULE réponse : les abonnés FB / Instagram

Mesuré le 2026-08-22 sur valisedemo, pas supposé. Meta publie les deux compteurs (757 followers Facebook, 3,3 K Instagram) sur la page « À propos de l'annonceur » de sa Bibliothèque publicitaire : c'est vraisemblablement là que l'outil concurrent les lit. Trois portes y mènent, les trois sont fermées à un serveur sans cookies :

SurfaceRéponseConclusion
Page Bibliothèque publicitaire403, 481 octets, sans cookies de sessionfermée à notre runtime
Page Plugin (plugins/page.php)200, ~18 Ko — mais coquille : le texte visible se réduit à « Facebook », zéro chiffrehydratée en JS, exige un rendu
Profils instagram.com / facebook.com403 "we do not support this site"Firecrawl refuse ces domaines par POLITIQUE — ni les en-têtes ni le tier de proxy n'y changent quoi que ce soit

Donc FIRECRAWL_API_KEY, quel que soit son crédit, ne débloquera jamais ces deux champs. BRIGHT_DATA_USERNAME + BRIGHT_DATA_PASSWORD sont la seule voie : le Scraping Browser n'a pas cette politique de domaine. Il ouvrira d'abord le Page Plugin, le moins cher des trois (un widget de 18 Ko, pas une page de profil, et aucun mur de connexion à franchir) : le code le demande déjà en rendu, donc rien d'autre n'est à modifier.

Tant que ces clés ne sont pas posées, social.*_followers reste absent, et le diagnostic le dit désormais franchement (social.counts_unrenderable) plutôt que de laisser croire à un mur qu'un meilleur parseur franchirait.


3. Publicités — la variable qui change tout pour un store européen

VariableCe qu'elle débloqueCoût
META_AD_LIBRARY_TOKENads.active_creatives, networks, primary_format, hook_clusters, networks_detail — plus la portée UE (reachBand) que le scraper ne porte pasgratuit
APIFY_TOKEN + APIFY_AD_LIBRARY_ACTOR_IDles mêmes champs, couverture mondialepayant, par run (navigateur, plusieurs minutes)
APIFY_TIKTOK_ADS_ACTOR_IDla ligne TikTok de ads.networks_detailpayant
APIFY_GOOGLE_ADS_ACTOR_IDla ligne Google — les créatives, pas la présence (voir ci-dessous)payant
APIFY_PINTEREST_ADS_ACTOR_IDla ligne Pinterestpayant

META_AD_LIBRARY_TOKEN est la meilleure ligne de ce document. Depuis le Digital Services Act, Meta doit publier les publicités commerciales, pas seulement politiques, pour toute annonce diffusée dans l'UE ou au Royaume-Uni. L'API officielle ads_archive les rend donc accessibles gratuitement, en un appel synchrone, avec la portée et le ciblage en prime. Hors UE/UK le même appel ne renvoie que du politique : l'adaptateur meta-graph.ts restreint donc ad_reached_countries à l'UE/UK et s'abstient ailleurs plutôt que de renvoyer un corpus qui n'a rien à voir.

L'enchaînement est : gratuit d'abord, payant seulement si le gratuit n'a rien trouvé (ad-library/index.ts). Un store français comme valisedemo.com est donc entièrement couvert sans dépenser un centime, et Apify ne se déclenche que pour les marchés hors UE.

Bénéfice secondaire, et il est structurel : l'API officielle renvoie ad_creative_link_captions, c'est-à-dire le domaine affiché par l'annonceur. L'attribution passe donc d'une comparaison de noms (« Valise Demo » ≈ n'importe quel annonceur employant ces mots, c'est ce qui avait produit 2 800 créatives fantômes) à une comparaison d'hôtes. Prouvable, pas plausible.

Comment l'obtenir : vérifier son identité sur facebook.com/ID → accepter les conditions sur facebook.com/ads/library/api → générer un token utilisateur longue durée. Compter 1 à 2 semaines de validation. Un token applicatif ({app_id}|{app_secret}) est refusé par cet endpoint : META_APP_ID / META_APP_SECRET ne peuvent pas s'y substituer.


Le Google Ads Transparency Center n'expose aucune API publique. La seule voie câblée vers ses créatives est un actor Apify payant (APIFY_GOOGLE_ADS_ACTOR_ID). Aucune clé gratuite n'existe et aucun scraper ne la remplace honnêtement.

Ce qui est gratuit et certain, en revanche : le tag de conversion AW-… que la boutique porte elle-même. Personne n'installe le tag de conversion d'un réseau sur lequel il n'achète pas. Il est déjà extrait (stack.tracking_ids.google_ads) par le lecteur de conteneur GTM et le détecteur de pixels, y compris derrière un Consent Mode, où la page seule ne montre rien.

La bande « Réseaux » de l'onglet Ads rend donc deux niveaux de preuve qui ne se confondent jamais :

NiveauCe qu'on afficheQuand
Mesuréle nombre de créatives activesune bibliothèque publicitaire a répondu pour cet annonceur
Taggél'identifiant du tag + « créatives indisponibles »seule la présence est établie

Un réseau sans aucune preuve n'a pas de ligne du tout. Écrire « Google · 0 » affirmerait que la boutique n'achète pas sur Google, ce qui est exactement l'inverse de ce que le tag prouve.

4. Trafic — 6 champs, et une vérité désagréable

VariableCe qu'elle débloque en plus du gratuitCoût
SIMILARWEB_API_KEYvisits_series (la courbe multi-mois) + des quotas et une fiabilité que le scrape n'a pasabonnement API
DATOS_API_KEYidemabonnement
SEMRUSH_API_KEYidem (+ sert aussi de repli SEO, §5)abonnement

Colonne libellée « en plus du gratuit » à dessein. monthly_visits, top_country, top_source, paid_share, country_breakdown et visits_change_pct arrivent sans aucune clé, par le scrape de la page publique : un scan live de valisedemo a remonté 724 visites / FR 100 % avec zéro variable posée. Les lister comme « débloqués par la clé » revient à faire payer un champ déjà obtenu ; seule la série temporelle l'est réellement.

Extension / hub lookup?rich=1. The Spy panel and the hub read the same HubStore projection (projectVisitsSeries). A monthly KPI with visits_series: null is not a missing extension wire: the free scrape has fewer than two months, none of the three keys above is set, or the panel has no coverage (traffic.no_coverage). Proof procedure: 2026-09-10-spy-ext-coherence.md.

Priorité de résolution : SimilarWeb → Datos → Semrush (traffic-providers/types.ts). Sans aucune clé, la sonde retombe sur le scrape gratuit de la page publique SimilarWeb.

La vérité désagréable. Aucune de ces clés ne produira de chiffre pour un petit store. Les panels ne mesurent que ce qu'ils observent, et un storefront sous leur plancher n'a pas de page publique : SimilarWeb répond 404, ce qui n'est ni un blocage ni un bug de parser. Le diagnostic distingue désormais ce cas (traffic.no_coverage) de traffic.scrape_challenged.

Recalibrage, ce que ce document a affirmé de trop

Une version antérieure de cette section concluait que le trafic de valisedemo.com « n'existe nulle part » et qu'il ne fallait acheter aucune clé. C'était une inférence, pas une observation. Le code de classification est juste ; son application à ce store précis ne l'était pas : le statut HTTP réellement renvoyé pour ce domaine n'a jamais été relevé.

Le fait rapporté par l'opérateur, l'outil de référence du marché affiche ce store complet, tranche dans l'autre sens. Deux lectures possibles, et il faut mesurer avant de choisir :

  1. Ils estiment le trafic à partir de signaux de première main (leur extension Chrome constitue un panel propriétaire), auquel cas la parité passe par notre propre estimation, pas par un abonnement.
  2. Une source couvre ce store et n'est pas câblée ici, auquel cas c'est une lacune d'implémentation.

Dans les deux cas la conclusion « la donnée n'existe pas » était fausse. La règle : quand un concurrent affiche une valeur pour un store, la donnée est atteignable ; la question est par quel chemin, jamais si.

Pistes gratuites déjà évaluées, avec leur limite connue :

SourceCe qu'elle donneLimite
Cloudflare Radar Rankingrang de domaine, gratuit avec un comptetop ~1 M
Trancoliste de rangs, CSV gratuittop ~1 M
CrUX (GOOGLE_PAGESPEED_API_KEY, déjà posée pour les Web Vitals)présence dans le dataset Chromesignal de plancher, pas un nombre de visites

Ces limites sont documentées par leurs éditeurs ; elles n'ont pas été vérifiées contre valisedemo.com en particulier. À faire avant toute décision d'achat, et avant de re-citer ce tableau comme un verdict.


5. SEO hors-page — 6 champs

VariableCe qu'elle débloqueCoût
AHREFS_API_KEYseo.organic_keywords, organic_traffic, backlinks, referring_domains, domain_rating, top_ranking_keywordsle plus cher
SEMRUSH_API_KEYidemintermédiaire
DATAFORSEO_API_KEYidem (base64 de login:password)le moins cher, à la requête

Priorité : Ahrefs → Semrush → DataForSEO (seo-providers/types.ts). Les 13 autres champs SEO (title, meta, h1, canonical, hreflang, schema, word count, liens internes, ratio alt, blog, indexable, keywords cibles, top pages) sont on-page : ils se remplissent gratuitement, sans aucune clé.

Recommandation : DataForSEO, facturé à l'appel. Sur ces six champs les trois fournisseurs racontent la même histoire ; payer un abonnement Ahrefs pour un domain_rating n'a pas de sens à ce stade.

Alternative gratuite partielle : OpenPageRank reconstruit un score d'autorité 0-10 depuis le graphe ouvert de Common Crawl, en lot et sans frais. Il couvre honnêtement domain_rating, pas les cinq autres champs. Non câblé aujourd'hui : c'est un candidat d'implémentation, pas une variable à poser.


6. Stores similaires

VariableCe qu'elle débloqueCoût
UPSTASH_VECTOR_REST_URL + UPSTASH_VECTOR_REST_TOKENl'index d'embeddings — toute la recommandation « stores similaires »tier gratuit Upstash suffisant au départ

Sans ces deux clés, getIndex() renvoie null et chaque appel à searchSimilar se termine par un tableau vide. Aucune erreur, aucun log d'alerte : la fonctionnalité est simplement absente de l'interface. C'est le meilleur rapport valeur/effort de tout ce document : deux clés, un tier gratuit, une section entière.

À ne pas confondre avec la section graph (§8), qui ne dépend d'aucune variable.


7. Confort — un repli honnête existe déjà

VariableCe qu'elle débloqueSans elle
KLAVIYO_BENCHMARK_API_KEYemail.niche_benchmarks en directsnapshot embarqué, mis à jour trimestriellement — parfaitement exploitable
APIFY_SHOPIFY_DATASET_IDbackfill de ~500 k domainescrt.sh + Common Crawl (gratuits) continuent de moissonner
COMMON_CRAWL_INDEXépingle un snapshot récentun snapshot récent est codé en dur
OPENCORPORATES_API_TOKENrattachement d'entité légalechamp absent
CLICKHOUSE_URLrien aujourd'hui : déclarée, sans effet. getTimeSeriesStore() retourne postgresStore dans les DEUX branches (intelligence/time-series/index.ts), le driver ClickHouse est un stub et le log annoncé n'est pas émispartitions Postgres, exactement pareil
INTELLIGENCE_VISION_BUDGET_CENTS_PER_STOREplafond d'analyse visuelle des créatives100 c/store
INTELLIGENCE_CREATIVE_LABELSactive les étiquettes IA des créatives (accroche, angle, étape du funnel, offre, urgence) ; exige aussi AI_GATEWAY_API_KEYdésactivé : aucune créative n'est étiquetée, les facettes restent vides
INTELLIGENCE_CREATIVE_LABELS_BUDGET_CENTS_PER_DAYplafond quotidien des appels d'étiquetage100 c/jour ; 0 arrête l'étiquetage
INTELLIGENCE_ANON_SECRETHMAC des handles anonymisésà poser malgré tout : sans secret, un handle « anonyme » est un hash devinable sur l'espace des domaines Shopify
JUDGE_ME_API_TOKENsur vos propres stores uniquement : photo_ratio, response_rate, verified_buyer_ratio, et l'échantillon de textes qui alimente le sentimentle compte et la note se lisent sur le badge que Judge.me a rendu dans la page — voir ci-dessous

Judge.me authentifie, et c'est la seule chose qui compte ici

L'endpoint judge.me/api/v1/widgets/preview_badge a été documenté dans ce repo comme « public, sans auth ». C'est faux. Appelé sans jeton il répond, pour n'importe quelle boutique :

{"error":"Failed to authenticate. Shop domain or Api Token is wrong"}

Le jeton en question est celui du marchand. Sur une surface d'intelligence concurrentielle on ne l'a jamais : donc l'appel était un 4xx garanti sur chaque store Judge.me rencontré, et son résultat vide se lisait en aval comme « cette boutique n'a pas d'avis ». La sonde ne le tente plus sans jeton et nomme la raison (widget_reason: "judge-me-api-token-missing").

Ce qui marche sans aucune clé, et qui est la seule source Judge.me pour un concurrent : le compte et la note que le widget de Judge.me a lui-même écrits dans la page (data-number-of-reviews, data-average-rating), lus au rendu que FIRECRAWL_API_KEY produit déjà. Un store dont la page d'accueil ne porte que des badges par produit, sans widget agrégé, n'expose donc pas de headline, chez nous comme chez un concurrent.


La date de création ne coûte rien, et n'était pas lue

identity.domain_registered_at et identity.domain_registrar viennent du registre lui-même, en RDAP (RFC 9082 / 9083) : HTTPS, JSON, aucune clé, aucun contrat, aucun quota facturé. Ils n'apparaissent donc dans aucun tableau ci-dessus, et c'est délibéré : il n'y a pas de variable à poser.

Cette page a longtemps laissé croire le contraire par omission : l'âge d'une marque semblait dépendre d'archive.org seul, donc d'un signal qu'aucune clé n'améliore. En réalité le registre répond gratuitement, et il répond mieux : la première capture d'archive.org est une borne haute (une petite marque est crawlée des mois après son ouverture), là où la création du domaine est une borne basse datée à la seconde. Voir intelligence-pipeline.md §5.2.

7 bis. Plafonds et bornes : les variables qui ne remplissent rien

Six variables déclarées dans src/env/server.ts manquaient à ce document. Elles ne débloquent aucun champ : elles bornent le pipeline, et c'est exactement ce qu'un opérateur vient régler ici.

VariableCe qu'elle borneDéfaut
INTELLIGENCE_SPY_FULL_SCANS_PER_MONTHscans full de stores espionnés par mois120 (~4/jour)
INTELLIGENCE_PROVIDER_BACKFILL_PER_DAYscans ciblés (sondes trafic / pubs seules) qui remplissent les fiches déjà indexées quand une source est posée, lancés par refresh-warm ; exige KV (sans compteur partagé, rien ne tourne) ; 0 coupe le rattrapage40
INTELLIGENCE_CATALOG_MAX_PAGESpages de catalogue lues par store25
INTELLIGENCE_TRAFFIC_HISTORY_MONTHSprofondeur d'historique de trafic demandée12
INTELLIGENCE_HISTORY_RETENTION_DAYSrétention de l'historique d'intelligence180
INTELLIGENCE_LIVENESS_BATCHtaille de lot du balayage de liveness1000
INTELLIGENCE_SUPPRESSED_DOMAINSdomaines exclus du pipeline (liste séparée par des virgules)vide

Ces deux plafonds-là exigent Upstash. INTELLIGENCE_SPY_FULL_SCANS_PER_MONTH et INTELLIGENCE_TIER3_BUDGET_CENTS_PER_MONTH comptent dans un compteur Redis partagé. Sans KV_REST_API_URL / KV_REST_API_TOKEN (ou leurs équivalents UPSTASH_REDIS_REST_*), il n'y a pas de compteur partagé du tout : rateLimit retombe sur une Map de portée module, donc par instance serverless, remise à zéro à chaque cold start.

Depuis intelligence/0351, les deux gardes refusent dans ce cas au lieu d'autoriser : le scan spy-full rend guard_unavailable, le tier-3 aussi. Avant, ils dépensaient — le plafond mensuel de 120 scans devenait 120 scans par lambda, et les $50 de tier-3 devenaient $50 par lambda, sans une ligne de log. Poser ces variables sans Upstash ne borne donc plus rien du tout, et ne dépense plus rien non plus.


8. Ce qu'aucune variable ne débloque

Trois familles de champs ne dépendent d'aucune clé. Les chercher dans ce document, c'est chercher au mauvais endroit.

Le temps. prediction.* (9 champs), catalog.inventory_velocity, best_seller_velocity, recent_diffs mesurent un mouvement. Ils exigent au moins deux scans espacés ; au premier scan ils sont légitimement vides, et les crons de rafraîchissement les remplissent tout seuls. Ils ne sont jamais fabriqués à partir d'un seul point.

Le volume. La section graph (edges, same_owner_domains, network_domains, clone_candidates, shared_identifiers, cluster_id) relie un store aux autres via l'index inversé StoreSignalIndex (identifiants de tracking partagés, comptes sociaux, empreinte thème+apps, recouvrement de produits). Un graphe se construit à partir de voisins : tant que peu de stores ont reçu un scan profond, il n'y a personne à relier et related_count: 0 est la réponse correcte. related_count est d'ailleurs toujours émis, même à 0 : c'est le marqueur « le graphe a tourné » qui distingue « aucun réseau trouvé » de « jamais analysé ». La cure est le débit de découverte, donc §1 (QSTASH_TOKEN), pas une nouvelle clé.

Le store lui-même. Un marchand qui masque inventory_quantity, ne tague pas ses produits ou n'a pas d'app d'avis laisse ces champs vides chez tout le monde, nous comme les concurrents. C'est une absence honnête, pas une panne.


9. Le cas valisedemo.com

Store français, jeune, catalogue restreint. Référence de parité : l'outil de référence du marché affiche ce store complet. Tant que ce n'est pas le cas ici, l'hypothèse par défaut est un défaut de notre côté, code ou quota, et non une donnée introuvable.

SectionÉtatLevier
identity, catalog, stack, commerce, seo on-pagepleindéjà là (+ FIRECRAWL_API_KEY)
social, emailplein si le store expose des comptes sociauxFIRECRAWL_API_KEY
reviewsapp détectée (judge-me), aucun chiffre — pas de page Trustpilot, et la page d'accueil ne porte pas de widget agrégé Judge.me. Aucune clé n'y change quoi que ce soit (§7)mesuré le 27/08/2026
adsgratuit pour un store UEMETA_AD_LIBRARY_TOKEN
similar storesvideUPSTASH_VECTOR_REST_*
seo hors-page (6)videDATAFORSEO_API_KEY
traffic (6)vide — cause non tranchée, voir §4à mesurer, pas à acheter
prediction (9), velocityse remplit tout seul2ᵉ scan
graph (6)vide tant que le voisinage est videQSTASH_TOKEN (§1)

Ordre d'action :

  1. META_AD_LIBRARY_TOKEN — gratuit, débloque la section vitrine. Sans elle, ads_absence reste not_observed / quarantined et creatives[] vide : l'extension garde Import Library en fallback (preuve : 2026-09-10-spy-ext-coherence.md).
  2. UPSTASH_VECTOR_REST_URL + _TOKEN — tier gratuit, débloque les similaires.
  3. QSTASH_TOKEN — remplit la DB, donc à terme le graphe.
  4. DATAFORSEO_API_KEY — 6 champs SEO, facturé à l'appel.
  5. Trafic : relever le statut HTTP réel avant toute décision (§4).

Deux blocages qui n'étaient ni des clés ni des crédits

Ils expliquent pourquoi des rescans répétés ne changeaient rien, et ils sont le rappel que ce document ne doit jamais être le premier suspect :

  • Le verrou de fraîcheur. Une section était considérée « fraîche » dès qu'un seul champ était rempli, ce qui faisait sauter la sonde à chaque scan suivant : les autres champs de la section ne pouvaient donc plus jamais se remplir. Cela touchait exactement les six sections concernées par skipIfFresh : ads, reviews, seo, social, traffic, catalog. Corrigé : une section n'est sautée que complète et fraîche.
  • Le cooldown Apify de 6 h. Il est posé dès qu'un run démarre, même s'il ne rend rien. Une rafale de rescans manuels retombe donc sur ads.budget_skipped pendant six heures. C'est délibéré, c'est ce garde-fou qui a arrêté la dépense, mais il faut le lire dans le diagnosis au lieu de conclure que le store n'a pas de publicités.

10. Vérifier, sans deviner

GET /api/admin/providers          # configured / breaker / live, par provider
GET /admin/platform/env-audit   # variables manquantes + impact
POST /api/admin/intelligence/scan # diagnosis[] + coverage.absentFields[]

Le diagnosis du scan nomme la cause et la variable qui la corrige (fix_env). Deux codes à savoir lire, parce qu'ils se ressemblent et appellent des gestes opposés :

  • traffic.no_coverage — SimilarWeb n'a pas de page pour ce domaine (404). Ni une clé, ni un proxy, ni un correctif de parser ne changent ce qu'eux renvoient. Ce n'est pas pour autant un verdict sur la donnée elle-même : si un concurrent affiche une valeur pour ce store, elle est atteignable autrement (§4).
  • traffic.scrape_challenged — un mur anti-bot s'est interposé. La donnée existe, l'accès manque : BRIGHTDATA_* ou une clé fournisseur.

coverage.absentFields liste nommément les champs vides par section : c'est ce qu'il faut lire avant d'ouvrir ce document, pas après.