https://api.vaelor.chat/v1/musicComposes a full track — vocals and instruments, or instrumental only — from a description and optional lyrics. Rendering takes one to several minutes, so the response is an NDJSON event stream that ends with the finished track.
Body#
requestIduuidRequiredA UUID you generate for this track. Retrying with the same ID never creates or bills a second track. See Idempotency.
configurationobjectRequiredWhat to compose.
modeenumRequiredsimple composes from description alone. custom uses every field you set.descriptionstringRequireddurationintegerRequiredlanguageenumRequireden, es, ja or pt. 20 languages are supported.instrumentalbooleanRequiredtrue for no vocals.titlestringlyricsstring[Verse] and [Chorus], up to 8,000 characters.genrestringsynthwave or bossa nova. Up to 120 characters.moodstringmelancholic, hopeful. Up to 120 characters.instrumentsstringvocalStylestringbreathy female alto. Up to 120 characters.keystringF# minor.bpmintegernegativePromptstringguidanceScalenumberRequiredthinkbooleanRequiredseedintegerResponse#
An application/x-ndjson stream of heartbeat, stage, complete and error events. The complete event carries the finished track and your remaining balance.
Example#
curl -N https://api.vaelor.chat/v1/music \
-H "Authorization: Bearer $VAELOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"requestId": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"configuration": {
"mode": "custom",
"title": "Harbor Lights",
"description": "A late-night synthwave drive along the coast",
"genre": "synthwave",
"mood": "nostalgic, warm",
"duration": 180,
"language": "en",
"instrumental": true,
"bpm": 96,
"guidanceScale": 7,
"think": true
}
}'const response = await fetch('https://api.vaelor.chat/v1/music', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VAELOR_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requestId: crypto.randomUUID(),
configuration: {
mode: 'custom',
title: 'Harbor Lights',
description: 'A late-night synthwave drive along the coast',
genre: 'synthwave',
mood: 'nostalgic, warm',
duration: 180,
language: 'en',
instrumental: true,
bpm: 96,
guidanceScale: 7,
think: true
}
})
})import uuid
response = requests.post(
"https://api.vaelor.chat/v1/music",
headers={"Authorization": f"Bearer {os.environ['VAELOR_API_KEY']}"},
json={
"requestId": str(uuid.uuid4()),
"configuration": {
"mode": "custom",
"title": "Harbor Lights",
"description": "A late-night synthwave drive along the coast",
"genre": "synthwave",
"mood": "nostalgic, warm",
"duration": 180,
"language": "en",
"instrumental": True,
"bpm": 96,
"guidanceScale": 7,
"think": True,
},
},
stream=True,
)Response200
{"type":"stage","message":"Composing your track. This may take a few minutes…"}
{"type":"heartbeat"}
{"type":"stage","message":"Saving your song…"}
{"type":"complete","track":{"id":"5f0c2d1e-7a39-4b8e-9e61-2d4f8a0b3c77","status":"ready","title":"Harbor Lights","durationSeconds":180,"creditCost":180},"usageRemaining":420}Billing#
The cost is duration × 1 credit, reserved in full before rendering starts. If rendering fails you get an error event and the credits are refunded.
Errors#
| Status | When |
|---|---|
400 | The configuration failed validation, or the combined prompt exceeds 2,000 characters. |
402 | Not enough credits for the requested duration. |
409 | DUPLICATE_REQUEST — a track already exists for this requestId. |
503 | Music generation is temporarily unavailable. |