API
API
All JSON endpoints emit access-control-allow-origin: *. Read-only; no auth required.
List recent events
GET /api/events?limit=50&offset=0&kind=news&category=Politics
curl 'https://gaithernews.com/api/events?limit=10'
Single event detail
GET /api/events/:id : returns { event, articles }.
curl 'https://gaithernews.com/api/events/abc123'
Server-rendered card HTML
GET /api/events-html?kind=news&offset=20&limit=20&category=Recipes
The optional category param pre-filters server-side so a single-category load-more reaches older events without paging through everything. Image-less events are filtered out automatically (matches the home page).
Or fetch by ids: GET /api/events-html?ids=id1,id2,id3
curl 'https://gaithernews.com/api/events-html?limit=5'
Bump view counter
POST /api/events/:id/view : idempotent at the network level (always +1); the home-page client dedupes per session.
curl -X POST 'https://gaithernews.com/api/events/abc123/view'
Lazy analysis layers
Generated on first request, then cached on the event row. The story layer uses Haiku (~5–10s); the rest use Sonnet (~15–25s).
GET /api/events/:id/story: long-form narrative expansion of the neutral summary (Haiku)GET /api/events/:id/differences: per-outlet forensic framing breakdownGET /api/events/:id/cynic: cynical-realism deep readGET /api/events/:id/money: forensic financial / power-routing analysisGET /api/events/:id/prior-left: "Previously, the left said" — framing pattern from real past coverage by left-leaning outletsGET /api/events/:id/prior-right: "Previously, the right said" — same idea, mirrored
curl 'https://gaithernews.com/api/events/abc123/cynic'
Operational triggers
GET /run: full ingest cycle (fetch all sources + cluster + synthesize)GET /run-source/:id: refetch a single source synchronouslyGET /run-cluster: cluster + synthesize over what's in DB (cap 6 per invocation)GET /run-cluster-big: same as /run-cluster but with cap 12 for manual backlog drainGET /run-dedup: dedup pass only, no synthesisGET /run-all: fan out fetch across all sources, then clusterGET /health: returnsok