Create music with vocals

May 15, 2025

Table of contents

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

This endpoint generates a complete song with vocals based on a text prompt and optional parameters.

https://api.useapi.net/v1/tempolor/music/song

Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
Request Body
{
  "prompt": "A cinematic orchestral piece with dramatic string sections and a powerful crescendo",
  "lyrics": "These are the lyrics for my song\nSecond line of the lyrics",
  "clonedVoiceItemId": "user:12345-tempolor:user_id-voice:abcdef123456789",
  "replyUrl": "https://your-callback-url.com",
  "replyRef": "your-reference-id"
}
  • prompt is required, a text description of the desired song.
    Maximum length 2000 characters.

  • lyrics is optional, custom lyrics for the song. If not provided, lyrics will be auto-generated based on the prompt.
    Maximum length 3000 characters.

  • model_song is optional, the model to use for generation.
    Supported values:
    • v3 - Enhanced AI music generation supporting EN/CN/JP, max 2 min
    • v3.5 - Supporting EN/CN, max 4.5 min (default)
  • artistVoiceItemId is optional, ID of a predefined artist voice to use for the vocals. Get available voices using GET artist-voices.

  • clonedVoiceItemId is optional, ID of a previously cloned voice to use for the vocals.
  • midiItemId is optional, ID of a previously uploaded MIDI file to base the composition on.
    • To get existing MIDI files, use GET midi.
    • To upload a new MIDI file, use POST midi.
  • user_id is optional, if not specified, the API will use the account from your request.

  • replyUrl is optional, a callback URL that will be called with generation progress updates.
    Maximum length 1024 characters.
    We recommend using sites like webhook.site to test callback URL functionality.

  • replyRef is optional, a reference ID that will be included in the callback requests.
    Maximum length 1024 characters.

  • maxJobs is optional; it specifies the maximum number of concurrent jobs for this request. If not provided, the value will be taken from the account configuration set in POST accounts.

Important notes:

  • You can only use one of artistVoiceItemId or clonedVoiceItemId, not both.
  • If you specify a midiItemId, you cannot use artistVoiceItemId or clonedVoiceItemId.
Responses
  • 200 OK

    Use the returned jobs values to retrieve generation status and results using GET music/job_id.

    If you specify the optional parameter replyUrl, the API will call the provided replyUrl with generation progress updates until the generation is complete or fails.

    {
      "result": true,
      "itemIds": [
        "abcdef123456789",
        "fedcba987654321"
      ],
      "jobs": [
          "user:12345-tempolor:user_id-job:abcdef123456789",
          "user:12345-tempolor:user_id-job:fedcba987654321",
      ],
      "remainSeconds": 21533,
      "maxGenCountAtOnce": 10,
      "unlimited": false,
      "remainNum": 1534,
      "totalNum": 3000
    }
    
  • 400 Bad Request

    {
      "error": "Parameter prompt is required",
      "code": 400
    }
    
  • 401 Unauthorized

    {
      "error": "Unauthorized",
      "code": 401
    }
    
  • 402 Payment Required

    {
      "error": "Subscription required",
      "code": 402
    }
    
  • 404 Not Found

    {
      "error": "The source material does not exist.",
      "code": 404
    }
    

    This error may occur if the specified artistVoiceItemId, clonedVoiceItemId, or midiItemId no longer exists.

  • 429 Too Many Requests

    Wait in a loop for at least 30 seconds and retry again.

    There are two possible cases for API response 429:

    1. API query is full and cannot accept new music generation requests. Size of queue defined by the maxJobs value from either the request body or the default from the account configuration set in POST accounts.
      {
        "error": "Account <user_id> is busy executing X jobs",
        "runningJobs": {
       "<user_id>": [
         {
           "user_id": "<user_id>",
           "job_id": "<job_id>",
           "started": 1715791234567,
           "replyUrl": "call back URL here, if provided",
           "replyRef": "reference id here, if provided"
         }
       ]
        },
        "code": 429
      }
      
    2. The API received an HTTP response status 429 from TemPolor.
      {
        "error": "please wait for current Generations to finish or upgrade your plan",
        "code": 429
      }
      
Model
{   // TypeScript, all fields are optional
    result: boolean
    itemIds: string[]
    jobs: string[]
    remainSeconds: number
    maxGenCountAtOnce: number
    unlimited: boolean
    remainNum: number
    totalNum: number
}
Examples
  • curl -H "Accept: application/json" \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer …" \
         -X POST https://api.useapi.net/v1/tempolor/music/song \
         -d '{"prompt": "A cinematic orchestral piece with dramatic string sections"}'
    
  • const apiUrl = `https://api.useapi.net/v1/tempolor/music/song`; 
    const api_token = "API token";
    const prompt = "A cinematic orchestral piece with dramatic string sections";      
    const data = { 
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${api_token}`,
        'Content-Type': 'application/json' }
    };
    data.body = JSON.stringify({ 
      prompt
    });
    const response = await fetch(apiUrl, data);
    const result = await response.json();
    console.log("response", {response, result});
    
  • import requests
    apiUrl = f"https://api.useapi.net/v1/tempolor/music/song" 
    api_token = "API token"
    prompt = "A cinematic orchestral piece with dramatic string sections"
    headers = {
        "Content-Type": "application/json", 
        "Authorization" : f"Bearer {api_token}"
    }
    body = {
        "prompt": f"{prompt}"
    }
    response = requests.post(apiUrl, headers=headers, json=body)
    print(response, response.json())
    
Try It