import type { Metadata } from "next"; import { Code } from "@/components/code"; import { Chip, PageHeader, Panel, Table, Td } from "@/components/ui"; import { SITE_URL } from "@/lib/api"; export const metadata: Metadata = { title: "API", description: "WebSensor REST API, RSS feed and replayable WebSocket live stream (protocol 2). Public, no key required in phase 1; owner-scoped tools use an anonymous header." }; const PUBLIC: [string, string][] = [ ["GET /api/v1/events", "List events (cursor pagination). See filters below. order=recent|importance|signal"], ["GET /api/v1/events/count", "Count of events matching the same filters as /events"], ["GET /api/v1/events/{id|slug}", "Event detail: change + field changes + unified diff, score reasons, related, cluster with propagation, interpretations, snapshots (has_raw), sensor reliability, history of the URL"], ["GET /api/v1/changes/{id}", "Raw change with heuristic, semantic class, field changes and the unified patch"], ["GET /api/v1/snapshots/{id}", "Snapshot metadata + canonical content; ?raw=1 streams the original body when retention kept it"], ["GET /api/v1/snapshots/compare?a=&b=", "Diff between any two snapshots of the same URL"], ["GET /api/v1/breaking", "Breaking desk: breaking_now, developing, recently_confirmed clusters + high-signal watching list"], ["GET /api/v1/pulse", "Pulse: 6 h activity series, desks, rising entities, anomalous sources, silent changes, group totals"], ["GET /api/v1/radar", "Radar: indicators (unusual source activity, silent clusters, doc/repo bursts, status changes, new coverage)"], ["GET /api/v1/clusters?limit=&since=", "Event clusters (state, signals, sources, lead time)"], ["GET /api/v1/clusters/{id|slug}", "Cluster detail: events, entities, propagation timeline, first-party vs external signals, lead_time_ms"], ["GET /api/v1/entities", "Entities (type, q)"], ["GET /api/v1/entities/rank?limit=", "Entity ranking: 24 h / 7 d activity, avg signal, confirmed ratio, baseline, rank score"], ["GET /api/v1/entities/{id}", "Entity detail: children, relations, sources, aliases, recent, insights (heatmap, anomaly, rank)"], ["GET /api/v1/entities/{id}/timeline", "Entity timeline (cursor pagination)"], ["GET /api/v1/countries", "Countries with sources, events and breaking counts (24 h)"], ["GET /api/v1/countries/{code}", "Country desk: breaking, by category, sources, by type, silent, recent"], ["GET /api/v1/categories/{channel}", "Category desk (ai · cyber · finance · health · government · science · products · infrastructure · news)"], ["GET /api/v1/sources", "Monitored organizations (category, q, country, tier, first_party)"], ["GET /api/v1/sources/{id}", "Source detail: sensors, entities, activity anomaly, quality, discovery, daily"], ["GET /api/v1/sensors/{id}", "Sensor detail: runs, snapshots, changes, events"], ["GET /api/v1/sensors/{id}/snapshots?limit=", "Snapshot history of one sensor (hashes, HTTP status, has_raw, event slug)"], ["GET /api/v1/domains/{domain}/timeline", "Domain: monitored URLs + events"], ["GET /api/v1/urls/history?url=", "URL history: snapshots, changes, events, removals"], ["GET /api/v1/search?q=", "Search events, entities, sources, URLs, clusters — accepts the q syntax below"], ["GET /api/v1/stats", "Platform counters (checks/min, events/min, breaking_now, 304 ratio…)"], ["GET /api/v1/trending?hours=24", "Trending entities"], ["GET /api/v1/explore", "Explore aggregates"], ["GET /api/v1/health/connectors", "Connector health, throughput, engine heartbeat, failing domains, slowest sensors"], ["GET /api/v1/feed.rss", "RSS 2.0 of the latest events (same filters as /events)"], ["WSS /api/v1/live", "Real-time event stream, protocol 2 (replayable)"], ]; const OWNER: [string, string][] = [ ["GET/POST/PUT/DELETE /api/v1/watchlists", "Watchlists; item kinds entity · source · keyword · category · url · event_type · country · group. GET /watchlists/{id}/events"], ["GET/POST/PATCH/DELETE /api/v1/alerts", "Alert rules {name, rule, channel: web|webhook, channel_config: {url, secret}}. PATCH {enabled, name}. Webhooks: https only, public hosts only"], ["GET /api/v1/notifications?limit=&unread=1", "Deliveries of your rules with event summary; POST /notifications/read {ids?} marks read (all when omitted)"], ["GET/POST/DELETE /api/v1/bookmarks", "Saved events {event_id, note?}; GET /bookmarks/ids for a quick membership check"], ["GET/POST/DELETE /api/v1/views", "Saved live-feed views {name, query} where query is a /live query string"], ["GET/POST/DELETE /api/v1/monitors", "Custom URL monitors {url, name?, frequency: hourly|daily, sensitivity: low|normal|high, selector?, keywords?}; GET /monitors/{id}/events. 5 per owner"], ]; const FILTERS: [string, string][] = [ ["after · before", "ISO-8601 bounds on detected_at"], ["category · group", "Category slug (ai, cyber…) · event group (security, reliability, product, commercial, corporate, government, science, transport, sports, web)"], ["event_type", "Comma list of event types"], ["entity · source · domain · sensor · cluster", "Scope to one id"], ["importance_min · confidence_min · signal_min", "Score floors (0–100)"], ["silent_change · first_party · confirmed", "Booleans (true)"], ["country · language · change_class", "ISO-2 country (CA, US, EU…) · language code · semantic class (pricing, policy, product, personnel, meaningful…)"], ["q", "Free text + search syntax (right)"], ["order · limit · cursor", "recent (default) | importance | signal · ≤ 200 · opaque nextCursor"], ]; export default function ApiPage() { const base = SITE_URL; const wss = base.replace(/^http/, "ws"); return ( <>
{PUBLIC.map(([ep, desc]) => ( ))}
{ep} {desc}
Owner-scoped endpoints · header X-WebSensor-Owner: <16–80 chars [A-Za-z0-9_-]>} dense> {OWNER.map(([ep, desc]) => ( ))}
{ep} {desc}

No accounts yet: the token is your identity. Anyone holding it can read and edit these resources. Webhook deliveries are signed when a secret is set: X-WebSensor-Signature: sha256=<HMAC-SHA256(secret, raw body)>.

{FILTERS.map(([k, v]) => ( ))}
{k} {v}

Strongest signals of the last 48 h, first-party only:

{`curl "${base}/api/v1/events?signal_min=80&first_party=true&order=signal&after=$(date -u -v-48H +%FT%TZ)"`}

Silent pricing / terms changes in the commercial group:

{`curl "${base}/api/v1/events?silent_change=true&group=commercial&change_class=pricing"`}

Everything from Canada in the government category, counted:

{`curl "${base}/api/v1/events/count?country=CA&category=government"`}

Search syntax (same as the ⌘K palette):

{`curl "${base}/api/v1/search?q=$(printf %s 'openai pricing type:pricing_change signal:>70 after:2026-09-01' | jq -sRr @uri)"`}

Cluster with propagation timeline and lead time:

{`curl "${base}/api/v1/clusters/" | jq '{lead_time_ms, first_party_signals, external_signals, propagation: .propagation[:3]}'`}

Create a signed webhook alert (owner token = any 16–80 char string you keep):

{`curl -X POST "${base}/api/v1/alerts" \\ -H "content-type: application/json" -H "X-WebSensor-Owner: $OWNER" \\ -d '{"name":"Critical security","rule":{"groups":["security"],"signal_min":80,"first_party_only":true}, "channel":"webhook","channel_config":{"url":"https://example.com/hooks/ws","secret":"…"}}'`}

Subscribe an RSS reader:

{`${base}/api/v1/feed.rss?signal_min=60&group=reliability`}
{`{ "id": "evt_…", "slug": "openai-api-pricing-changed-…", "event_type": "pricing_change", "change_class": "pricing", "title": "OpenAI: price changed $10 / million tokens → $8 / million tokens", "summary": "…", "why_it_matters": "…", "signal_score": 91, "importance": 88.2, "confidence": 98.1, "novelty": 87.4, "impact_score": 85, "velocity_score": 40, "anomaly_score": 12, "score_reasons": [{ "sign": "+", "text": "First-party source", "points": 8 }, { "sign": "-", "text": "Single source so far", "points": -5 }], "importance_components": { "severity": 82, "source": 92, "entity": 92, "novelty": 87, "magnitude": 40, "confirmation": 0, "userImpact": 85, "unusualness": 30 }, "field_changes": [{ "label": "gpt-4o input", "kind": "price", "before": "$10.00", "after": "$8.00", "deltaPct": -20 }], "categories": ["ai", "technology"], "keywords": ["pricing"], "silent_change": true, "first_party": true, "country": "US", "language": "en", "evidence_label": "OBSERVED", "url": "https://openai.com/api/pricing/", "published_at": null, "observed_from": "…", "detected_at": "…", "processed_at": "…", "detection_latency_ms": null, "processing_latency_ms": 412, "cluster": { "id": "clu_…", "slug": "openai-pricing-…", "state": "developing", "event_count": 3, "source_count": 2, "first_party_count": 1, "external_count": 2, "velocity": 61, "lead_time_ms": 5400000 }, "change_id": "chg_…", "old_snapshot_id": "snap_…", "new_snapshot_id": "snap_…", "source": { "id": "openai", "name": "OpenAI", "domain": "openai.com", "tier": "S" }, "sensor": { "id": "openai_pricing", "name": "pricing", "type": "HTML", "connector": "http" }, "entities": [{ "id": "org_openai", "name": "OpenAI", "type": "organization", "role": "subject" }] }`}
); }