A small API. No extension runtime.
OpenTune uses the BitChord HTTP add-on contract. Users add your service root or manifest.json URL in Settings → Audio → Audio add-ons. No executable package is installed.
The starter is a Cloudflare Worker with a small configurable catalog, CORS support and tests. It starts with an empty catalog; add your own audio URLs and their measured metadata before deploying.
cd examples/audio-addon
node --test worker.test.mjs
npx wrangler deployConfigure CATALOG in wrangler.toml. Keep signed audio URLs short-lived and generate them at stream resolution if your service needs that. The example catalog is intended for a small collection; use a database for a larger service.
The three endpoints
GET /manifest.json
{
"id": "org.example.catalog",
"name": "My audio catalog",
"version": "1.0.0",
"resources": ["search", "stream"],
"allowDownloads": true,
"checkValidLossless": false,
"settings": [{
"key": "quality", "default": "lossless",
"options": [{"label": "Best available FLAC", "value": "lossless"}]
}]
}Use a stable, unique ID. allowDownloads: false excludes your source from file downloads. checkValidLossless: true requires a supported wired, USB or HDMI output before OpenTune queries your service. Bluetooth and unknown outputs do not qualify.
GET /search?q=title%20artist&quality=lossless
{"tracks": [{
"id": "recording-42", "title": "Example Song",
"artist": "Example Artist", "album": "Example Album",
"duration": 203, "format": "flac",
"artwork": "https://cdn.example.org/cover.jpg"
}]}Duration is in seconds. Return the real title and credited performers, including version labels such as live or remix. OpenTune checks recording identity and duration; the first search result is not automatically accepted. No match should return {"tracks":[]}.
GET /stream/recording-42?quality=lossless
{
"url": "https://cdn.example.org/recording-42.flac",
"codec": "flac", "format": "flac", "manifest": "none",
"sampleRate": 96000, "bitDepth": 24,
"encrypted": false
}IDs are opaque and URL-encoded as one path segment. sampleRate is in Hz; bitrate, if supplied, is in bits per second. For unencrypted segmented playback use manifest: "hls" or "dash". File downloads currently require a direct audio file.
Describe the audio you actually serve.
Lossless describes the encoding, not a promise about the original master. Do not relabel AAC or MP3 as FLAC, upsample to claim higher resolution, or advertise 24-bit/192 kHz for every track.
ffprobe -v error -select_streams a:0 \
-show_entries stream=codec_name,sample_rate,bits_per_raw_sample \
-of json recording.flacOpenTune reads direct FLAC headers and uses the playback decoder's format for the quality display. HLS/DASH renditions must contain supported lossless audio; encrypted audio is unsupported. Browser codec support differs from Android.
Make delivery reliable.
| Concern | Expected behavior |
|---|---|
| Transport | Public HTTPS endpoints, including redirects and media URLs. Local/private destinations are rejected by the Android addon transport. |
| Browser access | Enable CORS on API responses, audio, manifests and every segment. Support OPTIONS. Public unauthenticated services can use Access-Control-Allow-Origin: *. |
| Seeking | Support Range requests and HTTP 206 with correct Content-Range and Content-Length for direct files. |
| Rate limits | Return HTTP 429 with Retry-After. OpenTune applies a bounded cooldown and tries another enabled source. |
| Failures | Use a suitable HTTP status and {"error":"A safe explanation"}. Never return an HTML error document as audio. |
| Response size | Keep JSON small; the Android client limits metadata responses to 2 MiB and downloads to 512 MiB. |
| Expiration | Stream responses may be cached for five minutes. Keep URLs valid for playback and seeking beyond that window, or return a renewable stable URL. |
Configured URL paths and query parameters are preserved locally. They are not safe places for credentials intended to stay secret from your users. OpenTune does not attach its Google session or other app cookies to addon requests.
Test it, then share the URL.
- Run the starter tests and check all three endpoints.
- Add your manifest in OpenTune and use Check to inspect its availability.
- Select Lossless quality, play a known recording, and inspect Signal path. Check a non-match, a timeout and an expired URL too.
- Test downloads, seeking and playback on the intended devices. Inspect the file with ffprobe instead of relying on its extension.
- Share the manifest URL and source code with your community. Document region limits, costs, authentication and availability.