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

  1. Start with `/api/v1/stations/healthy` when you want reliable defaults and smaller payloads.
  2. Use `/api/v1/stations/telemetry` when you want the full stream-variant feed, including at-risk rows.
  3. Check `/api/v1/system/status` before demos, cron jobs, or agent tasks that depend on fresh data.
  4. 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.