Introspection agent interface Use ?json=true (exactly once) on the same route. Keep existing query options with &. GET /agents is this plain-text guide; /agents?json=true returns it in JSON. GET /signals?json=true and /tests?json=true return current catalogs without running probes. Catalog entries identify automatic versus explicit starts and link to JSON browser routes. Research documents - Research access uses ?key= once, then a 90-day research_access cookie. Follow the redirect and retain cookies; without access the response is a password form. - GET /research?json=true lists public reports and their references without running JavaScript. - Report URLs are static reading pages. Inline examples require an explicit Run test click. Read that block’s [data-test-result] textContent and data-state (ready/running/complete/error/timeout). complete means execution settled, not that a capability is supported; inspect the returned value. Results are current-browser demonstrations, not saved study evidence or product captures. - Research documents do not have a ?json=true measurement adapter; use the catalog for HTTP discovery. Browser measurements - Navigate the TARGET browser to /?json=true. /json remains a supported alias. - Fresh measurement visits run the full product catalog three times and attempt to save a new session. Repeated navigation creates new captures. Cookie-based dashboard recall does not apply. - Optional source=chrome|product|unknown records supplied provenance, not observed browser identity. configuration and revision must be supplied together. attribution is URL-encoded attribution JSON. - /sessions/{label}?json=true loads saved evidence without probing. /sessions/{labelA}/{labelB}?json=true loads and compares saved A and B without probing. /?json=true&a={UUID-or-label}&b={UUID-or-label} also works. Invalid selections stay errors. - Legacy selections require explicit ae/be execution UUIDs with a/b. Never infer an execution sequence. - In automation, read only document.querySelector('#results').textContent and JSON.parse it. Wait until #results.dataset.state is complete, partial, or error. For new sessions also wait for #results.dataset.persistence to be saved or failed; inspect acknowledgement before claiming a save. Loading, collecting and processing are not results. A partial capture is not a successful full run. Individual signals and test suites - /tests/canvas-stress-full/?json=true runs the combined stress, static vendor, noise and confirmation corpus. It uses canvas-stress-hashes/v1 with suite canvas-stress-full/1 and aggregate SHA-256 over the UTF-8 CSV of full row hashes. ?full=true includes the shared canvas-stress/v1 sample/blob evidence. #comparison= accepts full hashes in lexical row order without HTTP header limits; the query form is also accepted. Inspect incomplete/unstable rows; matching error hashes never confirm parity. - /tests/canvas-stress/?json=true automatically runs the canvas stress suite. Read #results at complete or error. canvas-stress-hashes/v1 returns ordered family/route hashes, repeat status, observed context and a csv string; ?full=true adds per-case evidence and byte blobs. Optional comparison= compares in table order. Copy comparison URL on the normal page preserves the test settings. Defaults: seed=20261009, variants=6, repeats=2; variants allows 1..16 and repeats 1..3. Match means stable observed hashes agree, not verified Windows parity. Keep the same build, seed, variants and browser version; preserve native/patch launch receipts separately. A CSV has no provenance. No session is saved. Reload for a fresh page baseline. - /tests/gradient/?json=true&tag=chrome&device=lab-pc-01 automatically collects three repetitions and saves one gradient capture. Add &persist=false for local JSON with persistence.status=not_requested and no D1 write. Tags: chrome, stealthium-noised, stealthium-swiftshader. Without tag, configure the form and explicitly start. Device must identify the same physical machine across profiles and tags. Optional configuration and outcome=unknown|allowed|blocked are supplied context. Inspect persistence.status, independently of capture completion. GET /api/gradient/dump is a read-only snapshot page; follow nextCursor with ?cursor=... until null. The normal page collects immediately and downloads the whole snapshot. Without labels, JSON returns an unlabelled measurement with needsLabels: true; labelled URLs return capture and persistence. - /signals/{key}?json=true runs one focused collector. Discover keys from the signal catalog. - /tests/{key}?json=true runs one longer HTTP observation; these are excluded from product captures. - Focused JSON is the existing signal-result/v1 portable export: signal, outcome, diagnostics, results. It saves no session. Unsupported/skipped/failed outcomes are evidence, not infrastructure success. - /tests/canvas/?json=true runs canvas validation; platform and expected options are preserved. Its JSON includes the full downloadable capture with raw samples. - /tests/media-codec-capabilities/?json=true and /tests/webrtc-offer/?json=true run automatically. - /tests/latest/?json=true (execution consistency), /tests/worker-startup/?json=true and /tests/canvas-parity/?json=true wait at ready. Click [data-agent-run] to run their default suite. Use the normal page to configure nondefault options or upload a reference/font; JSON mode retains the same form fields for browser automation. It never adds user activation on an automatic visit. - /tests/shape-stats/?json=true waits at ready; click [data-agent-run] or add &autorun. The shape-stats/v1 export uses a pinned inspector collector in an offline disposable frame. Inspect status, recorder omissions, compiled coverage and each slot's roundTripVerified. No ADP verdict is measured, no telemetry is delivered and no session is saved. Device/episode/proxy labels are supplied context. This collector version differs from historical ADP summaries. - /tests/webgpu-subgroup/?json=true waits at ready; click [data-agent-run] to run. Optional min=32&max=128, context=page|worker|both, cases=comma-separated-IDs and label configure the same grid. &autorun starts explicitly on navigation. The webgpu-subgroup-challenges-v1 diagnostic keeps shader source, readbacks, errors and per-case wall times; inspect complete, counts and events. No session is saved. Previous runs can be recovered on the normal page. - Focused encrypted-media cases need an explicit [data-agent-run] click after the automatic pass. An automation click is not proof that the browser granted a permission or activation-gated API. - All focused/custom JSON pages expose #results with data-state loading, ready, collecting, processing, complete, or error. Wait for complete or error, then parse textContent. complete means the export settled; inspect its outcome/status/terminal and diagnostics. Explicit suites expose a ready JSON placeholder until started. A disabled run button means wait or reload (for unresolved cleanup). Error output is { state: "error", error: "..." }. - Fresh reloads are clean baselines; warm reruns can retain modules/caches. Keep the tab visible and focused. Run measurements sequentially. Do not take screenshots, inspect layouts, fetch source, activate reference demos or render large DOM snapshots while collection is active. - JSON mode suppresses tables, reference visuals and highlighting; it is a distinct presentation context. Do not assume timing equality with a full page or a user-clicked run. HTTP-only reads (no browser execution) - GET /sessions?json=true[&limit=1..50&cursor=...] redirects to /api/v2/sessions. Supported filters include source, sessionId, sessionLabel, configurationId, configurationRevision, browserVersion and reference=verified|unverified. Follow the returned nextCursor; totals are paged. - GET /api/v2/sessions/{UUID-or-label} returns a saved summary. - GET /api/v2/sessions/{UUID-or-label}/export returns the complete saved export. - GET /api/v2/sessions/{UUID-or-label}/signals/{key} returns only that signal's saved evidence. - GET /archive?json=true[&cursor=...] lists historical records; &id={id} reads original evidence. - GET /signals/{key}/manifest.json describes a focused build. Its sample.url returns generated IIFE source metadata. Fetch source only when needed, after collection settles. - API routes already return application/json; no json parameter is needed there. - Live browser routes return HTML with a minimal JSON result surface, not an HTTP JSON measurement. fetch/curl cannot execute target-browser probes. Use a browser/CDP/Playwright for these routes. Preserve existing authentication and same-origin access; this interface adds no access bypass. Playwright example (focused automatic run) await page.goto(origin + '/signals/browser.navigator?json=true'); await page.waitForFunction(() => ['complete', 'error'].includes(document.querySelector('#results')?.dataset.state)); const result = await page.locator('#results').evaluate(el => JSON.parse(el.textContent)); For an explicit suite, first wait for ready and click page.locator('[data-agent-run]'). For a full measurement, accept complete/partial/error and check persistence separately.