Upload audio or an image

November 14, 2026

Table of contents

  1. Request Headers
  2. Query Parameters
  3. Request Body
  4. Responses
  5. Model
  6. Examples
  7. Try It

Upload a file to an account’s ACE Music Library, sent as the raw request body with its Content-Type:

  • Audio (MP3, WAV, FLAC, OGG, M4A or AAC, up to 100 MB and 8 minutes) becomes a song in the Library. ACE Music transcribes it, reading its lyrics, style, tempo and melody, which took about 15 to 30 seconds in our tests. The answer is that song with its songId, which works as a reference in POST /music: cover it, remix or edit it, mash it up, or let it guide a prompt.
  • An image (JPEG, PNG or WebP, up to 10 MB) returns a mediaId for the images of a prompt in POST /music.

The type is read from the file’s first bytes. The Content-Type you send only has to agree on audio or image. An uploaded file, its songId and its mediaId work only on the account it was uploaded to, so a request that uses them runs there.

Uploaded audio counts against the account’s upload allowance, the total length of audio it keeps: 10 minutes on Free, 30 on Creator and 60 on Artist. When it is used up the API answers 412: delete uploads on acemusic.ai, or move up a plan. Transcribing costs no credits. The song’s own audio downloads with GET /music/download.

https://api.useapi.net/v1/acemusic/files?email=email&title=title

Request Headers
Authorization: Bearer {API token}
Content-Type: audio/mpeg
# Or the file's own type: audio/wav, audio/flac, audio/ogg, audio/mp4, audio/aac,
# image/jpeg, image/png, image/webp
  • API token is required, see Setup useapi.net for details.
  • Content-Type is required, an audio/… or image/… type matching the file.
  • Content-Length is required. Most tools send it for you.
Query Parameters
  • email is optional, the account to upload to. Default: any healthy account.
  • title is optional, the title of an uploaded song, and its file name at ACE Music. Default: upload- with the date and time.
    Maximum length: 80 characters.
Request Body

The file’s bytes, nothing else.

Responses
  • 200 OK

    Audio, transcribed:

    {
      "songId": "user:[email protected]:so_7d2e9b4c1a8f4e6d93b0c5a1",
      "taskId": "so_7d2e9b4c1a8f4e6d93b0c5a1",
      "status": "succeeded",
      "title": "paper-boat-demo",
      "model": null,
      "style": "A gentle acoustic indie-folk lullaby at a slow, peaceful tempo. Delicate fingerpicked acoustic guitar with warm ambient pads, and a tender female lead vocal close to the mic.",
      "lyrics": "[verse]\nFold the morning into paper\nSend it down the gutter stream\nSail away, little paper boat\nCarry every quiet dream",
      "instrumental": false,
      "duration": 35,
      "audioUrl": null,
      "playUrl": "https://example.r2.cloudflarestorage.com/…/upload.mp3?X-Amz-…",
      "playUrlExpires": "2026-11-16T01:27:32.000Z",
      "coverUrl": "https://acemusic.ai/data/so_7d2e9b4c1a8f4e6d93b0c5a1-cover.jpg?v=1794685595471",
      "pageUrl": null,
      "created": "2026-11-14T19:46:25.300Z",
      "finished": "2026-11-14T19:46:37.999Z",
      "kind": "upload",
      "score": true,
      "upload": {
        "seconds": 35,
        "bpm": 88,
        "transcription": "done"
      }
    }
    

    An image:

    {
      "mediaId": "user:[email protected]:cx_5e8a1f3b9c2d4e7f80a6b4d2",
      "email": "[email protected]",
      "url": "https://acemusic.ai/data/cx_5e8a1f3b9c2d4e7f80a6b4d2.jpg",
      "mime": "image/jpeg",
      "kind": "image"
    }
    
  • 202 Accepted

    Audio that ACE Music was still transcribing after 90 seconds. The body is the song as it stands, the same shape as 200. Read it again with GET /music/songId.

  • 400 Bad Request

    ACE Music refused the file, or the body ended early.

    {
      "error": "Importing the audio: Audio can be up to 8 min long",
      "code": 400
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "useapi.net ⁝ Unauthorized",
      "code": 401
    }
    
  • 404 Not Found

    {
      "error": "Account [email protected] is not configured",
      "code": 404
    }
    
  • 411 Length Required

    {
      "error": "Content-Length is required (send the file as the raw request body)",
      "code": 411
    }
    
  • 412 Precondition Failed

    The account’s upload allowance is used up: delete uploads on acemusic.ai, or move up a plan.

  • 413 Content Too Large

    {
      "error": "The image file is 11.0 MB: the limit is 10 MB",
      "code": 413
    }
    
  • 415 Unsupported Media Type

    {
      "error": "Content-Type says audio but the file is an image (png)",
      "code": 415
    }
    
    {
      "error": "Send the file as the raw request body with its Content-Type (audio/mpeg, audio/wav, audio/flac, audio/ogg, audio/mp4, audio/aac, image/jpeg, image/png or image/webp)",
      "code": 415
    }
    
  • 422 Unprocessable Entity

    ACE Music could not read the audio. The body is the song with its error.

  • 596 Account Error

    The account is paused, or no account is healthy. Add it again with the current password.

Model

An image:

{ // TypeScript, all fields are optional
  mediaId: string                // user:<id>-<email>-media:cx_…  for POST /music `images`
  email: string                  // the account it was uploaded to
  url: string | null             // ACE Music's link to the image
  mime: string                   // image/jpeg | image/png | image/webp
  kind: string                   // image
}

Audio, the song (kind: "upload"):

{ // TypeScript, all fields are optional
  songId: string                 // user:<id>-<email>-song:so_…  use it as a reference, to split, download or delete
  taskId: string                 // ACE Music's own id of the song (so_…)
  status: 'planning' | 'scoring' | 'queued' | 'running' | 'succeeded' | 'failed' | 'interrupted'
  title: string | null
  model: string | null           // acemusic-v1 | acemusic-v1.1 | ace-step-1.5-xl, null for an uploaded file
  style: string | null           // the style the song was made with (ACE Music writes it for a prompt request)
  lyrics: string | null          // [verse] / [chorus] tagged
  instrumental: boolean | null
  duration: number | null        // seconds
  audioUrl: string | null        // public mp3 link, https://acemusic.ai/data/<taskId>.mp3, once the song succeeded.
                                 // It never changes: store this one. null for an uploaded file: get its audio with
                                 // GET /music/download
  playUrl?: string | null        // the same mp3 as a direct link for players, valid until playUrlExpires (about an hour):
                                 // some browsers (Brave) block the redirect behind audioUrl. Store audioUrl, play playUrl.
                                 // For about a minute after the song is made it is audioUrl itself (ACE Music serves the
                                 // file directly then). In job records and GET /music/{songId} only, not in GET /music or
                                 // POST /files. null while the song is not finished, or when the link could not be read
  playUrlExpires?: string | null // ISO 8601, when playUrl stops working: read the job or the song again for a fresh one
                                 // an upload (kind 'upload'): no audioUrl; playUrl is its own audio, signed for 24 hours
  coverUrl: string | null        // cover art (jpg)
  pageUrl: string | null         // the song's page on acemusic.ai, when ACE Music made one
  created: string | null         // ISO 8601
  finished: string | null        // ISO 8601
  kind: 'original' | 'cover' | 'mashup' | 'edit' | 'upload'
  score: boolean                 // true when ACE Music already has the song's score (GET /music/score)
  error?: {                      // a failed song
    code?: string                // ACE Music's code, e.g. ref_no_melody, song_not_made
    message?: string
    reason?: string
  }
  refunded?: boolean             // ACE Music gave the credits back for a failed song
  stems?: {                      // splits made with POST /music/stems
    vocals?: { status?: string, tracks: { type?: string, url: string | null, duration?: number }[] }
    all?: { status?: string, tracks: { type?: string, url: string | null, duration?: number }[] }
  }                              // track links are signed (24 hours) on GET /music/{songId}, null elsewhere
  upload?: {                     // an uploaded audio file (POST /files)
    seconds?: number             // its length, counted against the account's upload minutes
    bpm?: number                 // the tempo ACE Music read
    transcription?: string       // done once ACE Music has read its lyrics, style and melody
  }
}
Examples
  • curl -X POST "https://api.useapi.net/v1/acemusic/files?title=paper-boat-demo" \
         -H "Authorization: Bearer …" \
         -H "Content-Type: audio/mpeg" \
         --data-binary "@demo.mp3"
    
  • import { readFile } from "node:fs/promises";
    
    const token = "API token";
    const bytes = await readFile("demo.mp3");
    const response = await fetch("https://api.useapi.net/v1/acemusic/files?title=paper-boat-demo", {
      method: "POST",
      headers: { "Authorization": `Bearer ${token}`, "Content-Type": "audio/mpeg" },
      body: bytes
    });
    const song = await response.json();
    console.log(response.status, song.songId, song.lyrics);
    
  • import requests
    
    token = "API token"
    with open("demo.mp3", "rb") as f:
        response = requests.post(
            "https://api.useapi.net/v1/acemusic/files",
            headers={"Authorization": f"Bearer {token}", "Content-Type": "audio/mpeg"},
            params={"title": "paper-boat-demo"},
            data=f.read()
        )
    print(response.status_code, response.json())
    
Try It