Download a song
November 14, 2026
Table of contents
Get a finished song as MP3, WAV, MIDI or MusicXML.
format | Plans | What comes back |
|---|---|---|
mp3 (default) | every plan | JSON with the song’s public mp3 link, the same as its audioUrl, and playUrl, the same mp3 as a direct link for players until playUrlExpires. For a file uploaded with POST /files, its own audio in the format it was uploaded in, as a signed link valid for 24 hours |
wav | Creator, Artist | JSON with a signed link valid for 24 hours. Not for ace-step-1.5-xl songs, which ACE Music makes as MP3 only |
midi | Creator, Artist | The .mid file itself, audio/midi |
musicxml | Creator, Artist | The MusicXML score itself, application/vnd.recordare.musicxml+xml |
For mp3, playUrl is a direct link to the same MP3 for players, valid until playUrlExpires (about an hour): some browsers (Brave) block the redirect behind audioUrl. Store audioUrl, play playUrl.
ACE Music makes WAV, MIDI and MusicXML on the first request for a song. The API waits up to a minute for it, then answers 202: call again a minute later. For the score as ABC notation, use GET /music/score.
https://api.useapi.net/v1/acemusic/music/download?songId=
songId&format=format
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Query Parameters
songIdis required, a finished song’ssongId(user:<id>-<email>-song:so_…), URL-encoded.formatis optional.
Supported values:mp3(default),wav,midi,musicxml.
Responses
-
mp3:{ "songId": "user:[email protected]:so_3f9c2a7d81e64b05a9d2c4e7", "format": "mp3", "url": "https://acemusic.ai/data/so_3f9c2a7d81e64b05a9d2c4e7.mp3", "playUrl": "https://….r2.cloudflarestorage.com/acemusic-data-prod/users/…/audio/202611/….mp3?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20261114T204512Z&X-Amz-Expires=3599&…", "playUrlExpires": "2026-11-14T21:45:11.000Z", "fileName": "Farmers Market Sunshine.mp3" }wav, andmp3of an uploaded file:{ "songId": "user:[email protected]:so_4e7b2c9d0a5f4183b6d8e2c7", "format": "wav", "url": "https://….r2.cloudflarestorage.com/acemusic-data-prod/users/…/audio/202611/….wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=86400&…", "fileName": "Orchestral Morning.wav", "expires": "2026-11-15T20:07:29.242Z" }midiandmusicxmlanswer with the file itself, withContent-Disposition: attachment; filename="<title>.mid"(or.musicxml). -
ACE Music is still making the file. Call again in a minute.
{ "songId": "user:[email protected]:so_4e7b2c9d0a5f4183b6d8e2c7", "format": "midi", "status": "processing", "message": "ACE Music is still making the midi: call again in a minute" } -
{ "error": "ace-step-1.5-xl songs are made lossy: no WAV (use mp3)", "code": 400 }{ "error": "Parameter format (flac) valid values: mp3,wav,midi,musicxml", "code": 400 } -
Invalid API token.
{ "error": "useapi.net ⁝ Unauthorized", "code": 401 } -
WAV, MIDI and MusicXML need a paid ACE Music plan, or the song belongs to another useapi.net user.
{ "error": "Downloading the wav needs a paid ACE Music plan (the account is on free): Downloads come with a paid plan", "code": 403 } -
{ "error": "Song user:[email protected]:so_3f9c2a7d81e64b05a9d2c4e7 not found (deleted on acemusic.ai?)", "code": 404 } -
The song is not finished, or it failed.
{ "error": "Song user:[email protected]:so_8c1d4f7a2b9e4c06a3f5d7e1 is running: nothing to download yet", "code": 409 }
Model
{ // TypeScript, all fields are optional
songId: string
format: 'mp3' | 'wav' | 'midi' | 'musicxml'
url: string // mp3: the public link. wav, an upload's mp3, a midi ACE Music redirects: a signed link
fileName: string // the song's title with the file's extension
expires?: string // ISO 8601, when a signed link stops working (24 hours)
status?: 'processing' // 202: the file is still being made
message?: string // 202
}
Examples
-
SONGID="user:[email protected]:so_4e7b2c9d0a5f4183b6d8e2c7" curl -H "Authorization: Bearer …" -o song.mid \ "https://api.useapi.net/v1/acemusic/music/download?format=midi&songId=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$SONGID")" -
const token = "API token"; const songId = "user:[email protected]:so_4e7b2c9d0a5f4183b6d8e2c7"; const params = new URLSearchParams({ songId, format: "wav" }); const response = await fetch(`https://api.useapi.net/v1/acemusic/music/download?${params}`, { headers: { "Authorization": `Bearer ${token}` } }); const result = await response.json(); console.log(response.status, result.url, result.expires); -
import requests token = "API token" params = {"songId": "user:[email protected]:so_4e7b2c9d0a5f4183b6d8e2c7", "format": "musicxml"} response = requests.get("https://api.useapi.net/v1/acemusic/music/download", headers={"Authorization": f"Bearer {token}"}, params=params) if response.status_code == 200 and "json" not in response.headers.get("content-type", ""): with open("song.musicxml", "wb") as f: f.write(response.content) else: print(response.status_code, response.json())
Try It
An mp3 or wav plays above the JSON. A MIDI file or a MusicXML score comes back as a download link.