Music Generation API
Introduction
This API provides AI-powered music generation from text descriptions. Create custom songs, background music, and audio tracks by describing what you want in natural language.
Try the Interactive Playground →Authentication
All API requests require authentication using a Bearer token. Include your API key in the Authorization header of every request:
Authorization: Bearer YOUR_API_KEY
Available Models
The API provides two music generation models with different capabilities:
Music 1.5
music-1.5First-generation music synthesis model. Suitable for general-purpose music generation with good quality.
Music 2.0
music-2.0Latest model with improved audio quality, better adherence to prompts, and enhanced musical coherence. Recommended for production use.
Music Generation: POST /api/v1/generate
This endpoint creates a music generation job. The music is generated asynchronously, and you'll receive a job ID to poll for results.
Request
Send a POST request with a JSON body containing your music description and optional configuration.
Required Parameters
| Parameter | Type | Description |
|---|---|---|
prompt | string | Text description of the music you want to generate |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
model | string | "music-2.0" | Model to use: "music-1.5" or "music-2.0" |
lyrics | string | "" | Optional lyrics for the song |
audio_settings.sample_rate | integer | 44100 | Sample rate in Hz (8000-48000) |
audio_settings.bitrate | integer | 256000 | Bit rate (64000-320000) |
audio_settings.format | string | "mp3" | Audio format: "mp3", "wav", or "flac" |
response_format | string | "hex" | Encoding: "hex", "base64", or "data_url" |
Example Request
{
"model": "music-2.0",
"prompt": "upbeat electronic dance music with energetic drums and synthesizers",
"lyrics": "Dancing through the night\nFeeling so alive\nLights are shining bright",
"audio_settings": {
"sample_rate": 44100,
"bitrate": 256000,
"format": "mp3"
},
"response_format": "base64"
}
Response
A successful request returns a job object with a unique job ID and polling information:
{
"id": "job-1234567890abcdef1234567890abcdef",
"object": "music.generation.job",
"status": "pending",
"created": 1699123456,
"poll_url": "/api/v1/poll/job-1234567890abcdef1234567890abcdef",
"processing_mode": "background"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique job identifier for polling |
status | string | Current job status: "pending", "processing", "completed", or "failed" |
created | integer | Unix timestamp of job creation |
poll_url | string | Endpoint to poll for job status and results |
processing_mode | string | "background" or "synchronous" depending on server configuration |
Polling for Results: GET /api/v1/poll/<job_id>
After creating a generation job, poll this endpoint to check the status and retrieve results when complete.
Request
Make a GET request to the poll URL provided in the generation response, or construct it manually:
GET /api/v1/poll/job-1234567890abcdef1234567890abcdef
Authorization: Bearer YOUR_API_KEY
Response - Job Pending/Processing
{
"id": "job-1234567890abcdef1234567890abcdef",
"object": "music.generation.job",
"status": "processing",
"created": 1699123456,
"updated": 1699123461,
"poll_interval": 5,
"message": "Job is still processing. Please poll again."
}
Response - Job Completed
{
"id": "job-1234567890abcdef1234567890abcdef",
"object": "music.generation.job",
"status": "completed",
"created": 1699123456,
"updated": 1699123490,
"result": {
"id": "music-gen-abcdef123456",
"object": "music.generation",
"created": 1699123490,
"model": "music-2.0",
"choices": [
{
"index": 0,
"audio": {
"data": "base64_encoded_audio_data_here...",
"format": "mp3",
"encoding": "base64"
},
"finish_reason": "completed"
}
],
"usage": {
"estimated_cost": 0.03,
"currency": "USD"
}
}
}
Response - Job Failed
{
"id": "job-1234567890abcdef1234567890abcdef",
"object": "music.generation.job",
"status": "failed",
"created": 1699123456,
"updated": 1699123470,
"error": {
"message": "Generation failed due to invalid prompt",
"type": "generation_error"
}
}
Audio Formats
The API supports multiple audio formats and quality settings to suit different use cases.
MP3 Format
Compressed audio format ideal for streaming and storage efficiency. Recommended for most applications.
| Parameter | Options | Description |
|---|---|---|
sample_rate | 8000, 16000, 22050, 24000, 32000, 44100, 48000 | Higher rates provide better quality (44100 recommended) |
bitrate | 64000 - 320000 | Higher bitrates provide better quality (256000 recommended) |
Example: High Quality MP3
{
"audio_settings": {
"format": "mp3",
"sample_rate": 48000,
"bitrate": 320000
}
}
WAV Format
Uncompressed audio format for professional audio production and editing.
{
"audio_settings": {
"format": "wav",
"sample_rate": 44100
}
}
FLAC Format
Lossless compressed audio format. Provides perfect quality with smaller file sizes than WAV.
{
"audio_settings": {
"format": "flac",
"sample_rate": 44100
}
}
Sample Rate Recommendations
| Sample Rate | Use Case |
|---|---|
| 8000 Hz | Telephony, voice-only applications |
| 16000 Hz | Voice-focused content, reduced file size |
| 22050 Hz | Basic music quality, web streaming |
| 44100 Hz | CD quality, recommended for most music (default) |
| 48000 Hz | Professional audio, video soundtracks |
Response Formats
Control how the audio data is encoded in the API response using the response_format parameter.
Hex Encoding (Default)
Raw hexadecimal encoding of the audio binary data. Efficient for server-to-server communication.
{
"response_format": "hex"
}
// Response
{
"audio": {
"data": "49443303000000000f...",
"encoding": "hex"
}
}
Base64 Encoding
Standard Base64 encoding. Compatible with most programming languages and easier to handle in JSON.
{
"response_format": "base64"
}
// Response
{
"audio": {
"data": "SUQzAwAAAAAA...",
"encoding": "base64"
}
}
Data URL
Complete data URL with MIME type. Can be used directly in HTML audio elements or image tags.
{
"response_format": "data_url"
}
// Response
{
"audio": {
"data": "data:audio/mp3;base64,SUQzAwAAAAAA...",
"encoding": "data_url"
}
}
Usage in HTML
<audio controls>
<source src="data:audio/mp3;base64,SUQzAwAAAAAA..." type="audio/mpeg">
</audio>
Error Handling
When an error occurs, the API returns an appropriate HTTP status code and a JSON error object:
{
"error": {
"message": "Invalid API key provided",
"type": "invalid_request_error",
"code": null
}
}
Common Error Codes
| Status Code | Error Type | Description |
|---|---|---|
400 | Bad Request | Invalid request format or parameters |
401 | Unauthorized | Missing or invalid API key |
402 | Payment Required | Insufficient account balance |
404 | Not Found | Job ID not found or expired |
500 | Server Error | Internal server error, try again later |
Generation Errors
Errors during music generation are returned in the job result:
{
"status": "failed",
"error": {
"message": "Prompt contains inappropriate content",
"type": "content_policy_violation"
}
}
Error Types
| Error Type | Description |
|---|---|
invalid_request_error | Request parameters are invalid or malformed |
authentication_error | API key is missing, invalid, or expired |
insufficient_balance | Account balance is too low for the operation |
generation_error | Music generation process failed |
content_policy_violation | Prompt violates content policy |
server_error | Internal server error occurred |
Code Examples
Here are examples of how to use the API in different programming languages.
import requests
import time
import base64
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://music.demo.efficientstack.com/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def generate_music(prompt, lyrics=None, model="music-2.0"):
"""Create a music generation job"""
payload = {
"model": model,
"prompt": prompt,
"audio_settings": {
"sample_rate": 44100,
"bitrate": 256000,
"format": "mp3"
},
"response_format": "base64"
}
if lyrics:
payload["lyrics"] = lyrics
response = requests.post(
f"{BASE_URL}/generate",
headers=headers,
json=payload
)
if response.status_code != 200:
raise Exception(f"Generation failed: {response.json()}")
return response.json()
def poll_job(job_id, max_attempts=60, interval=5):
"""Poll for job completion"""
for attempt in range(max_attempts):
response = requests.get(
f"{BASE_URL}/poll/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
if response.status_code != 200:
raise Exception(f"Polling failed: {response.json()}")
data = response.json()
status = data["status"]
print(f"Attempt {attempt + 1}: Status = {status}")
if status == "completed":
return data["result"]
elif status == "failed":
raise Exception(f"Generation failed: {data['error']['message']}")
time.sleep(interval)
raise Exception("Job timed out")
def save_audio(audio_data, filename, encoding="base64"):
"""Save audio data to file"""
if encoding == "base64":
audio_bytes = base64.b64decode(audio_data)
elif encoding == "hex":
audio_bytes = bytes.fromhex(audio_data)
else:
raise ValueError(f"Unsupported encoding: {encoding}")
with open(filename, "wb") as f:
f.write(audio_bytes)
print(f"Audio saved to {filename}")
# Example usage
if __name__ == "__main__":
# Generate music
prompt = "upbeat electronic dance music with energetic drums"
lyrics = "Dancing through the night\nFeeling so alive"
print("Creating music generation job...")
job = generate_music(prompt, lyrics, model="music-2.0")
job_id = job["id"]
print(f"Job created: {job_id}")
print("Polling for results...")
# Poll for results
result = poll_job(job_id)
# Save audio
audio_data = result["choices"][0]["audio"]["data"]
encoding = result["choices"][0]["audio"]["encoding"]
save_audio(audio_data, "generated_music.mp3", encoding)
# Print usage info
cost = result["usage"]["estimated_cost"]
print(f"Estimated cost: ${cost}")
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://music.demo.efficientstack.com/api/v1";
const headers = {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
};
async function generateMusic(prompt, lyrics = null, model = "music-2.0") {
const payload = {
model: model,
prompt: prompt,
audio_settings: {
sample_rate: 44100,
bitrate: 256000,
format: "mp3"
},
response_format: "base64"
};
if (lyrics) {
payload.lyrics = lyrics;
}
const response = await fetch(`${BASE_URL}/generate`, {
method: "POST",
headers: headers,
body: JSON.stringify(payload)
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Generation failed: ${error.error.message}`);
}
return await response.json();
}
async function pollJob(jobId, maxAttempts = 60, interval = 5000) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const response = await fetch(`${BASE_URL}/poll/${jobId}`, {
headers: { "Authorization": `Bearer ${API_KEY}` }
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Polling failed: ${error.error.message}`);
}
const data = await response.json();
const status = data.status;
console.log(`Attempt ${attempt + 1}: Status = ${status}`);
if (status === "completed") {
return data.result;
} else if (status === "failed") {
throw new Error(`Generation failed: ${data.error.message}`);
}
// Wait before next poll
await new Promise(resolve => setTimeout(resolve, interval));
}
throw new Error("Job timed out");
}
function downloadAudio(audioData, filename, encoding = "base64") {
let blob;
if (encoding === "base64") {
const binaryString = atob(audioData);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
blob = new Blob([bytes], { type: "audio/mpeg" });
} else if (encoding === "data_url") {
// Extract base64 from data URL
const base64 = audioData.split(',')[1];
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
blob = new Blob([bytes], { type: "audio/mpeg" });
}
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
console.log(`Audio downloaded: ${filename}`);
}
// Example usage
async function main() {
try {
const prompt = "upbeat electronic dance music with energetic drums";
const lyrics = "Dancing through the night\nFeeling so alive";
console.log("Creating music generation job...");
const job = await generateMusic(prompt, lyrics, "music-2.0");
const jobId = job.id;
console.log(`Job created: ${jobId}`);
console.log("Polling for results...");
const result = await pollJob(jobId);
const audioData = result.choices[0].audio.data;
const encoding = result.choices[0].audio.encoding;
downloadAudio(audioData, "generated_music.mp3", encoding);
const cost = result.usage.estimated_cost;
console.log(`Estimated cost: $${cost}`);
} catch (error) {
console.error("Error:", error.message);
}
}
main();
#!/bin/bash
API_KEY="YOUR_API_KEY"
BASE_URL="https://music.demo.efficientstack.com/api/v1"
# Create music generation job
echo "Creating music generation job..."
RESPONSE=$(curl -s -X POST "$BASE_URL/generate" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "music-2.0",
"prompt": "upbeat electronic dance music with energetic drums",
"lyrics": "Dancing through the night\nFeeling so alive",
"audio_settings": {
"sample_rate": 44100,
"bitrate": 256000,
"format": "mp3"
},
"response_format": "base64"
}')
# Extract job ID
JOB_ID=$(echo $RESPONSE | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Job created: $JOB_ID"
# Poll for results
echo "Polling for results..."
MAX_ATTEMPTS=60
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
ATTEMPT=$((ATTEMPT + 1))
POLL_RESPONSE=$(curl -s -X GET "$BASE_URL/poll/$JOB_ID" \
-H "Authorization: Bearer $API_KEY")
STATUS=$(echo $POLL_RESPONSE | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
echo "Attempt $ATTEMPT: Status = $STATUS"
if [ "$STATUS" = "completed" ]; then
echo "Job completed!"
# Extract audio data and save to file
echo $POLL_RESPONSE | \
grep -o '"data":"[^"]*"' | \
head -1 | \
cut -d'"' -f4 | \
base64 -d > generated_music.mp3
echo "Audio saved to generated_music.mp3"
exit 0
elif [ "$STATUS" = "failed" ]; then
echo "Job failed!"
echo $POLL_RESPONSE
exit 1
fi
sleep 5
done
echo "Job timed out!"
exit 1
<?php
$apiKey = "YOUR_API_KEY";
$baseUrl = "https://music.demo.efficientstack.com/api/v1";
function generateMusic($apiKey, $baseUrl, $prompt, $lyrics = null, $model = "music-2.0") {
$payload = [
'model' => $model,
'prompt' => $prompt,
'audio_settings' => [
'sample_rate' => 44100,
'bitrate' => 256000,
'format' => 'mp3'
],
'response_format' => 'base64'
];
if ($lyrics !== null) {
$payload['lyrics'] = $lyrics;
}
$ch = curl_init("$baseUrl/generate");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
$error = json_decode($response, true);
throw new Exception("Generation failed: " . $error['error']['message']);
}
return json_decode($response, true);
}
function pollJob($apiKey, $baseUrl, $jobId, $maxAttempts = 60, $interval = 5) {
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
$ch = curl_init("$baseUrl/poll/" . urlencode($jobId));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
$error = json_decode($response, true);
throw new Exception("Polling failed: " . $error['error']['message']);
}
$data = json_decode($response, true);
$status = $data['status'];
echo "Attempt " . ($attempt + 1) . ": Status = $status\n";
if ($status === 'completed') {
return $data['result'];
} else if ($status === 'failed') {
throw new Exception("Generation failed: " . $data['error']['message']);
}
sleep($interval);
}
throw new Exception("Job timed out");
}
function saveAudio($audioData, $filename, $encoding = 'base64') {
if ($encoding === 'base64') {
$audioBytes = base64_decode($audioData);
} else if ($encoding === 'hex') {
$audioBytes = hex2bin($audioData);
} else {
throw new Exception("Unsupported encoding: $encoding");
}
file_put_contents($filename, $audioBytes);
echo "Audio saved to $filename\n";
}
// Example usage
try {
$prompt = "upbeat electronic dance music with energetic drums";
$lyrics = "Dancing through the night\nFeeling so alive";
echo "Creating music generation job...\n";
$job = generateMusic($apiKey, $baseUrl, $prompt, $lyrics, "music-2.0");
$jobId = $job['id'];
echo "Job created: $jobId\n";
echo "Polling for results...\n";
$result = pollJob($apiKey, $baseUrl, $jobId);
$audioData = $result['choices'][0]['audio']['data'];
$encoding = $result['choices'][0]['audio']['encoding'];
saveAudio($audioData, 'generated_music.mp3', $encoding);
$cost = $result['usage']['estimated_cost'];
echo "Estimated cost: \$$cost\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>