import type { Metadata } from 'next'; import { Section } from '@/components/ui/primitives'; import { SITE_URL } from '@/lib/site'; export const revalidate = 3600; export const metadata: Metadata = { title: 'API', description: 'Public, rate-limited JSON API and Server-Sent Events stream of InternetPressure.io — the same API the site uses.' }; const ENDPOINTS: { path: string; desc: string; params?: string }[] = [ { path: '/api/v1/status', desc: 'Instrument health: engine, ingest, probes, BGP, stores, internal_status.' }, { path: '/api/v1/pressure/global', desc: 'The index: pressure, level, Δ1h/Δ24h, velocity, acceleration, volatility, confidence, coverage, components with drivers, explain rows, 1-h sparkline.' }, { path: '/api/v1/pressure/history', desc: 'Server-side aggregated series for any scope.', params: 'scope_type=global|region|country|asn|service|component · scope_id · range=1h|6h|24h|7d|30d|1y' }, { path: '/api/v1/pressure/regions', desc: 'All regions with pressure, level, Δ1h, component scores, probes, targets, coverage.' }, { path: '/api/v1/pressure/region/{id}', desc: 'Region detail: 24-h history, 7-d baseline, incidents, top ASNs/services, probes, latency matrix.' }, { path: '/api/v1/pressure/countries', desc: 'Countries where we hold at least one probe or anchored target — nothing else is pretended.' }, { path: '/api/v1/pressure/country/{cc}', desc: 'Country detail with history, baseline, incidents, ASNs, services, probes and targets.' }, { path: '/api/v1/asns', desc: 'Autonomous systems index.' }, { path: '/api/v1/pressure/asn/{asn}', desc: 'ASN detail: components, BGP stats and 24-h series, regions observed, targets, incidents.' }, { path: '/api/v1/services', desc: 'Services index with observed availability and vendor status indicator.' }, { path: '/api/v1/service/{slug}', desc: 'Observed vs vendor, discrepancy, probe × target matrix, affected regions.' }, { path: '/api/v1/targets', desc: 'Target registry.' }, { path: '/api/v1/target/{id}', desc: 'Target detail: latest measurement per probe, 24-h series, DNS resolvers.' }, { path: '/api/v1/probes', desc: 'Probe network: status, last seen, version, uptime, clock offset, capabilities.' }, { path: '/api/v1/incidents', desc: 'Incident list.', params: 'status=active|resolved|all · limit · offset' }, { path: '/api/v1/incident/{slug}', desc: 'Incident detail: timeline, evidence, series with global overlay, probes, targets, BGP, annotations.' }, { path: '/api/v1/fronts', desc: 'Active Pressure Fronts (source → destination arcs).' }, { path: '/api/v1/bgp/stats', desc: 'BGP rates vs baseline, collectors, 1-h series, top origins.' }, { path: '/api/v1/latency', desc: 'Global latency medians, inter-region matrix, per-probe view.' }, { path: '/api/v1/ticker', desc: 'The live ticker counters.' }, { path: '/api/v1/routes', desc: 'Route Explorer: baseline vs current traceroute, diff, 24-h hashes, 7-d share.', params: 'probe · target' }, { path: '/api/v1/routes/pairs', desc: 'Sampled (probe, target) pairs with 24-h change counts.' }, { path: '/api/v1/history/summary', desc: 'History explorer summary.', params: 'year · month' }, { path: '/api/v1/explain', desc: 'Deep explainability: components → signals with current, median, MAD, robust z, samples, stress, contribution.' }, { path: '/api/v1/methodology', desc: 'Public copy of the scoring configuration.' }, { path: '/api/v1/search', desc: 'Search countries, regions, ASNs, services, targets, incidents.', params: 'q' }, { path: '/api/v1/live', desc: 'Server-Sent Events: snapshot, global_pressure_update, regional_pressure_update, ticker, bgp_stats, probe_stats, incident_created/updated, service_degradation, front_update, internal_status.' }, ]; export default function ApiPage() { return (

Developers

Public API

The website is built on the same API. It is free and rate-limited (120 requests per minute per IP, 4 concurrent SSE connections), returns JSON with UTC ISO-8601 timestamps and plain numbers, and is served with Cache-Control: no-store except long-range history (30 s). Unknown scopes return 404 {'{"error":"not_found"}'}. Higher limits, webhooks and historical exports: contact@spboucher.ai.

          {`# the index right now
curl -s ${SITE_URL}/api/v1/pressure/global | jq '{pressure, level, delta_1h, confidence}'

# 24 h of global pressure, 1-minute step
curl -s "${SITE_URL}/api/v1/pressure/history?scope_type=global&range=24h" | jq '.summary'

# a country, an ASN, a service
curl -s ${SITE_URL}/api/v1/pressure/country/CA | jq '.pressure'
curl -s ${SITE_URL}/api/v1/pressure/asn/13335 | jq '.bgp'
curl -s ${SITE_URL}/api/v1/service/cloudflare | jq '{observed, vendor_status, discrepancy}'

# live stream (SSE)
curl -N ${SITE_URL}/api/v1/live`}
        
{ENDPOINTS.length} public routes}>
{ENDPOINTS.map((e) => ( ))}
GET Returns Query
{e.path} {e.desc} {e.params ?? ''}

Every level field is one of calm ≤10 · normal ≤25 · elevated ≤40 · stressed ≤55 · high ≤70 · severe ≤85 · extreme ≤100; level_label is its human label.

internal_status is ok, degraded (too few fresh probes, stale BGP or unhealthy stores — the score is frozen and stale: true) or stale (engine has not run). Clients must show a degraded state instead of interpreting a frozen number.

); }