One dataset. Every route.
No API key is needed for the scrape targets. Responses use fixed synthetic data, with errors you can test.
Paginated products
GET /api/products?page=1&limit=12 GET /api/products?q=canvas&category=Travel GET /api/products/1
page starts at 1. limit accepts 1–100. Responses include items, total, page, and a relative next URL. Invalid pagination returns 400; missing items return 404.
Cursor feed
GET /api/feed?cursor=0&limit=12
Follow next_cursor until it is null. The cursor is a zero-based offset.
POST search
curl -X POST http://localhost:8787/api/search -H 'Content-Type: application/json' -H 'X-Test-Run: post-search' -d '{"q":"canvas","page":1,"limit":12}'More formats
JSON articles · CSV export · JSON export · RSS · Sitemap
Correlate a test run
Send X-Test-Run: python-baseline, or append ?run=browser-baseline to a browser URL. Browser requests carry that label in a test cookie. Run and session labels are client claims, not trusted identity.
Browser telemetry
Pages send a small JSON event to POST /api/events: JavaScript execution, navigator.webdriver, viewport, and language. These values can be changed by a client. They are recorded as self-reported signals.
JA3 / JA4 and HTTPS
Run npm run cert once, then npm run start:https. Visit https://localhost:8788 to capture JA3/JA4 directly from the TLS ClientHello, plus the negotiated cipher and protocol. Your browser will ask you to accept the self-signed test certificate. The HTTP listener on port 8787 cannot capture TLS. The local HTTPS listener supports HTTP/2 and HTTP/1.1 over TLS 1.2/1.3. It records decoded HTTP/2 settings and pseudo-header order, but does not calculate full HTTP/2 frame/priority or HTTP/3 fingerprints.
See docs/TLS.md for the trust contract. Headers from an untrusted source are never treated as verified fingerprints.
Demo rules
config/rules.json defines example user-agent patterns, a burst threshold, a trap route, and exact fingerprint matches. Restart after edits. Set MODE=block to return 403 for configured matches, or 429 for burst matches. Default: observe only.
Request records
logs/requests.jsonl contains request IDs, timestamp, peer/client address, connection ID, headers and their observed order, timing, response bytes, run/session hashes, matched rules, and action. Credentials and cookie values are redacted.