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 (
<>
| {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)>.
| {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" }]
}`}