Skip to content

Suno Cloud v1 Migration Guide

This guide is the public contract and migration runbook for existing Suno Cloud clients. OmnAPI exposes nine compatibility endpoints at the original /v1 paths so you can separate the host and credential cutover from the later API redesign.

All nine covered routes are implemented. Request names, the main success shapes, real clip IDs, and the live service’s 200/201 success status rules are preserved. Differences that protect account isolation, use OmnAPI credits, or reflect the OmnAPI task model are listed in Deliberate differences.

MethodCompatibility pathSupported purposeModern destination
POST/v1/generateCustom, extend, upload-extend, cover, or Persona musicSuno songs/derive routes, or a generic upload-extend task
POST/v1/generate-gptSimple prompt-to-song generationPOST /api/v1/suno/songs with mode: "simple"
POST/v1/generate/lyricLyrics generationPOST /api/v1/suno/lyrics
POST/v1/concatenateConcatenate an existing extended clipGeneric concat-music task
GET/v1/songsCompatibility resource lookup and recent resultsClip lookup or task history, depending on the query
GET/v1/songs/lyric-stampAligned lyrics timelineGET /api/v1/suno/clips/{clipId}/timeline
GET/v1/infoCompatibility credit-account viewDashboard and usage export
POST/v1/stemsBasic two-stem exportPOST /api/v1/suno/clips/{clipId}/export
POST/v1/generate-wavWAV exportPOST /api/v1/suno/clips/{clipId}/export

Every other Suno Cloud path is outside this compatibility contract.

https://api.omnapi.com

The compatibility paths are mounted directly under /v1; there is no additional /legacy prefix.

Both header names are accepted:

api-key: YOUR_OMNAPI_KEY
x-api-key: YOUR_OMNAPI_KEY

The header name can remain unchanged during phase one, but the credential value cannot. Create a new OmnAPI API key in the dashboard; existing Suno Cloud key values are not portable. Grant these scopes as needed:

ScopeUsed by
task:createThe six POST endpoints
task:read/v1/songs and /v1/songs/lyric-stamp
usage:read/v1/info

All six write routes accept Idempotency-Key, including the zero-credit lyrics task. Reuse the same key only when retrying the same logical request with an unchanged body. Deduplication is scoped to the customer and exact compatibility route; it does not span a different /v1 route, a modern /api/v1 route, or the old Suno Cloud host.

Terminal window
curl https://api.omnapi.com/v1/info \
-H "api-key: $OMNAPI_KEY"

Compatibility responses include:

Deprecation: @1784073600
Link: <https://docs.omnapi.com/legacy/suno/>; rel="deprecation"; type="text/html"

The Deprecation value is an RFC 9745 Structured Field Date: it marks the compatibility surface as deprecated from 2026-07-15T00:00:00Z. It is not the retirement date. If a retirement date is scheduled, the response also carries a Sunset header; treat that value as authoritative.

Do not treat every field containing “id” as interchangeable.

FieldMeaningSafe use
idCompatibility resource-row ID in the OmnAPI data store/v1/songs?ids=... for resources created through OmnAPI
midReal Suno clip IDFollow-up clip operations and /v1/songs?mids=...
taskIdLegacy generation-operation identifier when availablePreserve only for old client compatibility; do not use it to poll OmnAPI
omnapiTaskIdStable OmnAPI task UUID added to music responsesGET /api/v1/tasks/{omnapiTaskId}
pollUrlReady-to-use canonical task URLPoll task state and recover after a wait timeout

Generation endpoints wait for a real music resource. They do not fabricate an id or mid from a task UUID. When a real clip cannot be acknowledged within the compatibility wait window, the request returns an error with task recovery details instead of a placeholder song.

/v1/generate, /v1/generate-gpt, and /v1/stems return an array. /v1/concatenate returns one object.

{
"id": "019c...",
"mid": "4fd8...",
"taskId": "legacy-generation-id",
"omnapiTaskId": "019d...",
"pollUrl": "/api/v1/tasks/019d...",
"url": "https://example.com/song.mp3",
"video": "https://example.com/song.mp4",
"cover": "https://example.com/cover.jpeg",
"title": "Late Train",
"tags": "city pop, warm bass",
"prompt": "[Verse] ...",
"mv": "chirp-fenix",
"duration": 123,
"status": "submitted",
"type": "generated",
"concatBy": null,
"syncedAt": "2026-07-15T08:00:01.000Z",
"reGenId": null,
"createdAt": "2026-07-15T08:00:00.000Z",
"updatedAt": "2026-07-15T08:00:01.000Z"
}

The compatibility shape also contains older fields such as identity, uid, payload, detail, and notes. Legacy ownership and execution-provider identifiers are empty or redacted; other compatibility fields may be reconstructed from OmnAPI records. Do not introduce new dependencies on those fields.

Legacy JSON DTO failures return HTTP 422. JSON booleans and numbers must use their real JSON types; strings such as "true" and "42" are not coerced for the covered generation DTOs. Unknown body properties do not change task behavior.

The following legacy model values are accepted:

chirp-auk-turbo
chirp-v4
chirp-auk
chirp-bluejay
chirp-crow
chirp-fenix

The live Suno Cloud guard selected chirp-fenix for every supported value except the exact chirp-auk-turbo value. The compatibility API keeps that selection rule. Malformed model values return 422 instead of reproducing the old validation bypass. A fenix/pro request is not automatically downgraded to turbo when fenix capacity is unavailable; handle the returned availability or service error instead of assuming a lower model ran.

An optional config extension is accepted on write requests:

{
"config": {
"priority": 5,
"webhookUrl": "https://example.com/webhooks/omnapi",
"tags": ["migration"],
"metadata": { "orderId": "ord_123" }
}
}

On the compatibility surface, priority accepts a number or numeric string, is rounded, and is clamped to 1–10. tags entries are converted to strings; an empty webhookUrl is ignored; a non-object metadata becomes an empty object. Prefer the canonical modern limits: priority 1–10, at most 20 tags of 100 characters each, an object for metadata, and a valid URI for webhookUrl. Feature-specific modern Suno routes keep these values inside config. Generic /api/v1/tasks and /api/v1/tasks/sync requests instead put priority, tags, metadata, and webhookUrl at the request top level.

Legacy operation or modeModern request mapping
GPT generationSuno songs body: mode: "simple"; gpt_description_promptprompt; make_instrumentalinstrumental; effective legacy model → model
Custom generationSuno songs body: mode: "custom"; legacy promptlyrics (or modern prompt); title/tags keep their names; effective legacy model → model
Persona generationSuno songs body: mode: "vox", plus personaId and the Persona root clip as artistClipId; copy prompt, title, and tags
ExtendPath clip ID = continue_clip_id; derive body uses action: "extend", continue_atcontinueAt, effective legacy model → model, plus prompt/title/tags
CoverPath clip ID = cover_clip_id; derive body uses action: "cover", effective legacy model → model, plus prompt/title/tags
Upload-extendGeneric task model suno/chirp-fenix/upload-extend; put clipId, prompt, title, tags, and continueAt inside inputParameters
LyricsSuno lyrics body uses prompt; omit legacy lyrics_model for equivalent single-candidate behavior
Stems / WAVPath clip ID = mid; export body is { "format": "stems", "stemsMode": "two" } or { "format": "wav" }

“Effective legacy model” is important: use chirp-auk-turbo only when the legacy value was exactly chirp-auk-turbo; use chirp-fenix for every other accepted legacy value or when mv was absent. Copying chirp-v4, chirp-bluejay, or chirp-crow directly into modern model would change the behavior that the compatibility guard preserved.

Modern write routes return HTTP 200 with a CreateTaskResponse task receipt; poll its taskId. The generic sync route returns SyncTaskResponse with HTTP 200 at terminal state or 202 on timeout. Modern clip reads also return the OmnAPI task/result envelope. They do not return the raw legacy music object. The compatibility API permits some empty required strings because the live DTO did; modern simple/custom routes require meaningful generation text. Normalize empty prompts before phase-two migration.

Custom music generation and the four legacy derivative dispatch modes.

FieldTypeRequiredLimit and behavior
promptstringYesMaximum 5,000 characters; an empty string remains valid
titlestringYesMaximum 80 characters; an empty string remains valid
tagsstringYesMaximum 1,000 characters; an empty string remains valid
mvstringNoDefaults to the legacy fenix behavior described above
taskstringNoextend, upload_extend, cover, or vox
continue_clip_idstringConditionalRequired by extend and upload_extend
continue_atnumberNoNon-negative continue point in seconds; string or negative numbers return 422. Absent/null is omitted for extend and becomes 0 for upload-extend
cover_clip_idstringConditionalRequired by cover
persona_idstringConditionalSelects Persona music; required when task is vox

Dispatch order is Persona, extend, upload-extend, cover, then custom. Supplying continue_clip_id without task selects extend. Cover dispatch requires the exact task: "cover"; cover_clip_id by itself does not select cover. Turbo is supported only for custom generation and extend. Extend, upload-extend, and cover sources must have a current-customer OmnAPI creation record. Persona generation likewise requires a current-customer Persona creation record. The old DTO could admit a negative continue_at, but OmnAPI will not schedule one. Normalize stored values to >= 0 before cutover.

HTTP 201 with LegacyMusic[]. The call may wait up to 180 seconds for real clip rows. Extend and upload-extend return their derivative candidates; the compatibility route does not concatenate them automatically. Call POST /v1/concatenate explicitly when the old workflow did so.

Terminal window
curl -X POST https://api.omnapi.com/v1/generate \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-123-generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "[Verse]\nNeon rain on the station floor...",
"title": "Late Train",
"tags": "city pop, warm bass, female vocal",
"mv": "chirp-fenix"
}'
  • Custom generation: POST /api/v1/suno/songs with mode: "custom".
  • Persona generation: POST /api/v1/suno/songs with mode: "vox", the owned Persona as personaId, and that Persona’s root clip as artistClipId.
  • Extend and cover: POST /api/v1/suno/clips/{clipId}/derive, using action: "extend" or action: "cover".
  • Upload-extend has no one-to-one operation in the modern resource API. Use generic POST /api/v1/tasks with model suno/chirp-fenix/upload-extend and input fields clipId, prompt, title, tags, and continueAt.
  • Store the returned modern taskId, then poll GET /api/v1/tasks/{taskId}.

Simple prompt-to-song generation.

FieldTypeRequiredLimit and behavior
gpt_description_promptstringYesMaximum 3,000 characters; an empty string remains valid
make_instrumentalbooleanYesMust be a JSON boolean
mvstringNoUses the legacy model-selection rule

Success is HTTP 201 with LegacyMusic[]; the real-clip wait budget is 180 seconds.

Terminal window
curl -X POST https://api.omnapi.com/v1/generate-gpt \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-124-generate" \
-H "Content-Type: application/json" \
-d '{
"gpt_description_prompt": "uplifting synth pop about a red-eye flight",
"make_instrumental": false
}'

Migrate to POST /api/v1/suno/songs with mode: "simple", map gpt_description_prompt to prompt, and map make_instrumental to instrumental.

FieldTypeRequiredLimit and behavior
promptstringYesMaximum 200 characters; an empty string remains valid
lyrics_modelstringNoValidated for legacy compatibility but intentionally has no model-selection effect

Success is HTTP 201 with a legacy lyrics object containing id, status, text, title, createdAt, and optional tags. The route waits up to 30 seconds. A failed or timed-out task returns a structured error; it is not converted into a successful object with empty lyrics. Its id and createdAt come from the customer-owned OmnAPI resource row, not the external lyrics ID.

Terminal window
curl -X POST https://api.omnapi.com/v1/generate/lyric \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-125-lyrics" \
-H "Content-Type: application/json" \
-d '{"prompt":"bittersweet indie pop about moving away"}'

Migrate to POST /api/v1/suno/lyrics. The compatibility route accepts but ignores lyrics_model; omit it for the equivalent modern single-candidate request. The modern lyricsModel option is intended for paired candidates. The modern API returns a task receipt and supports canonical polling.

FieldTypeRequiredBehavior
midstringYesSource extended clip ID

The source must have a current-customer OmnAPI creation record. Success is HTTP 201 with one LegacyMusic object. A fresh request waits up to 200 seconds for the generation acknowledgement and first persisted task-result row; it does not wait for terminal completion, so the returned status can still be submitted. A completed, customer-owned concat result may be reused. The cache is isolated by customer and accepts only completed concat-music results. As in suno-cloud, the legacy object’s taskId remains an empty string; use the additive omnapiTaskId and pollUrl fields for canonical task tracking.

Terminal window
curl -X POST https://api.omnapi.com/v1/concatenate \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-126-concat" \
-H "Content-Type: application/json" \
-d '{"mid":"clip_123"}'

There is no one-to-one dedicated concat operation in the modern Suno resource API. Use the generic task API when exact concat behavior is required:

Terminal window
curl -X POST https://api.omnapi.com/api/v1/tasks \
-H "x-api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-126-concat-modern" \
-H "Content-Type: application/json" \
-d '{
"model": "suno/chirp-fenix/concat-music",
"inputParameters": {"clipId":"clip_123"}
}'

The generic async route immediately returns a task receipt; poll its canonical task URL. Use /api/v1/tasks/sync only when your new client intentionally wants to wait for a terminal result. Do not replace concatenate with a new extend request: extending and concatenating an existing extended clip are different operations.

QueryTypeBehavior
idscomma-separated stringMatch compatibility resource-row IDs
midscomma-separated stringMatch clip IDs
takeinteger stringValid range 1–50; effective maximum 30; default 20
skipnon-negative integer stringValidated but intentionally ignored to match the live query behavior

When both ids and mids are present, they are combined as an intersection. Results are customer-isolated and sorted newest first. Duplicate clip IDs are collapsed to the newest resource row. Legacy type is reconstructed from the creating operation (concatenated, stemed, uploaded, or generated). With no ID filters, the route returns recent music resources from the OmnAPI data store; lookup-only rows are not promoted into creation history. While a task is running, provider feed snapshots refresh the row’s queued/streaming state and available media URLs; terminal sibling failures retain their own notes and detail instead of inheriting only a task-level error.

Terminal window
curl "https://api.omnapi.com/v1/songs?mids=clip_123,clip_456&take=20" \
-H "api-key: $OMNAPI_KEY"

Success is HTTP 200 with LegacyMusic[].

Modern migration depends on the old query:

  • mids: GET /api/v1/suno/clips?ids=clip_123,clip_456.
  • ids: there is no equivalent because compatibility row IDs are not clip IDs; migrate your stored references to mid or omnapiTaskId first.
  • Recent listing: use GET /api/v1/tasks?providerCode=suno, then read the task resources. The modern clip batch endpoint requires explicit clip IDs.

Suno can acknowledge a generation quickly and leave its clips non-terminal for much longer. Treat these resource statuses as follows:

Clip statusMeaningClient action
submittedAccepted by Suno; usually changes in about 3–5 secondsKeep polling; do not resubmit
queuedWaiting for Suno capacity; usually changes in about 5–10 secondsKeep polling; do not resubmit
streamingMedia is being produced; commonly lasts at least 15 secondsKeep polling; partial URLs are not a terminal guarantee
completeTerminal successPersist the clip and media URLs
errorTerminal Suno failureRead notes/detail and the OmnAPI task error

The compatibility Worker polls near the observed fast path—approximately 3 seconds for submitted, 5 seconds for queued, and 15 seconds for streaming—then backs off for old tasks through 30-second, 2-minute, 5-minute, and 15-minute tiers. The hard observation window is 48 hours from the Provider acknowledgement, not from the start of an API queue delay. Temporary empty feed responses or temporarily missing sibling clips are not treated as 404 or terminal failure before that deadline.

A compatibility POST may stop waiting before the Provider reaches a terminal state. This is only a synchronous HTTP wait timeout; it does not cancel or fail the durable task. Save omnapiTaskId and pollUrl, poll the canonical task, and use /v1/songs?mids=... when clip IDs are already known. Do not create a replacement request with a new idempotency key. For application polling, add jitter and follow the same increasing cadence instead of querying every second for hours.

There is one safety-first acknowledgement-loss case. If OmnAPI started the Suno submission but did not receive a definitive response, the task remains PROCESSING. An internal PROVIDER_SUBMISSION_OUTCOME_UNKNOWN diagnostic is retained for support, but the public Suno and compatibility responses do not present it as a terminal failure. OmnAPI deliberately does not submit the request again because Suno may already have created and charged for the clips. Keep polling the original task and contact support with its omnapiTaskId; support can reconcile a confirmed Suno clip ID. If no creation can be confirmed, the 48-hour observation deadline is followed by a 24-hour reconciliation grace before the final failure/refund safety net (about 72 hours from the submission boundary). Never switch to a new idempotency key for this task.

Pass either mid (the clip ID) or id (the compatibility resource-row ID). The resource must belong to the current OmnAPI customer. Requiring one value and resolving id safely corrects the live service’s ineffective id handling.

Terminal window
curl "https://api.omnapi.com/v1/songs/lyric-stamp?mid=clip_123" \
-H "api-key: $OMNAPI_KEY"

Success is HTTP 200 with the aligned timeline object, including fields such as aligned_words, waveform_data, hoot_cer, and is_streamed. The wait budget is 30 seconds. Empty success bodies are not used for failures.

Migrate to GET /api/v1/suno/clips/{clipId}/timeline.

Success is HTTP 200 with an OmnAPI credit-account view plus familiar aliases:

FieldMeaning
creditsLeft, leftCreditsExact available OmnAPI credit balance
currentUsageTotal used OmnAPI credits
totalPurchasedTotal purchased credits
totalRefundedTotal refunded credits
tierCurrent account tier
apiKeyIdCurrent OmnAPI API-key ID
apikeyEmpty compatibility field; the credential secret is never echoed
openidEmpty compatibility field; internal customer IDs are not exposed
packagesEmpty compatibility array; package rows are not recreated
expiredAtnull compatibility field
usage0 compatibility alias
requestMeta{ "type": "profile" } compatibility alias
updatedAtCredit-account update time

The compatibility API never echoes the API-key secret.

Terminal window
curl https://api.omnapi.com/v1/info \
-H "api-key: $OMNAPI_KEY"

There is no exact modern package-object replacement. Use the dashboard for the current balance, GET /api/v1/usage/export for automated usage reports, and each task descriptor’s creditsRequired, creditsCharged, and refunded fields for request-level reconciliation.

Body: { "mid": "clip_123" }. The source must have a current-customer OmnAPI creation record and its resource status must be complete; otherwise the route returns 404 or 406 before creating a paid task.

Success is HTTP 201 with LegacyMusic[]. The compatibility operation creates the basic two-stem result and retains the old type: "stemed" spelling. It waits up to 180 seconds for real music resources. As in suno-cloud, each legacy object’s taskId remains an empty string; use its additive omnapiTaskId and pollUrl fields for canonical task tracking.

Terminal window
curl -X POST https://api.omnapi.com/v1/stems \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-127-stems" \
-H "Content-Type: application/json" \
-d '{"mid":"clip_123"}'

Migrate to POST /api/v1/suno/clips/{clipId}/export with:

{
"format": "stems",
"stemsMode": "two"
}

Body: { "mid": "clip_123" }. The source must have a current-customer OmnAPI creation record and its resource status must be complete; otherwise the route returns 404 or 406 before creating a paid task.

Success is HTTP 201 with a non-null WAV URL:

{
"url": "https://example.com/song.wav"
}

The wait budget is 45 seconds. A completed task without a WAV URL is a structured 502 error; the route no longer returns { "url": null } as a successful export.

A 504 after this wait does not mean that WAV conversion was rejected. It means OmnAPI already created and charged the export task, but the URL was not materialized within 45 seconds. The conversion continues asynchronously. Read the returned taskId/pollUrl until terminal, or replay the exact legacy route, body, and Idempotency-Key to recover the original task. Do not submit another export with a new key, and do not fail over this in-flight write to the modern route.

Terminal window
curl -X POST https://api.omnapi.com/v1/generate-wav \
-H "api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-128-wav" \
-H "Content-Type: application/json" \
-d '{"mid":"clip_123"}'

Migrate to POST /api/v1/suno/clips/{clipId}/export with { "format": "wav" }. The modern route returns a Task receipt immediately; poll links.task instead of waiting for the URL in the create response:

Terminal window
curl -X POST https://api.omnapi.com/api/v1/suno/clips/clip_123/export \
-H "x-api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: order-128-wav-modern" \
-H "Content-Type: application/json" \
-d '{"format":"wav"}'
{
"taskId": "019d...",
"status": "PENDING",
"creditsRequired": 5,
"links": {
"task": "/api/v1/tasks/019d...",
"stream": "/api/v1/tasks/019d.../stream",
"resource": null,
"final": null
}
}

Suno Cloud package deductions are not reproduced. OmnAPI deducts the quoted credits atomically when a task is created and records settlement in the task and credit ledger. Eligible failed tasks and cancellations that were safely completed before submission or explicitly confirmed by the Provider are refunded. A post-submit 409 means the task remains active and was not refunded; keep polling it.

Current standard prices are:

OperationStandard OmnAPI credits
Song generation and generative derive25
Basic two-stem export28
Concatenate5
WAV export5
Lyrics generation and timeline read0

Customer pricing can change the final quote. Treat creditsRequired on the task receipt and creditsCharged/refunded on the terminal task as authoritative. See Credits & Billing.

Compatibility errors use the OmnAPI envelope:

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "title must be a string"
}
}
HTTPTypical meaningRetry guidance
400Valid JSON but an unsupported operation combinationCorrect the request
401Missing, invalid, disabled, or expired OmnAPI keyReplace or enable the key
402Insufficient OmnAPI credits; no task was createdAdd credits, then retry the unchanged request with the same idempotency key
403API-key scope or IP policy rejected the requestCorrect the key scope or IP policy
404Referenced target does not exist or lacks current-customer creation provenanceDo not blind-retry or probe other customer resources
406Stems/WAV source exists but is not completeWait for the source task to complete, then retry the unchanged request and key
409Key/body mismatch, concurrent request, or a task was already createdDifferent body: use a new key. No taskId: back off and retry the same key; if it remains unbound for 15 minutes, contact support rather than changing keys. With taskId: poll that task and do not resubmit
422Legacy DTO type, length, enum, or required-field failureCorrect the request
429Request limit reachedBack off using the response headers
502Task completed without the required compatibility resourceRead task details before deciding to retry
503Queue backpressure or no eligible provider capacity before executionBack off with the same host, route, body, and idempotency key; if the error includes a task ID, poll it instead of resubmitting
504Compatibility wait expired after a task was createdPoll the pollUrl. For a write request, retry only the original host and route with the same key; a same-key replay returns 409 with the original taskId. The timeline GET has no idempotency key and should use its returned task recovery details
5xxService failureBefore task creation, retry with backoff and the same key. If details contain taskId, poll it and never switch keys

For the six write routes, an idempotency claim is released when validation, ownership, or credit checks fail before a task exists. Task creation now binds COMMITTED + taskId in the same PostgreSQL transaction as the charge, Task, credit ledger, and durable dispatch row; the same binding rule applies to every created task, paid or zero-credit. A lost database response, or a later compatibility wait/mapping 500/502/504, therefore cannot leave a newly created task unbound or make a same-route retry create a second task.

For a composite legacy workflow such as Persona creation, each child-task transaction advances that same claim to the latest committed child. If a later database response is lost, a same-key retry therefore exposes the furthest task already created for the workflow, rather than only its first prerequisite.

An old claim with no visible taskId is still not automatically discarded. It can be a pre-atomic-binding migration row or a request that stopped before task creation; support must compare Task, credit ledger, request hash, and logs before repairing or releasing it. Clients should keep the original key and contact support after 15 minutes rather than switching keys. This preserves old customers’ financial history while new writes use the atomic path.

There is no shared idempotency namespace across the compatibility API, the modern API, and the old host. After an uncertain write, poll the returned task details or replay the exact original host, path, key, and body. Never fail over an individual in-flight write between surfaces; move only cohorts whose prior writes are known to be settled or absent.

These differences are part of the public contract and will not be changed to copy unsafe or incompatible legacy behavior.

AreaSuno Cloud behaviorOmnAPI compatibility behavior
CredentialExisting Suno Cloud key valueNew OmnAPI key value; either header name is accepted
Authentication errorsCommonly 403401 for key authentication; 403 only for key scope or IP policy
Insufficient balanceCommonly 403402
BillingPackage-based deduction after generationAtomic create-time deduction with terminal settlement and eligible refund
Long-tail statusFrequent legacy feed sync could still leave tasks stale or expire with process-local stateDurable PostgreSQL task state, adaptive polling, 48-hour Provider-acknowledged observation window, and restart/multi-node recovery
Submission acknowledgement lossA process retry could repeat a non-idempotent Suno writeAutomatic replay stops at the durable submission boundary; reconcile the original task or wait through the 48-hour observation window plus 24-hour reconciliation grace instead of creating a replacement
Source ownershipSome follow-up operations could use another customer’s clipFollow-up operations and cached results are customer-isolated and require creation provenance
HistoryMySQL song rows and physical IDsOnly OmnAPI task/resource history is queryable
Old resourcesA known old clip or Persona ID could be routed by legacy runtime stateExtend, upload-extend, cover, Persona generation, concatenate, stems, WAV, and timeline reads require a matching current-customer OmnAPI creation record
Query provenanceA clip returned by a lookup could later be reused as a sourceOnly create/upload and other operations that generate a new owned resource — including generative derive, concatenate, edits/remaster, Persona creation, and stems — establish provenance. Query, timeline, WAV, and other read-only/conversion results do not
Model validationMalformed mv values could be rewritten to fenixSupported legacy values normalize as documented; malformed values return 422
Model fallbackA fenix/pro request could be retried as turbo when pro execution was unavailableThe selected effective model is preserved; fenix/pro is not automatically downgraded to turbo
Continue positionA negative continue_at could pass the old DTOValues must be finite and >= 0; normalize legacy data before migration
Legacy identity fieldsOwner and execution-provider identifiers could be populatedidentity, uid, openid, and comparable compatibility identifiers are empty or redacted
Lyrics timeoutCould return running without a public recovery routeReturns an error with canonical task recovery details
Timeline failureCould return HTTP 200 with an empty bodyReturns a structured error
WAV failureCould be surfaced as an empty or unavailable URLA successful response always contains a URL
/v1/infoPackage rows and internal legacy dataOmnAPI credit-account view; package rows and key secrets are not recreated
Error bodyNest-era error shapeOmnAPI { success, error } envelope
  1. Inventory calls to the exact nine covered paths. Route every other path to a product redesign instead of assuming compatibility.
  2. Record which stored values are resource id, clip mid, legacy taskId, or business IDs.
  3. Split historical clips from clips that will be created after the cutover. Historical Suno Cloud rows are not copied automatically.
  4. Identify workflows that use an old clip for extend, upload-extend, cover, concatenate, stems, WAV, or lyric timeline, plus workflows that reuse an old Persona. Keep them on the old service until the corresponding creation provenance is migrated to the correct OmnAPI customer, or arrange a managed migration with support.
  5. A successful lookup through the compatibility or modern query endpoints is not a provenance backfill. Importing history must create customer-scoped task/resource records with the correct original operation; never grant ownership merely because a client supplied a clip ID.
  1. Create an OmnAPI account, fund credits, and issue a scoped OmnAPI API key.
  2. Change the base host to https://api.omnapi.com and replace the key value. Keep the old api-key header and /v1 paths if that reduces client changes.
  3. Add a unique Idempotency-Key to every write request.
  4. Persist mid, omnapiTaskId, and pollUrl from new responses. Stop using taskId as a canonical poll key.
  5. Send canary traffic for each write operation. Compare HTTP status, array vs object shape, clip count, non-null media URLs, and terminal task settlement.
  6. During the history transition, route a request according to where its source clip was created: old clips to the old service, OmnAPI clips to OmnAPI.
  1. Move simple/custom music to /api/v1/suno/songs.
  2. Move extend/cover to /api/v1/suno/clips/{clipId}/derive.
  3. Move timeline and exports to clip resource endpoints.
  4. Replace mids lookup with /api/v1/suno/clips?ids=...; replace recent compatibility history with task listing.
  5. Use generic concat-music only where existing-clip concat is still needed.
  6. Replace /v1/info reporting with dashboard balance, usage export, and task settlement fields.
  7. Remove dependencies on compatibility-only fields, then switch the header to x-api-key and remove /v1 code paths.

Before raising traffic, verify all of the following:

  • Both generated clip mid values can be looked up and downloaded.
  • omnapiTaskId reaches a terminal state and matches the compatibility result.
  • Required credits and final charged/refunded credits reconcile.
  • Retries with the same idempotency key do not create duplicate tasks, including zero-credit lyrics tasks.
  • ids and mids are not mixed in application storage.
  • Historical clip derivatives follow the intended old/new routing rule.
  • Error handling covers 401, 402, 403, 404, 406, 409, 422, 429, 502, 503, and 504.

Keep rollback configuration-based: retain the old host and key separately, and route only historical or failing cohorts back. Never send an OmnAPI key to the old host or a Suno Cloud key to OmnAPI.