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.

Radio Browser, by the numbers

Rendered live from the atlas entry
AuthenticationNone required
HTTPSSupported
CORSEnabled
PricingFree
FormatsJSON, XML, M3U
radiostreamingopen-datakeyless

Sources

Facts checked Sep 2026