Open Radio Player Developer API
Public JSON API docs for Open Radio Player station health, telemetry, system status, and station catalog feeds for apps, 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, and recent health metrics.
- `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 90): 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 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 `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, defaultStreamId, streamCount, streams}'
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",
"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.