← Addonium

8. HTTP API Reference

All endpoints below apply to HTTP addons (Open or Locked). For Locked addons, prefix every path with the token segment per §7, or send the configured header/param per §6.2.

EndpointRequiredResource flagPurpose
GET /manifest.jsonYes-Addon identity & capabilities
GET /search?q=recommendedsearchSearch results
GET /stream/:idrecommendedstreamResolve a playable URL
GET /album/:idNocatalogAlbum detail + tracklist
GET /artist/:idNocatalogArtist detail + top tracks
GET /playlist/:idNocatalogPlaylist detail + tracks
GET /lyrics?artist=&title=NolyricsLyrics (plain or LRC)
GET /resolve-isrc?isrc=NoisrcExact id lookup by ISRC/UPC-equivalent
GET /resolve?title=&artist=&durationMs=NoresolveBest-match id for a generated queue item
GET /catalog/:rowId?skip=NocatalogA declared home/browse row, paged by 100
`GETPOSTDELETE /libraries...`No
Settings values-settingsAppended as query params on every call

Response shapes below mirror the Eclipse/BeatBoss conventions so existing addon authors can port with near-zero changes.

8.1 GET /search?q=&limit=

{
  "tracks": [
    {
      "id": "track_101",
      "title": "Starlight Harmony",
      "artist": "Echo Voyager",
      "album": "Celestial Echoes",
      "duration": 240,
      "artworkURL": "https://example.com/star.jpg",
      "isrc": "USRC12345678",
      "format": "mp3",
      "streamURL": null
    }
  ],
  "albums": [],
  "artists": [],
  "playlists": []
}

All four arrays are optional - return only what you have. streamURL, if present, lets the host skip the /stream/:id round-trip entirely.

8.2 GET /stream/:id

{
  "url": "https://cdn.example.com/audio/track_101.mp3",
  "format": "mp3",
  "quality": "320kbps",
  "codec": "mp3",
  "container": "mp3",
  "manifest": "none",
  "expiresAt": 1767225600,
  "encrypted": false
}
FieldNotes
urlRequired. Direct HTTP(S) link to the audio/video/manifest resource. No HTML pages, no login walls.
formatFree-text container/file hint, e.g. mp3, flac, aac, m4a, opus, ogg, wav, m3u8, mpd.
codec / container / manifestOptional routing hints so the host doesn't have to probe the file - see §8.2.1 below.
qualityFree-text, e.g. "320kbps", "lossless", "Dolby Atmos"
expiresAtUnix timestamp; host re-fetches /stream/:id after this.
chaptersOptional array of { title, startTime } for audiobook/podcast content.
drmOptional object describing content protection on the stream - see §8.2.1. Omit entirely for unprotected content.
videoOptional object per Eclipse's video model - { url, mimeType, muxed, width, height, renditions[] } - for addons with visual content.

8.2.1 Streaming formats are open-ended

The url an addon returns is not limited to a flat audio file. Addonium places no ceiling on what a stream can be - the fields below are hints, not a whitelist. A host is expected to fall back to sniffing the resource (by extension, Content-Type, or magic bytes) when it receives a codec/container/manifest value it doesn't recognize, rather than rejecting the stream outright.

Supported today, non-exhaustively:

  • Plain files: mp3, aac, flac, alac, wav, ogg/vorbis, opus.

  • Adaptive manifests: manifest: "hls" for an .m3u8 (played via native AVPlayer/ExoPlayer support or hls.js), manifest: "dash" for an .mpd (played via dash.js, Shaka Player, etc.).

  • Multi-channel / spatial audio: codec values like eac3, eac3_joc (Dolby Digital Plus / Dolby Atmos-in-JOC), ac3, truehd, dts. These typically ride inside an HLS or DASH manifest rather than a bare file - set manifest accordingly and let codec carry the finer-grained detail.

  • Low-latency / chunked-transfer live streams: manifest: "hls" with a live (non-VOD) playlist, or a raw chunked url with no manifest at all - a host should treat an endless/growing response as valid.

  • DRM-protected streams (optional, and orthogonal to §6's addon-level auth): when present, a drm object tells the host which system and key endpoint to use, e.g.:

    {
      "url": "https://cdn.example.com/stream.mpd",
      "manifest": "dash",
      "drm": {
        "system": "widevine",
        "licenseUrl": "https://license.example.com/widevine",
        "headers": { "Authorization": "Bearer ..." }
      }
    }
    

    system is free-text (widevine, playready, fairplay, clearkey, or anything a host's player happens to support); a host that can't fulfill the requested DRM system should skip the stream rather than attempt playback.

  • Anything else: an addon may return a codec/container/manifest combination not listed here at all. The contract is only that url points at something a modern media pipeline (native player, hls.js, dash.js, Shaka Player, or similar) can be handed directly - Addonium itself has no opinion on which formats exist, only on how a stream response is shaped once you've picked one.

Because of this, codec, container, manifest, and format are intentionally typed as free-text strings in the JSON Schema rather than closed enums - new formats (a future codec, a new manifest type) are automatically valid without a spec revision.

8.3 GET /album/:id · GET /artist/:id · GET /playlist/:id

Same detail-object shapes as Eclipse's catalog endpoints: an entity object plus a tracks (or topTracks/albums) array of the same track shape used in /search.

8.4 GET /lyrics?artist=&title=

Returns either a raw string (LRC recommended) or { "lyrics": "..." }.

8.5 GET /resolve-isrc?isrc=

{ "trackId": "track_101" }

Return 404 or { "trackId": null } if unknown. Never guess - a wrong answer here is treated as authoritative by the host.

8.6 GET /resolve?title=&artist=&durationMs=&isrc=

{ "item": { "id": "track_101", "type": "track", "title": "...", "artist": "..." } }

Return { "item": null } with 200 when there's no confident match.

8.7 Library Sync (resources: ["library"])

MethodPathBody
GET/libraries-
POST/libraries{ "name": "..." }
GET/libraries/:id-
POST/libraries/:id/sync{ "tracks": [...] }
POST/libraries/:id/remove{ "trackId": "..." }
POST/libraries/:id/update{ "name": "..." }
DELETE/libraries/:id-

Library ID 1 is reserved for Favourites and cannot be renamed/deleted. Library sync is inherently a "stores data" feature - an addon exposing it SHOULD set "storesData": true (§11) so hosts can disclose that to users.

8.8 Settings (resources: ["settings"])

Declared in the manifest:

{
  "settings": [
    {
      "key": "quality",
      "type": "select",
      "label": "Audio quality",
      "default": "high",
      "options": [
        { "value": "high", "label": "High (320kbps)" },
        { "value": "low", "label": "Low (96kbps)" }
      ]
    },
    { "key": "preferOpus", "type": "toggle", "label": "Prefer Opus", "default": true }
  ]
}

Field types: select (with options), toggle, text (maxLength, placeholder), number (min, max, step). Values are appended as query parameters, using the key verbatim, on every request:

GET /t/{token}/stream/abc123?quality=high&preferOpus=true

8.9 Catalogs (resources: ["catalog"], catalogs in manifest)

{ "catalogs": [ { "id": "top", "type": "track", "name": "Top Tracks" } ] }
GET /catalog/top?skip=0
{ "items": [ { "id": "...", "type": "track", "title": "...", "artist": "..." } ] }

skip is always a multiple of 100; returning fewer than 100 items signals the end of that row.