$npx -y skills add browserbase/skills --skill browser-to-apiTurn a website's observable HTTP traffic into a best-effort OpenAPI 3.1 spec by analyzing a browser-trace capture. Use when the user wants to discover/extract API endpoints from a browser session, build an OpenAPI doc from network traffic, or document a third-party site's XHR/f
| 1 | # Browser to API |
| 2 | |
| 3 | Replay-driven API discovery. Consume a `browser-trace` capture, pair its CDP request / response events, templatize observed URLs, infer JSON schemas from samples, and emit an **OpenAPI 3.1** document plus a human-readable coverage report. |
| 4 | |
| 5 | This skill **does not capture traffic**. It is purely offline post-processing on top of `browser-trace`'s `cdp/network/*.jsonl` buckets. The two skills compose: |
| 6 | |
| 7 | ``` |
| 8 | browser-trace → .o11y/<run>/cdp/network/{requests,responses}.jsonl |
| 9 | browser-to-api → .o11y/<run>/api-spec/index.html + openapi.yaml + client.mjs |
| 10 | ``` |
| 11 | |
| 12 | ## When to use |
| 13 | |
| 14 | - The user wants an OpenAPI document for a third-party or undocumented website API. |
| 15 | - The user has a `browser-trace` run and wants endpoints + schemas extracted from it. |
| 16 | - The user is building a client/SDK against a site that doesn't publish a spec. |
| 17 | - The user wants a coverage report showing which flows would broaden the spec. |
| 18 | |
| 19 | If the user wants to **capture** traffic, send them to `browser-trace` first. |
| 20 | |
| 21 | ## Two-step workflow |
| 22 | |
| 23 | ### 1. Capture with `browser-trace` (and optionally bodies via `browse network on`) |
| 24 | |
| 25 | ```bash |
| 26 | # Local example against an existing debuggable Chrome target |
| 27 | TARGET=9222 |
| 28 | |
| 29 | node ../browser-trace/scripts/start-capture.mjs "$TARGET" my-site |
| 30 | browse open about:blank --cdp "$TARGET" |
| 31 | browse network on # capture request/response bodies |
| 32 | browse open https://example.com |
| 33 | # ...drive whatever flows you want covered... |
| 34 | |
| 35 | # Snapshot the bodies dir BEFORE turning capture off (the temp dir is shared |
| 36 | # per-session, so subsequent `browse network on` runs would mix your bodies |
| 37 | # with whatever a future capture writes if you skip this step). |
| 38 | cp -r "$(browse network path | jq -r .path)" .o11y/my-site/cdp/network/bodies/ |
| 39 | browse network off |
| 40 | |
| 41 | node ../browser-trace/scripts/stop-capture.mjs my-site |
| 42 | node ../browser-trace/scripts/bisect-cdp.mjs my-site |
| 43 | ``` |
| 44 | |
| 45 | `browse network on` is **optional but strongly recommended** — without it, the spec has no response-body schemas (the CDP firehose used by `browse cdp` does not embed bodies). With it, both request bodies (already captured by CDP) *and* response bodies are joined into the trace by CDP `requestId`. |
| 46 | |
| 47 | ### 2. Generate the spec |
| 48 | |
| 49 | ```bash |
| 50 | node scripts/discover.mjs --run .o11y/my-site |
| 51 | # → .o11y/my-site/api-spec/index.html ← open this |
| 52 | # .o11y/my-site/api-spec/client.mjs |
| 53 | # .o11y/my-site/api-spec/openapi.yaml |
| 54 | # .o11y/my-site/api-spec/openapi.json |
| 55 | # .o11y/my-site/api-spec/report.md |
| 56 | # .o11y/my-site/api-spec/confidence.json |
| 57 | # .o11y/my-site/api-spec/samples/*.json |
| 58 | # .o11y/my-site/api-spec/intermediate/*.jsonl |
| 59 | ``` |
| 60 | |
| 61 | `discover.mjs` auto-detects `<run>/cdp/network/bodies/`. To use a body capture from elsewhere (e.g. didn't snapshot, want the live `browse network` dir), pass `--bodies <path>` explicitly. |
| 62 | |
| 63 | ### 3. Open the HTML report |
| 64 | |
| 65 | After `discover.mjs` finishes, **always open the generated HTML report**: |
| 66 | |
| 67 | ```bash |
| 68 | open .o11y/my-site/api-spec/index.html |
| 69 | ``` |
| 70 | |
| 71 | The report is a self-contained HTML file (no server needed) that shows each discovered operation as an expandable card with variables, client usage, request/response examples, and a generated `client.mjs` snippet at the bottom. This is the primary deliverable — always open it for the user. |
| 72 | |
| 73 | ## CLI flags |
| 74 | |
| 75 | | Flag | Required | Meaning | |
| 76 | |---|---|---| |
| 77 | | `--run <path>` | yes | Path to a `browser-trace` run directory | |
| 78 | | `--out <path>` | no | Output dir; default `<run>/api-spec/` | |
| 79 | | `--bodies <path>` | no | `browse network` capture dir to join into the trace (auto-detected from `<run>/cdp/network/bodies/` when present) | |
| 80 | | `--include <regex>` | no | Only include URLs matching regex (repeatable) | |
| 81 | | `--exclude <regex>` | no | Exclude URLs matching regex (repeatable; in addition to defaults) | |
| 82 | | `--origins <list>` | no | Comma-separated origin allow-list (e.g. `api.example.com,example.com`) | |
| 83 | | `--format <yaml\|json\|both>` | no | Output format. Default `both` | |
| 84 | | `--title <string>` | no | OpenAPI `info.title`. Default derived from primary origin | |
| 85 | | `--redact <list>` | no | Extra header names / JSON keys to redact (comma-separated) | |
| 86 | | `--min-samples <n>` | no | Minimum samples per endpoint to include. Default `1` | |
| 87 | | `--stage <name>` | no | Run only one stage: `load`, `filter`, `normalize`, `infer`, `emit` | |
| 88 | |
| 89 | |
| 90 | ## Ou |