# Free Music API — Complete Reference > Real music, cleared for code. A free REST API for searching, streaming, and downloading royalty-free music. Base URL: https://api.freemusicapi.com Auth: Bearer token — `Authorization: Bearer YOUR_API_KEY` Get a free key: https://freemusicapi.com/signup OpenAPI spec: https://api.freemusicapi.com/v1/openapi.json --- ## Authentication All /v1/* endpoints require a Bearer token: Authorization: Bearer fma_live_xxxxxxxxxxxx Get a free API key by signing up at https://freemusicapi.com/signup Demo key for testing (30-second previews only): fma_test_localdev1234567890abcdef --- ## Endpoints ### Health Check GET / GET /v1 No authentication required. Returns API status. Response: { "name": "{music}", "tagline": "Real music, cleared for code.", "version": "v1", "docs": "https://freemusicapi.com/docs", "openapi": "https://api.freemusicapi.com/v1/openapi.json" } --- ### Search & Browse Tracks GET /v1/tracks Query parameters: q string Full-text search (title, genre) genre string Filter by genre (case-insensitive), e.g. "Lo-Fi", "EDM", "Hip Hop" mood string Filter by mood, e.g. "Chill", "Energetic", "Dark" bpm_min integer Minimum BPM bpm_max integer Maximum BPM energy_min integer Minimum energy (1-10) energy_max integer Maximum energy (1-10) key string Musical key, e.g. "C Major", "A Minor" label string Filter by label slug duration_min integer Minimum duration in seconds duration_max integer Maximum duration in seconds tags string Comma-separated tags (all must match) instruments string Comma-separated instruments (all must match) vocal boolean Filter by vocal presence (true/false) vocal_gender string Vocal gender filter valence string Emotional valence filter version string Track version filter explicit boolean If false, excludes explicit tracks sort string "newest" (default) or "popular" limit integer Results per page, 1-50 (default 20) offset integer Pagination offset (default 0) Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/tracks?genre=Lo-Fi&mood=Chill&energy_max=5&limit=10" Response: { "data": [ { "id": "uuid", "title": "Midnight Drive", "artists": [{ "name": "VYEN", "role": "primary" }], "label": { "name": "NCS", "slug": "ncs" }, "genre": "Lo-Fi", "subgenre": "Chillhop", "moods": ["Chill", "Dreamy"], "tags": ["study", "night"], "bpm": 85, "key": "C Minor", "energy": 3, "valence": "positive", "duration_seconds": 195.5, "version": null, "has_vocals": false, "vocal_presence": null, "instruments": ["piano", "drums"], "explicit": false, "release_date": "2025-01-15", "credits": { "produced_by": "VYEN", "written_by": "VYEN" }, "attribution": "Music by VYEN via Free Music API (freemusicapi.com)", "artwork_url": "https://...", "tier": "free", "play_count": 1234, "download_count": 567, "formats_available": ["mp3", "wav"], "external_ids": { "isrc": "...", "spotify_uri": "..." } } ], "meta": { "total": 42, "limit": 10, "offset": 0 } } --- ### Get Single Track GET /v1/tracks/{trackId} Path parameters: trackId string (uuid) Track UUID Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/tracks/abc-123-def" Response: Same as track list item but with additional fields: stream_url string Pre-signed streaming URL stream_url_expires_at string ISO 8601 expiry timestamp waveform_data object Audio waveform visualization data --- ### Find Similar Tracks GET /v1/tracks/{trackId}/similar Returns tracks similar to the given track. Similarity is scored by genre match, mood overlap, BPM proximity, and energy proximity. Useful for building "More like this" sections and auto-play queues. Query parameters: limit integer Number of results, 1-20 (default 6) Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/tracks/abc-123/similar?limit=10" Response: { "data": [ { "id": "uuid", "title": "Similar Track", "artists": [{ "name": "Artist", "role": "primary" }], "genre": "Lo-Fi", "bpm": 88, "energy": 4, "moods": ["Chill", "Dreamy"], ... } ], "meta": { "total": 10, "limit": 10, "offset": 0 } } --- ### Get Your Track Stats GET /v1/tracks/{trackId}/my-stats Returns per-user usage stats for a specific track — how many times you (your API key) have played, downloaded, or made API calls for this track. Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/tracks/abc-123/my-stats" Response: { "data": { "track_id": "abc-123", "plays": 12, "downloads": 3, "api_calls": 15 } } --- ### Get Stream URL POST /v1/tracks/{trackId}/stream Returns a time-limited signed URL for streaming. Counts as a play event. Demo-tier keys get 30-second previews. Path parameters: trackId string (uuid) Track UUID Request body (optional): { "app_identifier": "my-app-name" } Example: curl -X POST -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"app_identifier": "my-app"}' \ "https://api.freemusicapi.com/v1/tracks/abc-123/stream" Response: { "data": { "stream_url": "https://api.freemusicapi.com/stream?token=...", "expires_at": "2025-01-15T12:00:00Z", "format": "mp3", "preview": false, "duration_limit": null, "attribution": "Music by VYEN via Free Music API" } } --- ### Get Download URL POST /v1/tracks/{trackId}/download Returns a time-limited URL for downloading. Requires a registered API key (demo keys cannot download). Path parameters: trackId string (uuid) Track UUID Request body (optional): { "format": "mp3", "app_identifier": "my-app" } format options: "mp3" (default), "wav" Example: curl -X POST -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"format": "wav"}' \ "https://api.freemusicapi.com/v1/tracks/abc-123/download" Response: { "data": { "download_url": "https://api.freemusicapi.com/stream?token=...&dl=1", "expires_at": "2025-01-15T12:00:00Z", "format": "wav", "attribution": "Music by VYEN via Free Music API" } } --- ### Get Beat Data GET /v1/tracks/{trackId}/beats Returns beat positions, bar boundaries, structural sections (intro, verse, chorus, build, drop, breakdown, outro), BPM, time signature, and energy data. Generated by neural-network beat analysis (madmom). Pro tracks require a pro API key. Query parameters: fps integer Frame rate — adds a \`frame\` field to each beat (e.g. fps=30 for Remotion) Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/tracks/abc-123/beats?fps=30" Response: { "data": { "bpm": 128.0, "time_signature": "4/4", "duration": 215.4, "total_beats": 460, "total_bars": 115, "beats": [ { "time": 0.43, "beat": 1, "bar": 1, "downbeat": true, "frame": 13 }, { "time": 0.90, "beat": 2, "bar": 1, "downbeat": false, "frame": 27 } ], "bars": [ { "bar": 1, "start": 0.43, "end": 2.30 } ], "sections": [ { "label": "intro", "start": 0.0, "end": 15.2, "energy": 0.25 }, { "label": "drop", "start": 45.0, "end": 78.6, "energy": 0.95 } ] } } Not all tracks have beat data yet — check the \`has_beats\` field on track responses, or handle the 404 response. --- ### List Genres GET /v1/genres Returns all genres with track counts, sorted by count. Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/genres" Response: { "data": [ { "name": "Lo-Fi", "track_count": 42 }, { "name": "EDM", "track_count": 38 }, ... ] } --- ### List Moods GET /v1/moods Returns all moods with track counts. Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/moods" Response: Same format as genres. --- ### List Tags GET /v1/tags Returns all tags with track counts. --- ### List Instruments GET /v1/instruments Returns all instruments with track counts. --- ### List Musical Keys GET /v1/keys Returns all musical keys with track counts. --- ### List Labels GET /v1/labels Returns all music labels with track counts and genre info. Response: { "data": [ { "name": "NCS", "slug": "ncs", "tier": "free", "track_count": 150, "genres": ["EDM", "House", "Dubstep"], "website_url": "https://ncs.io" } ] } --- ### List Playlists GET /v1/playlists Returns curated playlists sorted by category. Response: { "data": [ { "id": "uuid", "name": "Chill Coding", "slug": "chill-coding", "description": "Low-key beats for focused work", "artwork_url": "https://...", "category": "Focus", "track_count": 25 } ] } --- ### Get Playlist with Tracks GET /v1/playlists/{playlistId} Accepts UUID or slug. Path parameters: playlistId string Playlist UUID or slug Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/playlists/chill-coding" Response: Playlist summary fields plus: tracks array Full track list items --- ### Report Play Event POST /v1/plays Report that a track was played in your app. Request body: { "track_id": "uuid", (required) "duration_played_seconds": 120, (optional) "completed": true, (optional, default false) "app_identifier": "my-app" (optional) } Response: { "success": true } --- ### Get API Usage GET /v1/me/usage Returns usage for the current billing period. Example: curl -H "Authorization: Bearer YOUR_KEY" \ "https://api.freemusicapi.com/v1/me/usage" Response: { "data": { "tier": "free", "billing_period": { "start": "2025-01-01", "end": "2025-01-31" }, "usage": { "requests_this_hour": 12, "requests_limit_per_hour": 100, "plays_this_month": 45, "plays_limit_per_month": 500, "top_tracks": [ { "track_id": "uuid", "title": "Midnight Drive", "plays": 5 } ] } } } --- ## Audio Streaming The stream URL returned by POST /v1/tracks/{id}/stream points to: GET /stream?token=... This endpoint is publicly accessible (no API key needed) — authentication is via the signed token in the query string. The token is base64-encoded and time-limited. To download instead of stream, append &dl=1. --- ## Error Responses All errors follow this format: { "error": { "code": "error_code", "message": "Human-readable message" } } Common error codes: 401 unauthorized Missing or invalid API key 403 tier_required Higher tier needed for this resource 404 not_found Track/playlist/resource not found 429 rate_limited Rate limit exceeded (check X-RateLimit-* headers) 400 bad_request Invalid parameters or missing required fields Rate limit headers (on 429 responses): X-RateLimit-Limit Requests allowed per hour X-RateLimit-Remaining Requests remaining this hour X-RateLimit-Reset Unix timestamp when window resets --- ## Tiers & Pricing Free: - 100 requests/hour - 500 plays/month - 30-second preview streams - MP3 downloads - Attribution required - Personal/non-commercial use only Pro ($9/month): - 1,000 requests/hour - 10,000 plays/month - Full-length streams - MP3 + WAV downloads - Commercial use allowed - Attribution appreciated but not required Business ($49/month): - 10,000 requests/hour - Unlimited plays - Full-length streams - MP3 + WAV + stems - Commercial use + white-label - No attribution required - Priority support --- ## License Summary - All music is royalty-free for use in apps, games, videos, podcasts, and content - Free tier: personal and non-commercial projects only, attribution required - Pro/Business: commercial use allowed - You may NOT use tracks to train AI/ML models - You may NOT redistribute the raw audio files or build a competing music library - You may NOT claim ownership of the music - End users of your app CAN use the music in their content (YouTube videos, streams, etc.) Full terms: https://freemusicapi.com/license --- ## Integration Examples For code examples in React, Python, Node.js, Swift, Unity, Claude Code, Cursor, and more: https://freemusicapi.com/docs/integrations OpenAPI 3.1 spec (for Postman, Swagger, code generators): https://api.freemusicapi.com/v1/openapi.json