Quick Start
Get Nova running in under 60 seconds. Zero configuration required.
curl -sSL https://nesbes.me/install.sh | bash
# Start API + open dashboard
./novam dashboard
# Or just start API (headless)
./novam api
# Update to latest version
./novam update
http://localhost:5001/api/v1
All endpoints are prefixed with /api/v1. No API key required in development
mode (Zero-Gate access).
Search API
Universal music search across tracks, artists, albums. Returns rich metadata with album art, duration, and IDs.
Query Parameters:
q |
string | Required. Search query (song name, artist, etc.) |
limit |
int | Max results (default: 20, max: 50) |
type |
string | Filter: "tracks", "artists", "albums" (default: all) |
// GET /api/v1/search?q=Blinding+Lights&limit=5
{
"success": true,
"data": {
"total": 5,
"tracks": [
{
"id": "4NhPJTK8cAq7uOa7SBGC9H",
"name": "Blinding Lights",
"duration_ms": 200040,
"explicit": false,
"artists": [
{
"id": "1Xyo4u8uXC1ZmMpatF05PJ",
"name": "The Weeknd"
}
],
"album": {
"id": "4yP0hdKOZPNshxUOjY0cZj",
"name": "After Hours",
"images": [
{"url": "https://...", "width": 640, "height": 640}
]
}
}
]
}
}
Tracks & Streaming
Stream audio and retrieve detailed track metadata. The stream endpoint returns raw audio data.
Returns raw audio stream. Content-Type: audio/webm or
audio/m4a.
Use in <audio src="..."> or download directly.
# Stream to file (bash)
curl -o song.m4a "http://localhost:5001/api/v1/tracks/stream/4NhPJTK8cAq7"
# Python download
import requests
r = requests.get(f"{API}/api/v1/tracks/stream/{track_id}", stream=True)
with open("song.m4a", "wb") as f:
for chunk in r.iter_content(8192):
f.write(chunk)
Returns full track metadata including duration, album art, and artist info.
{
"data": {
"id": "4NhPJTK8cAq7",
"name": "Blinding Lights",
"duration_ms": 200040,
"artists": [{"id": "...", "name": "The Weeknd"}],
"album": {
"name": "After Hours",
"images": [{"url": "https://..."}]
},
"thumbnail": "https://i.ytimg.com/vi/.../maxresdefault.jpg"
}
}
Returns high-resolution album artwork. Redirects to image URL.
Lyrics API
Fetch song lyrics. Supports auto-transcription via Whisper AI for tracks without lyrics.
{
"data": {
"track_id": "4NhPJTK8cAq7",
"lyrics": "I've been tryna call\nI've been on my own for long enough...",
"source": "genius",
"synced": false
}
}
AI-powered transcription using Whisper. Generates lyrics from audio when none are
available.
Note: Takes 10-30 seconds depending on track length.
Browse & Discovery
Explore trending music, genres, and get AI-powered recommendations.
Query: ?region=US (ISO country code)
Returns trending tracks for the specified region.
Returns all available genre categories with playlist IDs.
Get similar tracks based on a seed track. Great for "radio" features.
Artists API
Get artist profiles, top tracks, albums, and related artists.
{
"data": {
"id": "1Xyo4u8uXC1ZmMpatF05PJ",
"name": "The Weeknd",
"description": "Canadian singer-songwriter...",
"images": [{"url": "https://..."}],
"subscribers": "35M"
}
}
Returns the artist's most popular tracks.
Returns all albums and singles by the artist.
Playlists
Create, manage, and share playlists. Get tracks from existing playlists.
Get playlist details and all tracks.
Body:
{
"name": "My Playlist",
"description": "Best vibes",
"tracks": ["track_id_1", "track_id_2"]
}
Data Schemas
Complete TypeScript/JSON schemas for all data types. Feed this to your AI.
// TypeScript Schemas for Nova API
interface Track {
id: string; // Unique track identifier
name: string; // Track title
duration_ms: number; // Duration in milliseconds
explicit: boolean; // Explicit content flag
artists: Artist[]; // Array of artists
album: Album; // Album info
thumbnail?: string; // Direct image URL
}
interface Artist {
id: string; // Unique artist identifier
name: string; // Artist/band name
images?: Image[]; // Profile images
description?: string; // Bio/description
subscribers?: string; // Subscriber count
}
interface Album {
id: string; // Unique album identifier
name: string; // Album title
images: Image[]; // Cover art (multiple sizes)
release_date?: string; // Release date (YYYY-MM-DD)
total_tracks?: number; // Number of tracks
}
interface Image {
url: string; // Image URL
width: number; // Width in pixels
height: number; // Height in pixels
}
interface SearchResponse {
success: boolean;
data: {
total: number; // Total results found
tracks: Track[]; // Array of tracks
}
}
interface Lyrics {
track_id: string;
lyrics: string; // Full lyrics text
source: string; // "genius" | "transcribed"
synced: boolean; // Time-synced lyrics available
}
interface ErrorResponse {
success: false;
error: {
code: string; // Error code (see Error Handling)
message: string; // Human-readable message
}
}
Code Examples
Copy-paste examples for common use cases. Perfect for AI-assisted development.
import requests
API = "http://localhost:5001/api/v1"
# Search for a song
results = requests.get(f"{API}/search", params={"q": "Blinding Lights"}).json()
track = results["data"]["tracks"][0]
print(f"Found: {track['name']} by {track['artists'][0]['name']}")
# Download the track
audio = requests.get(f"{API}/tracks/stream/{track['id']}", stream=True)
with open(f"{track['name']}.m4a", "wb") as f:
for chunk in audio.iter_content(8192):
f.write(chunk)
print("Download complete!")
const API = "http://localhost:5001/api/v1";
async function playTrack(query) {
// Search
const res = await fetch(`${API}/search?q=${encodeURIComponent(query)}`);
const { data } = await res.json();
const track = data.tracks[0];
// Play in audio element
const audio = new Audio(`${API}/tracks/stream/${track.id}`);
audio.play();
// Show info
console.log(`Now playing: ${track.name} by ${track.artists[0].name}`);
console.log(`Album art: ${track.album.images[0].url}`);
}
playTrack("Starboy");
# Search
curl "http://localhost:5001/api/v1/search?q=Drake&limit=5"
# Get track info
curl "http://localhost:5001/api/v1/tracks/4NhPJTK8cAq7"
# Download audio
curl -o song.m4a "http://localhost:5001/api/v1/tracks/stream/4NhPJTK8cAq7"
# Get lyrics
curl "http://localhost:5001/api/v1/lyrics/4NhPJTK8cAq7"
# Get recommendations
curl "http://localhost:5001/api/v1/browse/recommendations/4NhPJTK8cAq7"
Error Handling
All errors return JSON with a consistent structure. Use the code for programmatic handling.
{
"success": false,
"error": {
"code": "TRACK_NOT_FOUND",
"message": "The requested track could not be found."
}
}
| Code | HTTP | Description |
|---|---|---|
| MISSING_QUERY | 400 | The 'q' query parameter is required for search. |
| INVALID_LIMIT | 400 | Limit must be between 1 and 50. |
| TRACK_NOT_FOUND | 404 | Track ID does not exist or is unavailable. |
| ARTIST_NOT_FOUND | 404 | Artist ID does not exist. |
| PLAYLIST_NOT_FOUND | 404 | Playlist ID does not exist or is private. |
| LYRICS_NOT_FOUND | 404 | No lyrics available. Consider using /transcribe. |
| STREAM_ERROR | 500 | Failed to fetch audio stream from source. |
| RATE_LIMITED | 429 | Too many requests. Wait and retry. |
| UPSTREAM_ERROR | 502 | Source service is temporarily unavailable. |