Issue Nº 44 — Sep 26, 2026
A missing item answers 200 and null, not 404
Issue forty-four covers hackernews, the keyless Firebase-backed feed of Hacker News items and users in the Social category. This session queried it live. A missing item id returns HTTP 200 with a null body, while an unknown path returns a Firebase security-rule 401. CORS echoes back whatever Origin header the caller sends, and a preflight admits PUT, POST, DELETE, and PATCH even though the API only ever answers reads.
A missing item is 200 and null; an unknown path is 401
This session sent GET https://hacker-news.firebaseio.com/v0/item/999999999999.json, an id far past any item that exists. It returned HTTP 200 with a body of exactly null, not a 404.
This session then sent GET https://hacker-news.firebaseio.com/v0/nosuch.json, a path the API never defines. It returned HTTP 401 with the body {"error": "Permission denied"}.
That 401 is a Firebase Realtime Database security-rule answer, not a not-found response. The API sits directly on a Firebase database, and Firebase rejects reads outside the paths its rules expose before any Hacker News-specific code runs. A client that treats every non-200 as "item not found" will misreport a 401 as a missing item, when it actually means the path itself is not one Firebase will serve.
CORS echoes the Origin; a preflight allows writes the API never accepts
This session sent GET https://hacker-news.firebaseio.com/v0/item/1.json with an Origin: https://example.com header. The response carried access-control-allow-origin: https://example.com, an echo of the exact origin sent, not a wildcard *.
This session then sent an OPTIONS preflight to the same URL with Access-Control-Request-Method: PUT. It returned HTTP 200 with Access-Control-Allow-Methods: OPTIONS,GET,POST,PUT,DELETE,PATCH, allowing every HTTP method even though the Hacker News API is read-only.
This session confirmed the API itself refuses those methods: a PUT to https://hacker-news.firebaseio.com/v0/item/1.json returned the same HTTP 401 {"error": "Permission denied"} as the unknown-path probe. The generous CORS preflight is Firebase's default database behavior, not a promise the Hacker News rules keep.
User ids are case-sensitive, and topstories caps at exactly 500
The README describes the v0 API as "essentially a dump of our in-memory data structures" with no built-in comment counts; a caller has to walk each item's kids array and count nodes itself to total up a discussion.
This session sent GET https://hacker-news.firebaseio.com/v0/user/pg.json. It returned a full profile with karma 157316. The same request against /v0/user/PG.json returned null: user ids are case-sensitive, exactly as the README states.
This session sent GET https://hacker-news.firebaseio.com/v0/topstories.json. It returned exactly 500 story ids, matching the README's "up to 500" cap. GET https://hacker-news.firebaseio.com/v0/maxitem.json returned 49855729, the current highest item id. Every response in this session carried cache-control: no-cache, and a burst of about ten back-to-back item requests hit no rate limit, matching the README's claim that none currently exists.
HackerNews, by the numbers
- GET/item/{id}.json
- GET/topstories.json
- GET/user/{id}.json