Open Radio Player Developer API
Public JSON API docs for station health, stream telemetry, system status, and station catalog feeds for apps, dashboards, games, and AI agents.
Live API Status | OpenAPI Schema | LLM Guide | Power Docs API Section
Who This Helps
- Apps that need a smaller set of recent, reliable radio streams without running their own monitor.
- Games and companion experiences that want compatibility flags and low-latency stream selection.
- AI agents that need explicit filters, freshness timestamps, and a stable station catalog.
- Dashboards, scripts, and automations that need pipeline health plus stream-level telemetry.
Quick Start
- Start with `/api/v1/stations/healthy` when you want reliable defaults and smaller payloads.
- Use `/api/v1/stations/telemetry` when you want the full stream-variant feed, including at-risk rows.
- Check `/api/v1/system/status` before demos, cron jobs, or agent tasks that depend on fresh data.
- Join `/api/v1/stations/index.json` with live telemetry by `streamId` or `defaultStreamId` when you need both catalog metadata and health.
Integration Notes
- Authentication: None. The current public API is read-only and does not require an API key.
- CORS: JSON endpoints send `Access-Control-Allow-Origin: *` and allow `GET, OPTIONS`.
- Formats: API responses are UTF-8 JSON. The `/api` landing page is HTML and intended for humans.
- Freshness: Check `generatedAt` and `telemetryGeneratedAt` before acting on results or surfacing them to users.
- Cache behavior: Healthy and telemetry responses use `public, s-maxage=60, stale-while-revalidate=300`. System status uses `no-store, max-age=0`. The station catalog is static build output.
- Selection semantics: The healthy endpoint applies database-side health gates first, then compatibility filters, then trims to `limit`.
Key Resources
- Developer Docs: Search-friendly reference page for apps, games, AI agents, and integrations.
- Live API Status: Human-readable API landing page with live health checks and endpoint links.
- OpenAPI Schema: Machine-readable contract for the public JSON endpoints.
- LLM Guide: Compact endpoint and integration guide for agents and retrieval systems.
Healthy stations
Path: /api/v1/stations/healthy
Recommended starting endpoint for apps, games, AI agents, widgets, and external clients that want recent playable streams.
Method: GET | Auth: None | Cache: public, s-maxage=60, stale-while-revalidate=300
Ordering: Sorted by score desc, availabilityPercent desc, averageStartupLatencyMs asc, then streamId asc.
Highlights
- Echoes the effective filters in `filters` so downstream clients can log exactly what was applied.
- Each item includes `stationId`, `defaultStreamId`, `streamId`, compatibility fields, recent health metrics, and optional `loudnessProfile` data.
- `count` reflects the final filtered set after compatibility checks and `limit` are applied.
Parameters
status(string, default healthy): Health band to query. Defaults to `healthy`.genre(string, default none): Optional genre filter such as `jazz`, `indie`, or `classical`.stationId(string, default none): Optional parent-station filter when you want all variants for one station.limit(integer, default 50): Maximum rows returned. Clamped to `1..200`.minScore(integer, default 86): Minimum health score required for a row to survive the first filter pass.maxStartupLatencyMs(integer, default 1500): Maximum acceptable average startup latency.minAvailabilityPercent(integer, default 80): Minimum rolling availability percentage.maxConsecutiveFailures(integer, default 0): Maximum allowed consecutive probe failures.maxAgeMinutes(integer, default 20): Rejects telemetry older than this threshold.streamType(string, default none): Compatibility filter such as `hls`, `mp3`, `aac`, or `direct`.streamTransport(string, default none): Transport filter: `direct` or `hls`.audioFormat(string, default none): Optional codec/container hint such as `mp3`, `aac`, `ogg`, `opus`, or `flac`.supportsNativeAudio(boolean, default none): Filter for clients that require direct/native browser audio playback.supportsHlsPlayback(boolean, default none): Filter for clients that specifically want HLS-capable rows.
Example Request
curl 'https://openradioplayer.com/api/v1/stations/healthy?genre=jazz&limit=12&minScore=90&maxStartupLatencyMs=1200&maxAgeMinutes=20&supportsNativeAudio=true'
Response Excerpt
{
"ok": true,
"generatedAt": "2026-03-21T19:11:52.654Z",
"telemetryGeneratedAt": "2026-03-21T19:02:19.000Z",
"filters": {
"status": "healthy",
"genre": "jazz",
"limit": 12,
"minScore": 90,
"maxStartupLatencyMs": 1200,
"maxAgeMinutes": 20,
"supportsNativeAudio": true
},
"count": 12,
"items": [
{
"streamId": "kcsm--hd2-aac",
"stationId": "kcsm",
"defaultStreamId": "kcsm",
"streamLabel": "HD2 AAC+",
"streamType": "aac",
"streamTransport": "direct",
"supportsNativeAudio": true,
"supportsHlsPlayback": false,
"status": "healthy",
"score": 100,
"availabilityPercent": 100,
"averageStartupLatencyMs": 1186
}
]
}
Telemetry feed
Path: /api/v1/stations/telemetry
Full stream-variant telemetry feed used by the site itself, including healthy and at-risk rows plus detailed timing and failure counters.
Method: GET | Auth: None | Cache: public, s-maxage=60, stale-while-revalidate=300
Ordering: Sorted by genre asc, stationName asc, then streamId asc.
Highlights
- Returns startup attempts, successes, failures, reconnect counts, buffering events, and recent failure timestamps.
- Useful for ranking, debugging, dashboards, or agent workflows that need the full health window instead of just healthy rows.
- If you only need a filtered shortlist, prefer `/api/v1/stations/healthy` to reduce payload size and client-side work.
Parameters
stationId(string, default none): Optional parent-station filter that returns all known variants for a station.
Example Request
curl 'https://openradioplayer.com/api/v1/stations/telemetry?stationId=krtu'
Response Excerpt
{
"ok": true,
"generatedAt": "2026-03-21T19:11:52.757Z",
"telemetryGeneratedAt": "2026-03-21T19:02:19.000Z",
"filters": {
"stationId": "krtu"
},
"count": 2,
"items": [
{
"streamId": "krtu--mp3",
"stationId": "krtu",
"streamLabel": "MP3 128",
"status": "healthy",
"score": 96,
"startupAttempts": 183,
"averageStartupLatencyMs": 161,
"playbackFailures": 0,
"reconnects": 0,
"lastFailureReason": null
}
]
}
System status
Path: /api/v1/system/status
Machine-readable heartbeat for the full monitor -> database -> production API pipeline.
Method: GET | Auth: None | Cache: no-store, max-age=0
Ordering: Not ordered. Single object response.
Highlights
- Includes freshness thresholds, summary metrics, named checks, and the canonical endpoint URLs.
- Returns HTTP 200 when healthy, HTTP 503 when the system is degraded but still able to report status, and HTTP 500 on unexpected failures.
- Useful as a lightweight readiness gate before agent jobs or external fetches.
No query parameters.
Example Request
curl 'https://openradioplayer.com/api/v1/system/status' | jq
Response Excerpt
{
"ok": true,
"status": "ok",
"generatedAt": "2026-03-21T19:11:53.374Z",
"thresholds": {
"freshTelemetryMinutes": 30,
"staleTelemetryMinutes": 60
},
"summary": {
"telemetryGeneratedAt": "2026-03-21T19:02:19.000Z",
"telemetryAgeMinutes": 9.6,
"healthyStations": 63,
"averageScore": 95
},
"checks": {
"database": {
"ok": true,
"level": "ok",
"detail": "Connected and queried successfully."
}
},
"endpoints": {
"landingPage": "https://openradioplayer.com/api",
"healthyStations": "https://openradioplayer.com/api/v1/stations/healthy"
}
}
Station catalog
Path: /api/v1/stations/index.json
Static station catalog published by the production site build, including per-station stream variants, city-level coordinates, and compatibility hints.
Method: GET | Auth: None | Cache: public, max-age=0, must-revalidate
Ordering: Build output order from the generated station catalog.
Highlights
- Includes `version`, `generatedAt`, `count`, `streamVariantCount`, and `items[]`.
- Each station row exposes `city`, city-level `coordinates`, `defaultStreamId`, `streamCount`, `stream`, and `streams[]`.
- Join catalog rows with telemetry by `streamId` to combine stable metadata with live health observations.
No query parameters.
Example Request
curl 'https://openradioplayer.com/api/v1/stations/index.json' | jq '.items[0] | {id, city, coordinates, defaultStreamId, streamCount}'
Response Excerpt
{
"version": 1,
"generatedAt": "2026-03-20T17:29:20.836Z",
"count": 71,
"streamVariantCount": 73,
"items": [
{
"id": "cfmz",
"stationId": "cfmz",
"stationName": "CFMZ 96.3 - Toronto, ON",
"city": "Toronto, ON",
"coordinates": {
"latitude": 43.6532,
"longitude": -79.3832,
"precision": "city",
"label": "Toronto, ON"
},
"defaultStreamId": "cfmz",
"streamCount": 1,
"streams": [
{
"id": "cfmz",
"label": "Primary",
"transport": "direct",
"supportsNativeAudio": true,
"supportsHlsPlayback": false
}
]
}
]
}
Error Model
- 200: Successful response.
- 405: Method not allowed. Use `GET` for reads and `OPTIONS` for CORS preflight.
- 500: Unexpected server or data source failure.
- 503: The system status endpoint can return degraded-but-readable data with HTTP 503 when the pipeline is unhealthy.