Sonus Manifest v1.0-draft
A Sonus Manifest is one JSON file, usually called sonus.json, that lists the tracks, albums,
artists and playlists in a library and says where each audio file lives. Host it next to your
music on any static file host, then give Sonus its URL.
- JSON Schema:
/schemas/v1/manifest.schema.json(draft 2020-12). Add"$schema"to your file to get validation and autocompletion in editors. - Media type: serve it as
application/json.
Smallest valid manifest
{
"sonus": "1.0",
"library": {
"id": "my-music",
"name": "My Music"
},
"tracks": [
{
"id": "t1",
"title": "First Light",
"url": "music/first-light.mp3"
}
]
}
Full example
{
"$schema": "https://moantage.github.io/sonus/schemas/v1/manifest.schema.json",
"sonus": "1.0",
"library": {
"id": "living-room-nas",
"name": "Living-room NAS",
"description": "Ripped CDs and Bandcamp purchases.",
"updatedAt": "2026-10-11T18:30:00Z"
},
"baseUrl": "https://music.example.com/library/",
"artists": [
{
"id": "ar-aurora-lane",
"name": "Aurora Lane",
"artwork": "artists/aurora-lane.jpg"
}
],
"albums": [
{
"id": "al-night-drive",
"title": "Night Drive",
"artist": "Aurora Lane",
"artistId": "ar-aurora-lane",
"year": 2024,
"genre": "Synthwave",
"artwork": "albums/night-drive/cover.jpg"
}
],
"tracks": [
{
"id": "tr-night-drive-01",
"title": "Neon Overpass",
"url": "albums/night-drive/01-neon-overpass.mp3",
"artist": "Aurora Lane",
"artistId": "ar-aurora-lane",
"album": "Night Drive",
"albumId": "al-night-drive",
"trackNumber": 1,
"discNumber": 1,
"duration": 214.6,
"mimeType": "audio/mpeg",
"size": 8583680,
"bitrate": 320,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"genre": "Synthwave",
"year": 2024,
"addedAt": "2026-09-30T09:12:00Z"
},
{
"id": "tr-night-drive-02",
"title": "Tail Lights",
"url": "https://cdn.example.com/night-drive/02-tail-lights.flac",
"artist": "Aurora Lane",
"artistId": "ar-aurora-lane",
"album": "Night Drive",
"albumId": "al-night-drive",
"trackNumber": 2,
"duration": 248,
"mimeType": "audio/flac"
}
],
"playlists": [
{
"id": "pl-late-night",
"name": "Late Night",
"description": "Low lights, long roads.",
"trackIds": [
"tr-night-drive-02",
"tr-night-drive-01"
]
}
]
}
Top-level fields
| Field | Required | Type | Notes |
|---|---|---|---|
sonus | yes | string | Spec version, e.g. "1.0". Apps accept any 1.x. |
library | yes | object | id and name are required. updatedAt lets apps skip unchanged manifests. |
tracks | yes | array | Can be empty. |
baseUrl | no | absolute URL | Base for relative URLs. Defaults to the manifest's own URL. |
albums, artists, playlists | no | arrays | Optional groupings that reference tracks by ID. |
Track fields
| Field | Required | Notes |
|---|---|---|
id | yes | Stable ID. See IDs. |
title | yes | |
url | yes | Absolute URL or path relative to baseUrl. The host should support HTTP range requests. |
artist, album | no | Display names. |
artistId, albumId | no | Must match an entry in artists / albums. |
trackNumber, discNumber | no | Integers starting at 1. |
duration | no | Seconds. Lets the app show times before the file loads. |
mimeType | no | audio/mpeg, audio/mp4, audio/flac, audio/wav… |
size | no | Bytes. Used for download progress and storage estimates. |
bitrate | no | Average kbit/s. |
sha256 | no | Lowercase hex. Lets the app verify downloads and notice changed files. |
artwork | no | Image URL (absolute or relative). |
genre, year, addedAt | no |
Rules the schema can't check
Apps reject a manifest that breaks any of these, so check them when you generate one:
- Unique IDs. No two items in the same collection (
tracks,albums,artists,playlists) share anid. - References resolve. Every
artistId,albumIdand playlisttrackIdsentry points at an item that exists. - Supported version.
sonusmust be a1.xversion. - Secure URLs. After resolving against
baseUrl, every URL ishttps://, orhttp://to a host on the local network (private IP ranges,localhostor.localnames).
IDs
IDs may contain letters, digits, ., _, : and -, up to 256 characters. Keep them stable: an
ID that changes looks like a brand-new track to the app, which then loses its downloads and playlist
positions. Good choices are a database key, a MusicBrainz ID or a hash of the original file path.
Relative URLs
Relative URLs resolve the same way they do in a browser:
| Manifest URL | url value | Resolves to |
|---|---|---|
https://music.example.com/library/sonus.json | albums/a/01.mp3 | https://music.example.com/library/albums/a/01.mp3 |
https://music.example.com/library/sonus.json | /other/01.mp3 | https://music.example.com/other/01.mp3 |
| any | https://cdn.example.com/01.flac | unchanged |
Set baseUrl when the audio lives somewhere other than the manifest.
Forward compatibility
Apps must ignore fields they don't recognise. New optional fields can appear in any 1.x release without breaking older apps. See Versioning.