browser-to-api

Par browserbase · skills

Transformez le trafic HTTP observable d'un site web en une spécification OpenAPI 3.1 au mieux de l'effort possible, en analysant une capture `browser-trace`. À utiliser lorsque l'utilisateur souhaite découvrir/extraire des endpoints API depuis une session navigateur, construire un document OpenAPI à partir du trafic réseau, ou documenter la surface XHR/fetch d'un site tiers pour une intégration client.

npx skills add https://github.com/browserbase/skills --skill browser-to-api

Browser to API

Découverte d'API pilotée par replay. Consommez une capture browser-trace, appairez ses événements de requête / réponse CDP, templatisez les URLs observées, déduisez les schémas JSON à partir d'échantillons, et émettez un document OpenAPI 3.1 accompagné d'un rapport de couverture lisible par l'homme.

Cette skill ne capture pas le trafic. C'est du post-traitement purement hors ligne sur les buckets cdp/network/*.jsonl de browser-trace. Les deux skills se composent :

browser-trace    →  .o11y/<run>/cdp/network/{requests,responses}.jsonl
browser-to-api   →  .o11y/<run>/api-spec/index.html + openapi.yaml + client.mjs

Quand l'utiliser

  • L'utilisateur veut un document OpenAPI pour l'API d'un site tiers ou non documenté.
  • L'utilisateur a une exécution browser-trace et veut en extraire les endpoints et schémas.
  • L'utilisateur construit un client/SDK contre un site qui ne publie pas de spec.
  • L'utilisateur veut un rapport de couverture montrant quels flux étendraient la spec.

Si l'utilisateur veut capturer le trafic, orientez-le d'abord vers browser-trace.

Workflow en deux étapes

1. Capturer avec browser-trace (et optionnellement les corps via browse network on)

# Exemple local (voir browser-trace SKILL.md pour la variante Browserbase)
browse env local
browse open about:blank
TARGET="$(browse status --json | jq -r .wsUrl)"

node ../browser-trace/scripts/start-capture.mjs "$TARGET" my-site
browse network on                                    # capturer les corps requête/réponse
browse open https://example.com
# ...piloter les flux que vous voulez couvrir...

# Faire un snapshot du répertoire bodies AVANT d'éteindre la capture (le répertoire
# temporaire est partagé par session, donc les exécutions `browse network on` ultérieures
# mélangeraient vos bodies avec ce qu'une future capture écrirait si vous sautez cette étape).
cp -r "$(browse network path | jq -r .path)" .o11y/my-site/cdp/network/bodies/
browse network off

node ../browser-trace/scripts/stop-capture.mjs my-site
node ../browser-trace/scripts/bisect-cdp.mjs my-site

browse network on est optionnel mais fortement recommandé — sans lui, la spec n'a pas de schémas de corps de réponse (le firehose CDP utilisé par browse cdp n'embarque pas les corps). Avec lui, les corps de requête (déjà capturés par CDP) et les corps de réponse sont joints à la trace par requestId CDP.

2. Générer la spec

node scripts/discover.mjs --run .o11y/my-site
# → .o11y/my-site/api-spec/index.html          ← ouvrez ceci
#   .o11y/my-site/api-spec/client.mjs
#   .o11y/my-site/api-spec/openapi.yaml
#   .o11y/my-site/api-spec/openapi.json
#   .o11y/my-site/api-spec/report.md
#   .o11y/my-site/api-spec/confidence.json
#   .o11y/my-site/api-spec/samples/*.json
#   .o11y/my-site/api-spec/intermediate/*.jsonl

discover.mjs détecte automatiquement <run>/cdp/network/bodies/. Pour utiliser une capture de corps provenant d'ailleurs (par ex. snapshot non effectué, vouloir le répertoire browse network en direct), passez --bodies <path> explicitement.

3. Ouvrir le rapport HTML

Après que discover.mjs se termine, ouvrez toujours le rapport HTML généré :

open .o11y/my-site/api-spec/index.html

Le rapport est un fichier HTML autonome (aucun serveur requis) qui affiche chaque opération découverte sous forme de carte dépliable avec variables, utilisation du client, exemples requête/réponse, et un snippet client.mjs généré en bas. C'est le livrable principal — ouvrez-le toujours pour l'utilisateur.

Drapeaux CLI

Drapeau Requis Signification
--run <path> oui Chemin vers un répertoire d'exécution browser-trace
--out <path> non Répertoire de sortie ; défaut <run>/api-spec/
--bodies <path> non Répertoire de capture browse network à joindre à la trace (détecté automatiquement depuis <run>/cdp/network/bodies/ si présent)
--include <regex> non Inclure uniquement les URLs correspondant à la regex (répétable)
--exclude <regex> non Exclure les URLs correspondant à la regex (répétable ; en plus des défauts)
--origins <list> non Liste blanche d'origines séparées par des virgules (ex. api.example.com,example.com)
--format <yaml\|json\|both> non Format de sortie. Défaut both
--title <string> non OpenAPI info.title. Défaut déduit de l'origine primaire
--redact <list> non Noms d'en-têtes / clés JSON supplémentaires à flouter (séparés par des virgules)
--min-samples <n> non Minimum d'échantillons par endpoint à inclure. Défaut 1
--stage <name> non Exécuter une seule étape : load, filter, normalize, infer, emit

Disposition de la sortie

<run>/api-spec/
├── index.html                rapport visuel — ouvrez ceci (autonome, pas de serveur)
├── client.mjs                client fetch sans dépendances avec fonctions typées par opération
├── openapi.yaml              spec lisible par machine
├── openapi.json              miroir
├── report.md                 résumé markdown + exemples curl
├── confidence.json           confiance par endpoint + drapeaux de normalisation
├── samples/                  exemples requête/réponse floutés
│   └── <method>__<path-hash>.json
└── intermediate/             sous-produits du pipeline (jsonl appairés/filtrés/endpoints)

Ce que vous obtenez de browse cdp et browse network

Deux sources de capture complémentaires :

Source Fournit Limitation
browse cdp (utilisé par browser-trace) méthode/URL/en-têtes de requête/postData, statut/en-têtes/mimeType de réponse, timing complet des événements N'embarque pas les corps de réponse. Les corps doivent être récupérés avec Network.getResponseBody, ce que le firehose ne fait pas.
browse network on (commande séparée) corps de requête ET corps de réponse sur disque, indexés par requestId CDP Le répertoire de capture est partagé par session browse ; faire un snapshot avant qu'un autre browse network on ne le réécrive.

discover.mjs extraira les corps d'un répertoire browse network si vous passez --bodies <path> (ou les stockez sous <run>/cdp/network/bodies/, détecté automatiquement). La correspondance se fait par requestIdbrowse network l'écrit dans chaque request.json comme id, et nous joignons directement.

Ce qui change quand les corps sont présents :

  • ✅ Templatisation de chemin, schémas de paramètres de requête, codes de statut, types de contenu — identique de toute façon.
  • ✅ Schémas de corps de requête — postData de CDP suffit ; le répertoire bodies est un plus pour les cas sans postData.
  • Schémas de corps de réponse — complètement déduits à partir d'échantillons réels. Sans bodies vous obtenez des squelettes { description, content: <mimeType> }.

Le rapport signale chaque endpoint qui n'a pas d'échantillon de corps de réponse.

Filtrage automatique du bruit

L'étape normalize classe automatiquement et supprime le bruit d'infrastructure :

  • Suivi / analytiques — chemins contenant /track, /pixel, /beacon, /impression, /pageview, /dag/v*
  • Défense anti-bot — Akamai (/akam/), charges utiles d'empreinte (sensor_data), chemins multi-segments obscurcis
  • Plomberie de session/session, /authenticate/start, consentement aux cookies, endpoints d'expériences A/B
  • Rendus de pages HTML — requêtes GET renvoyant text/html (la page rendue, pas l'API)

Cela supprime généralement 60-80% du trafic capturé. Le drapeau --include peut sauver un faux positif.

Décomposition GraphQL / endpoint multiplexé

Quand un single endpoint (comme /dapi/fe/gql) est appelé avec différentes valeurs operationName, la skill le divise automatiquement en opérations logiques séparées. Chacune obtient sa propre :

  • Entrée de chemin OpenAPI (ex. /dapi/fe/gql [Autocomplete])
  • Schéma requête/réponse déduit uniquement des échantillons de cette opération
  • Exemple curl et tableau de variables dans le rapport

La détection fonctionne sur les champs de corps (operationName, method, action) et paramètres de requête (opname, op). Cela couvre GraphQL (APQ et inline), JSON-RPC, et patterns de dispatch similaires.

Limitations

  • La couverture est bornée par le flux capturé. Les endpoints non exercés dans la trace n'apparaîtront pas. La skill ne peut pas prouver la complétude.
  • Les schémas sont inductifs, pas contractuels. Un champ peut être optionnel sur le serveur même si tous les échantillons le contenaient.
  • L'authentification est observée, pas spécifiée. La skill enregistre les en-têtes de forme auth dans une extension x-observed-auth mais ne revendiquera pas un schéma de sécurité.
  • La templatisation de chemin est heuristique. Les patterns numérique / UUID / hex / slug sont détectés par segment. Les URLs ambiguës sont signalées dans confidence.json.
  • Le floutage est au mieux un effort. Les floutages par défaut couvrent les identifiants courants, mais les secrets spécifiques à l'app peuvent s'échapper ; utilisez --redact pour les en-têtes/clés personnalisés connus.

Bonnes pratiques

  1. Piloter les flux que vous voulez documenter. Plus la browser-trace est riche, plus la spec est riche.
  2. Utiliser --origins pour les sites bruyants. Une page marketing frappe des douzaines d'hôtes d'analytiques ; limitez à l'origine API qui vous intéresse.
  3. Inspecter report.md en premier. Il a des exemples curl-ready et des échantillons de réponse pour chaque opération découverte.
  4. Augmenter --min-samples à 2+ quand vous voulez uniquement les endpoints confidemment formés dans le doc final — éliminez la queue longue.
  5. Coupler avec browse network on quand les schémas de corps de réponse importent. Le firehose CDP seul a les corps de requête mais pas les corps de réponse.

Pour les internals du pipeline et la référence de format de fichier, voir REFERENCE.md.

Skills similaires