Complete REST API Documentation
Get all songs with optional filters and sorting
[
{
"id": 1,
"title": "Song Title",
"artist": "Artist Name",
"album": "Album Name",
"genre": "Hip-Hop",
"style": "Trap",
"mood": "energetic",
"year": 2024,
"track": "1/12",
"img": "https://...",
"path": "https://...",
"avatar": "https://...",
"fanart": "https://..."
}
]
Get a single song by ID
{
"id": 123,
"title": "Song Title",
"artist": "Artist Name",
"album": "Album Name",
"genre": "Hip-Hop",
"style": "Trap",
"mood": "energetic",
"year": 2024,
"path": "https://...",
"img": "https://..."
}
Get all unique artists in alphabetical order
[ "Adele", "Drake", "Ed Sheeran", "Taylor Swift", ... ]
Get artist metadata including bio and thumbnail
{
"artist": "Drake",
"thumb": "/assets/thumb/drake.jpg",
"bio": "Canadian rapper and singer..."
}
Get all albums by a specific artist
[
{
"name": "Album Name",
"artist": "Drake",
"year": 2023,
"cover": "https://...",
"songs": [...]
}
]
Get all tracks from a specific album
[
{
"id": 1,
"title": "Track 1",
"artist": "Drake",
"album": "Certified Lover Boy",
"year": 2021,
"track": "1/21",
...
},
...
]
Get all available genres, styles, and moods for filtering
{
"genres": [
"Hip-Hop",
"Pop",
"Rock",
"Electronic",
...
],
"styles": [
"Trap",
"House",
"Alternative",
...
],
"moods": [
"energetic",
"chill",
"melancholic",
...
]
}
Get iTunes top songs (all genres)
Get iTunes top songs by genre
Get Deezer global chart
Get Deezer chart by genre
List audio files available on the server (filename, size, mtime).
List thumbnail images in /assets/thumb.
Serve a small, prefixed thumbnail variant. The server prefers a prefixed small file /assets/thumb/small/th_{filename} and will generate it on-demand from the original when sharp is available. If missing, the original thumbnail is returned as a fallback.
/small to stored img values) so the UI requests lightweight images without changing persisted metadata. The server stores original thumbs as /assets/thumb/{name} and keeps prefixed smalls under /assets/thumb/small/th_{name}.Upload audio files (multipart/form-data). Adds entries to the local tags store when possible.
Retrieve recent uploads log. Returns an array of recent add objects (ts, meta, ip, region).
Clear the recent-adds log and create a timestamped backup in /assets/logs/backup/.
Get logs configuration (currently: maxEntries).
Set logs configuration. JSON body: { "maxEntries": 500 }. Max allowed value is 10000.
Delete (move to backup) an audio file and remove its tag entry. Filename should be URL encoded.
Delete or backup a thumbnail image and clear references in the local tags store.
Update metadata for a song in tags-local.json (title, artist, album, img, path, etc.).
Upload a replacement thumbnail for a song. Server saves image, updates tag, and attempts to embed into MP3 ID3 when possible.
Proxy or serve audio. If url points to a local /assets/ path the server serves it with Range support; remote http(s) URLs are proxied.
Reload tags-local.json into server memory (admin use).
Clear the play tracking log (plays.ndjson).
Record a play event. Appends one JSON object per line to `plays.ndjson`.
curl -X POST http://localhost:3000/track_play \
-H "Content-Type: application/json" \
-d '{"id":123,"title":"Song Title","artist":"Artist"}'
{"ok":true}
Get recent plays and simple aggregates (by song, region). Returns last 100 plays and counts.
Get the total number of play entries recorded. Optional query: ?days=7 to count plays within the last N days.
Get recent play events enriched with song metadata. Query: limit (default 100).
Get top-played tracks. Query: limit (default 20), days or since (timestamp ms) to limit timeframe.
{
"id": "number - Unique song identifier",
"title": "string - Song title",
"artist": "string - Artist name",
"album": "string - Album name",
"genre": "string - Music genre",
"style": "string - Music style/subgenre",
"mood": "string - Song mood/vibe",
"year": "number - Release year",
"track": "string - Track number (e.g., '1/12')",
"img": "string - Album cover image URL",
"path": "string - Audio file URL",
"alternate": "string - Alternate version info",
"born": "string|null - Artist birth info",
"logo": "string - Artist logo URL",
"avatar": "string - Artist avatar URL",
"wide": "string|null - Wide banner image",
"banner": "string - Banner image URL",
"clearart": "string|null - Clear art image",
"cutout": "string|null - Cutout image",
"fanart": "string - Fan art/background image"
}
/api/filters to get available filter valueshttp://localhost:3000. Use simple HTTP clients like curl, fetch, or Postman to call the endpoints below.curl http://localhost:3000/api/songs/assets/. Example with Range header (seek support):curl -H "Range: bytes=0-1023" "http://localhost:3000/proxy/audio?url=/assets/audio/track.mp3" --output - | head -c 1024
curl -F "files=@/path/to/track.mp3" http://localhost:3000/api/upload
curl -X POST http://localhost:3000/track_play \
-H "Content-Type: application/json" \
-d '{"id":123,"title":"Song Title","artist":"Artist"}'TRACKING_TOKEN, include header X-Tracking-Token: <token>.tags-local.json after editing or importing. Example:curl -X POST http://localhost:3000/admin/reload-tags
ADMIN_TOKEN is set, include header X-Admin-Token: <token>.plays.ndjson by ts (timestamp) and/or id. Body: JSON with ts and/or id. Example:curl -X POST http://localhost:3000/admin/plays/delete \
-H "Content-Type: application/json" \
-d '{"ts":1612345678901,"id":123}'X-Admin-Token header when ADMIN_TOKEN is configured.fetch Example/proxy/audio?url= for cross-origin remote audio or point directly to local paths (e.g. /assets/audio/track.mp3) when the file is hosted on the same server.
fetch('/proxy/audio?url='+encodeURIComponent('/assets/audio/track.mp3'), { headers: { Range: 'bytes=0-1023' } })
.then(r => r.arrayBuffer()).then(b => console.log('got', b.byteLength));public/assets/meta.json).curl http://localhost:3000/api/meta
artist, thumb, avatar, etc.curl -X PUT http://localhost:3000/api/meta \
-H "Content-Type: application/json" \
-d '{"artist":"My Artist","avatar":"/assets/meta/avatar/my_avatar.jpg"}'artist, field (e.g. avatar, thumb), and file (multipart).curl -i -X POST \ -F "artist=Automated Test Artist" \ -F "field=avatar" \ -F "file=@/path/to/avatar.jpg" \ http://localhost:3000/api/meta/upload
path (the new saved path). The server also persists the path into public/assets/meta.json and creates a backup.?id=<metaId> or ?artist=<name>. Without query returns the full bios object (may be large)./assets/meta/<field>/. Example: ken_avatar020039443.jpg.
scripts/download-meta-images.js (one-time) that downloads external images into public/assets/meta/* and updates meta.json. Use it to localize remote art and improve reliability.
alternate field when present.
curl "http://localhost:3000/api/meta?q=James%20Blunt" curl "http://localhost:3000/api/meta/artist/James%20Blunt"
{
"artist": "James Blunt",
"thumb": "/assets/meta/thumb/jam_thumb1769479514341721198.jpg",
"website": "https://www.jamesblunt.com",
"bio": "..."
}