Breaking and behaviour-affecting changes to the MusicAPI HTTP API, newest first.Cosmetic and additive-only changes are not listed here. If a change can alter
what your integration receives, it belongs on this page.Want these by email? Write to support@musicapi.ai with the subject
changelog and the account you integrate with, and we will send a short notice
before changes of this kind.
2026-10-13 — Polling: mv is always the sonic-* id, and every task failure answers 200#
Affects: GET /api/v1/sonic/task/{task_id}1. mv is always the documented sonic-* id. Some polls returned the model as chirp-v6, chirp-v3-5 and so on, depending on how the task was processed, and a few changed spelling between the rendering answer and the finished one. Every poll now returns the documented id — sonic-v6, sonic-v4-5-plus, etc. — whichever spelling you sent on create. If you compare mv against chirp-* values, compare against sonic-* instead. Webhook payloads are unchanged.2. A task failure always answers HTTP 200. A small share of failed tasks answered a content rejection with 403 and a timeout with 504; the rest already answered 200. All of them now answer 200 with the failure in the body (type, message, reason_code, retriable). Request errors (validation 400, authentication 401, credits 403) are unchanged.What to check: detect a failed task from type / reason_code in the body, not from the HTTP status. See Error handling.
2026-10-12 — Polling a song that is still rendering: 200 with state: "running" again#
Affects: GET /api/v1/sonic/task/{task_id} while a generation is still renderingThis reverses point 2 of the 2026-10-10 entry below. Answering a rendering song with 202 stopped integrations that read the stream from a 200 with state: "running". Rendering is back to how it was before 2026-10-10:200 {"code": 200, "message": "success", "data": [ { "state": "running", "audio_url": "https://api.musicapi.ai/api/v1/stream/<id>", ... } ]}
The caching problem that prompted the 202 is fixed on our side: a 200 that still contains a running clip is never cached as a finished answer, so the next poll returns the finished song.Unchanged from 2026-10-10: the stream link is always on our own domain (https://api.musicapi.ai/api/v1/stream/<id>). A finished song is 200 with state: "succeeded" and the final file on files.musicapi.ai.What to check: decide "done" from state: "succeeded" on every clip, not from the HTTP status. If you switched to reading the stream from the 202 body on 2026-10-10, a 202 with type: "not_ready" still appears before the stream is available, so that code keeps working; the stream itself now arrives in a 200.
2026-10-10 — Polling a song that is still rendering: our stream URL, and a 202#
Affects: GET /api/v1/sonic/task/{task_id} while a generation is still rendering1. The stream link is now always on our domain. While a song renders, audio_url can hold a link you can already play. Some polls returned it on a third-party host. It is now always our own stream address, https://api.musicapi.ai/api/v1/stream/<id>, which plays the same audio. Once the song is finished, audio_url is the final file on files.musicapi.ai, as before.2. A still-rendering answer is now 202 with type: "not_ready". Reverted on 2026-10-12, see above. Some polls answered a rendering song with 200 and state: "running". That answer could be cached for several minutes, so a later poll could keep showing the stream after the song had finished. Rendering now always answers like this, the same shape other in-progress polls already used:202 {"type": "not_ready", "error": "task not ready, please wait few seconds.", "data": [ { "state": "running", "audio_url": "https://api.musicapi.ai/api/v1/stream/<id>", ... } ]}
A finished song is still 200 with state: "succeeded".What to check: if your code treats any 200 as "done", nothing changes for you. If it read audio_url from a 200 with state: "running", read it from the 202 body's data instead.
2026-10-10 — persona_music: three optional voice-fidelity parameters, and max_mode costs double#
Affects: POST /api/v1/sonic/create with task_type: "persona_music"All three are optional. If you send none of them, nothing changes.| Parameter | Type | What it does |
|---|
audio_weight | number, 0–1 | How strongly the song follows the Persona's reference voice |
variety | off / normal / high / extra / max (default normal) | How far the style may wander. off keeps the voice closest to the Persona |
max_mode | boolean (default false) | Spends more compute on consistency across the song |
Billing: with max_mode: true a generation costs double (40 credits on v6 instead of 20). A failed max_mode generation refunds the full 40.Validation: an unknown variety value, a non-boolean max_mode, or an audio_weight outside 0–1 returns 400. Sending variety or max_mode with any other task_type also returns 400, because those task types would ignore them.What to check: nothing, unless you want to use them. For voice likeness, start with variety: "off" and an audio_weight around 0.7–0.9, and add max_mode only where consistency matters enough to pay double.
2026-10-10 — Persona creation works again; clearer errors when it can't#
Affects: POST /api/v1/sonic/persona1. Fixed: persona creation failed for most new clips. From about 2026-09-20,
creating a persona from a clip that had never been used for one usually
returned 500 {"error": "Internal Server Error"}. The cause was on our side: we
gave up on the request before the persona was ready. We now wait for it. Expect
a first-time persona to take about 10–30 seconds. Repeating the request for the
same clip returns the same persona_id, so retrying never creates a duplicate.
Personas you already have were never affected.2. If it still fails, you get 503, not 500:503 {"type": "service_unavailable", "error": "Persona creation is temporarily unavailable: the request was dropped before a result came back. No persona was returned and no credits were charged. Please retry later."}
3. Uploaded audio is rejected. A persona built from a clip_id returned by
upload_song fails with 400 Voices cannot be made from audio uploads. This
comes from Suno and is final. Use clips generated on the platform.What to check: give this request a client timeout of at least 60 seconds,
and handle 503 alongside 500. Failed persona requests are never charged.
2026-09-09 — Suno v6 is selectable, and every model now costs the same#
Affects: every endpoint that takes mv1. v6 is available. sonic-v6, sonic-v6-wild and sonic-v6-mini are
accepted mv values on the generation endpoints. Nothing else about the request
changes.2. Generation now costs 20 credits on every model. sonic-v3-5 and
sonic-v4 used to cost 15 because Suno charged less to run them. Suno retired
v3.5 through v5.5 on its own platform and maps those ids onto v6, so a request
naming one of them runs v6 — at v6's cost. The remix family (add_vocals,
add_instrumental, remaster) moves from 10 to 15 for the same reason.Unchanged: the extend family stays at 15, stem separation at 30 / 75, and the
price you pay per credit is untouched.| Operation | Before | Now |
|---|
Generation on sonic-v3-5 / sonic-v4 | 15 | 20 |
| Generation on every other model | 20 | 20 |
| Extend / replace-section, any model | 15 | 15 |
add_vocals / add_instrumental / remaster on the retired ids | 10 | 15 |
What to check: if you pin mv to sonic-v3-5 or sonic-v4, the same call
now consumes 20 credits instead of 15 — and the audio comes from v6, so it can
also sound different. Nothing in your request has to change; your credit burn
does. If you were choosing an older model for cost, that reason no longer
exists and you may as well name sonic-v6 so the request says what it does.
2026-09-09 — Suno retired v3.5–v5.5; the model IDs are unchanged#
Affects: every endpoint that takes mvSuno released v6 and retired v3.5, v4, v4.5, v4.5-plus, v5 and v5.5 on its own
platform. Suno's published model mapping sends a request naming a retired
version to v6.No request change is required. Every mv value documented before today is
still accepted and still valid.
Credit costs are unchanged.
mv in responses still reports the model ID the task was created with.
Suno's v6-wild and v6-mini are not selectable through this API yet. Adding
them will get its own entry here.
What to check: if you picked an older version deliberately for its sound,
the version you name is no longer what Suno runs. The audio character can shift
with no change on your side, while the field you read back stays the same.
2026-09-07 — state: "succeeded" now means the MP3 exists#
Affects: GET /api/v1/sonic/task/{task_id}A clip could previously report state: "succeeded" while audio_url still held
the live preview stream rather than the finished file. Callers that polled until
succeeded and then downloaded got audio that plays but never completes.A clip now reports state: "running" until a real MP3 exists.state: "succeeded" is the authoritative completion signal.
On a succeeded clip, audio_url is the final MP3 on our own CDN.
While rendering, stream_audio_url carries the preview and is absent once
the clip is finished.
What to check: if you poll until succeeded and act immediately, you will
now wait slightly longer and receive a finished file. If you relied on
succeeded appearing early to start playback, read stream_audio_url instead.
2026-09-07 — rejected uploads now return the reason#
Affects: POST /api/v1/sonic/uploadA rejected upload could return Upload request failed (HTTP 400) with no
reason, while the same underlying rejection returned a descriptive message on a
different code path. Which one you got depended on the MP3 header, not on the
cause.The reason is now returned consistently — for example Invalid audio file
instead of the generic wording. The HTTP status is unchanged.
2026-09-06 — live preview stream is served from our domain#
Affects: GET /api/v1/sonic/task/{task_id}, song.streaming webhooksSuno moved the preview stream that plays while a clip renders to a new host on
2026-09-05. It is now relayed through our own domain rather than that host being
passed through to you:https://api.musicapi.ai/api/v1/stream/{clip_id}
The response is audio/mpeg and readable cross-origin. If you allowlist hosts,
add api.musicapi.ai. Final MP3s are unaffected and remain on our CDN.
2026-09-04 — /sonic/midi now has a terminal answer#
Affects: POST /api/v1/sonic/midi⚠️ Backfilled 2026-09-11. This shipped on 2026-09-04, three days before this
changelog existed, and was never announced. A customer found it by noticing the
documentation had changed. That is the gap this page exists to close, so it is
recorded here rather than quietly left out.A MIDI conversion that stalled used to answer 202 forever. There was no
terminal state, so a caller polling until "done or failed" polled indefinitely.A stalled conversion now returns 400, which is terminal:202 — still converting. Retry the same request.
400 — terminal. The conversion stalled, or the source audio is too old to
convert. Do not retry this clip_id.
What to check: if your client treats any non-200 as retryable, a stalled
clip will now stop retrying instead of looping. Nothing is charged for a 202
or a 400 — only a successful 200 costs credits.There is no 24-hour eligibility window for MIDI, and there never was one in
the code. An older documentation example implied one; that was wrong and has
been corrected. What actually limits eligibility is whether the source audio is
still convertible, which is why the answer is a 400 rather than a rule you can
compute from the clip's age.
2026-09-02 — /sonic/midi distinguishes a dead source account from the 7-day window#
Backfilled 2026-09-11. This shipped on 2026-09-02, before this changelog
existed, and was never announced.When the Suno account that generated a clip has been deactivated upstream,
POST /api/v1/sonic/midi now returns 400 with:MIDI extraction failed because the upstream provider can no longer retrieve
the source audio for this clip. Please regenerate the track or use a
different clip_id.
Previously this case produced the ~7-day retention message, which was
misleading — the cause is the source account, not the age of
the audio. If you match on error text, this is a new string. It is terminal
for that clip_id: do not retry it.
2026-09-02 — POST /api/v1/sonic/download added#
Additive. Returns a stored MP3, M4A or WAV for a clip you have already
generated. Existing endpoints are unchanged.
2026-08-30 — use_suno_cdn no longer changes the link host#
Affects: /api/v1/sonic/createResult audio and image URLs are always served from our delivery CDN, whatever
use_suno_cdn is set to. The field is still accepted, and non-boolean values
still return 400 validation_error, so no request needs to change. If you were
relying on cdn1/cdn2.suno.ai links, switch to the URLs in the response. Modified at 2026-10-12 13:18:55