6.8 KiB
ACE-Step 1.5 Turbo music and songs
Source: maintainer's 2026-10-15 unified API guide; public models and OpenAPI inspected the same day. This is the hosted service's protocol, not upstream ACE-Step API.
POST /v1/audio/music/acestep, JSON. Model acestep-v15-turbo, optional semantic LM acestep-5Hz-lm-0.6B. Reuse the existing service Bearer token or an enabled KeyInfo member key via AUDIO_API_TOKEN; no separate ACE-Step key. Never embed a real key in the skill or a public frontend.
Choose ACE-Step explicitly for Turbo instrumentals or supplied-lyric songs. Existing music/sfx still call Stable Audio; yue2 still supports its own lyric/ABC workflow. This ACE-Step route has no reference audio, covers, inpainting, continuation, stems or multi-output batch mode.
Fields and mode checks
Only prompt is required. Unknown fields return 422. Character limits count Unicode characters, not UTF-8 bytes.
| Field | Default | Allowed / meaning |
|---|---|---|
| prompt | required | Nonblank 1–512 characters; describe 2–5 core traits such as genre, instruments, mood and arrangement. Put sung words in lyrics |
| lyrics | "" |
String <=4096 characters; omitted/empty is valid for instrumentals, null is invalid |
| instrumental | true | Boolean; set false explicitly for a lyric song |
| seconds | 30 | Number 10–600; deployment may lower the upper bound, see models.acestep.max_seconds |
| steps | 8 | Integer 1–20; start at 8, try 4 for drafts. Do not copy non-Turbo 30/50-step settings |
| seed | null/random | Integer 0–4294967295 or null; actual value in response X-Audio-Seed |
| use_lm | true | Boolean; optional 0.6B planning. False usually lowers latency but changes results; the text encoder still runs |
| vocal_language | unknown | Exact code below; zh Mandarin, yue Cantonese, en English. Not auto/zh-CN; does not translate lyrics |
| bpm | null | Integer 30–300 or null; rhythmic condition, not a guarantee of measured beat accuracy |
| keyscale | "" |
<=16 characters; empty or A–G + optional #/b/♯/♭ + space + Major/Minor, e.g. C Major, F# minor, Bb Major; no Am shorthand |
| timesignature | "" |
String "", "2", "3", "4", "6"; correspond to unspecified, 2/4, 3/4, 4/4, 6/8. Not "4/4" |
instrumental=true allows only omitted/empty/whitespace lyrics or [Instrumental]. instrumental=false requires nonblank lyrics other than that marker. Conflicts return 422 instead of silently discarding lyrics. Instrumental conditioning does not guarantee the absence of voice-like sounds.
Language codes:
ar az bg bn ca cs da de el en es fa fi fr he hi hr ht hu id
is it ja ko la lt ms ne nl no pa pl pt ro ru sa sk sr sv sw
ta te th tl tr uk ur vi yue zh unknown
Turbo guidance is fixed at 1.0: do not send cfg, cfg_scale or guidance_scale. Internal shift=3.0, batch_size=1 and ODE are not request controls. LM does not write/rewrite lyrics or prompt, and does not fill unspecified BPM/key/meter via CoT. More steps do not guarantee better quality.
CLI and payload examples
Use existing environment credentials. In this repository prefix external commands with rtk proxy; replace <skill-dir> with the actual skill path.
python '<skill-dir>/scripts/call_voice_api.py' acestep --prompt 'Warm piano, bright acoustic guitar, steady drums, upbeat indie pop. Instrumental, no vocals.' --instrumental true --seconds 30 --steps 8 --seed 7 --out music.wav
python '<skill-dir>/scripts/call_voice_api.py' acestep --prompt 'Mandarin acoustic pop, clear female vocal, warm piano, gentle drums.' --instrumental false --lyrics-file lyrics.txt --vocal-language zh --seconds 30 --steps 8 --use-lm true --bpm 120 --keyscale 'C Major' --timesignature 4 --seed 7 --out song.wav
--lyrics and UTF-8/BOM --lyrics-file are alternatives; add --dry-run to inspect a request without credentials or inference. The helper defaults to a 900-second timeout and prints the actual response seed when a valid X-Audio-Seed header is available; it does not substitute the requested seed for a missing header.
Equivalent song JSON:
{
"prompt": "Mandarin acoustic pop, clear female vocal, warm piano, gentle drums.",
"instrumental": false,
"lyrics": "[Verse]\n风吹过安静的街道\n你的笑还留在转角\n[Chorus]\n我们向着晨光奔跑\n让每个明天都闪耀",
"vocal_language": "zh",
"seconds": 30,
"steps": 8,
"use_lm": true,
"seed": 7
}
Use a JSON serializer for real multiline strings; do not double-escape \n. [Verse]/[Chorus] guide structure but are not strict score instructions. 4096 input characters do not fit automatically in 30 seconds: start with a short verse/chorus, match duration to lyrics, then listen for omissions, truncation, repetition and word accuracy. Neither lyrics nor seed ensure exact performance across hardware/versions.
Output, availability and failures
Success is complete 48 kHz stereo PCM16 WAV with Content-Disposition: attachment; filename=acestep.wav and X-Audio-Seed. Use bytes/arrayBuffer/Blob after checking HTTP status/media; no JSON/Base64/download URL. The generated OpenAPI 200 entry currently says application/json; follow the supplied binary contract and check the actual response. Approximate PCM data: 30 s = 5.76 MB, 600 s = 115.2 MB; account for client/proxy response size and memory. CORS/proxies must expose X-Audio-Seed for browser access.
One active ACE-Step task per API process, including first load; busy rejects immediately with 503 + Retry-After: 2, without queueing. Missing installation, disabled autostart and worker connection failures can also be 503; retry only explicit busy rejection with a finite bound. The helper never retries.
This is synchronous: output starts after generation, with no streaming playback, job ID, progress or cancellation. First use includes weight verification/loading/compilation; first LM use loads the LM too. Client disconnect/timeout or proxy HTML 504 may leave inference running. The guide distinguishes internal JSON 504, which terminates the worker, from proxy timeout; diagnose before manually resubmitting either.
401 needs credential correction; 422 needs schema/mode/deployment-limit correction; 500 indicates failed/invalid generation and worker cleanup. Startup and inference have separate timeouts (currently 120 + 600 seconds); a client timeout of 900 does not extend a gateway timeout.
Public /models reports models.acestep installed/state/loaded/lm_loaded/max_seconds; /health and /models do not load or prewarm models. installed=true is not proof that weight validation or inference succeeds; stopped/loaded=false can be normal lazy startup. Hosted callers need no local runtime/extra port. Service deployment/worker changes belong to the operator, not this skill's request workflow.