Issue Nº 37 — Sep 19, 2026
This radio API's docs page and its data live on different hosts
Issue thirty-seven covers Radio Browser, the keyless directory of internet radio stations. This session queried it live. The address in the catalogue serves a docs page, not the API. A missing country returns an empty list, not an error. And one GET request has a side effect: it logs a listener click for the station.
The catalogue address serves docs, not data
GET https://api.radio-browser.info/, queried live this session, returned 200 with an HTML page titled "API.radio-browser.info docs".
GET https://api.radio-browser.info/json/stats, the same host with an API path, returned 404 with an HTML body, not JSON.
GET https://de1.api.radio-browser.info/json/stats, one of the mirror hosts, returned 200 with real data: {"stations":59271,"stations_broken":6718,"tags":12264,"languages":666,"countries":241}.
A caller must resolve a mirror host first. The address in this catalogue's url field is correct for docs, but it never answers a data query.
Every response carries an open CORS header, even the empty ones
GET /json/stations/bycountry/Absurdistan, an unknown country queried live this session, returned 200 with an empty array, not a 404.
GET /json/nosuchpath, an unrecognized route, returned 404 with a zero-byte body.
Both responses, and every other JSON and XML response this session queried, carried access-control-allow-origin: * and server: tiny-http (Rust).
A caller cannot use the HTTP status code to tell a bad country from an empty result. Only the array length says which one happened.
One GET request logs a listener click, and the mirror list only names itself
GET /json/url/<station-uuid>, queried live this session against a French station, returned 200 with the station's stream URL and a message field: "retrieved station url". The response also carried cache-control: no-cache, no-store, must-revalidate.
That endpoint is the one Radio Browser documents for players to call before they start streaming. Calling it also counts as a click for that station, so a plain read request changes the station's click count.
GET /json/servers, queried live this session against the de1 mirror, returned only de1's own two addresses, one IPv4 and one IPv6, not the full round-robin mirror list.
A caller who expects that endpoint to discover other mirrors gets one server's own address back instead.