Skip to main content

Internal Worker endpoints

Not a public API
These endpoints exist only to serve the NovaReport web app. They reject requests from other origins and are not supported for third-party use. NovaReport does not currently offer a public API.
Method & pathPurpose
GET /healthUptime check
GET /gnews?endpoint=top-headlines|search&…GNews, proxied
GET /gdelt?q=…&max=…GDELT, proxied
GET /unsplash?query=…Fallback image
POST /newsletterNewsletter sign-up
GET /api/healthWhich application services are configured (database, Clerk, webhooks, NewsData, key encryption) — never their values
GET /api/news/cached?category=&limit=Articles the Worker served in the last 14 days (fallback when every live provider fails)
GET /api/newsdata?…NewsData, proxied; configured: false when the Worker has no key
GET, PATCH /api/meThe signed-in reader's account record (role, display name). Requires a Clerk session token
/api/admin/providers, /keys, /logs, /blocklists/sources|keywords, /overrides, /test-requestAdmin console. Clerk session token and the admin role in the database, checked on every call; every change is audited
POST /api/webhooks/clerkClerk user events, Svix-signed

/api/* answers JSON errors as { "error": "<code>", "message": "<text>", "requestId": "<id>" }. Routes that need a service that is not connected yet answer 503 (database_not_configured, auth_not_configured).

When GNews or GDELT fail (429/5xx) on a feed request, /gnews and /gdelt answer 200 with the last good copy and the headers X-NovaReport-Stale (ISO time it was saved) and X-NovaReport-Upstream-Status (the provider's status). Searches are never served from that copy.

All articles are normalized into one shape (UnifiedArticle: title, description, url, image, publishedAt, source) before display.