Skip to main content
The Suno Studio Project API manages multi-track music projects through a single endpoint:
The action in the request determines the operation type. The Project primary key consistently uses id; version_id represents the current project version, and all modification and export operations must submit the latest version to avoid concurrent overwrites.

Operation Overview

Async operations immediately return a task_id. Use the free /suno/tasks endpoint for polling, or pass callback_url to receive final-state results.

Create and Retrieve

All modification operations should send a unique Idempotency-Key Header. After successful creation, data.id in the response is the Project ID. A newly created empty project may not have a version_id before its first save.
The retrieval response contains the complete state. A newly created empty project returns {"tracks":[],"timing":{"bps":2}}, which can be used directly for the first save. timing.bps represents beats per second, with a default of 2 (120 BPM), and must be positive; a clip’s startBeats, endBeats, and readStartBeats use project beat units, and measure positions in audio analysis cannot be directly treated as timeline coordinates.

Save Complete State

The first save of a newly created empty project may omit version_id; after the first save generates a version, subsequent saves must submit the latest value. If the version has changed, the API returns HTTP 409. In this case, retrieve again, merge the changes, and submit using a new idempotency key; do not blindly retry the old request.

Upload and Add Tracks

After a successful upload, read the audio ID from response.data.candidate.audio_id. Then add it to the project:
Adding a track preserves the audio playback speed by default and converts the audio duration into beats according to the project’s timing.bps. After every save, add_track, commit_candidate, or remove_track, use the new version_id in the response.

Generate and Replace

generate_track generates track candidates for a project range; replace_section returns two local replacement candidates. Neither operation automatically selects the artistic result. Models must use public names: chirp-v3-5, chirp-v4, chirp-v4-5, chirp-v4-5-plus, chirp-v5, chirp-v5-5, chirp-v6, chirp-v6-wild, or chirp-v6-mini; availability for specific operations is still subject to the task final state, unsupported names return 400 before submission. It will not automatically switch to another model.
generate_track must also provide render_audio_id (completed project export audio), stem_control_tags, and source audio source_audio_id. batch_size is 1–4, with a default of 2; start_seconds and end_seconds are source audio seconds. A replacement range with fixed=true must be shorter than 26 seconds. Commit after selecting a candidate:
Candidates are bound to the project version at the time of generation. Once the project has changed, old candidates cannot be committed directly. Local replacement candidates are committed to the original track containing the unique source clip, and complete take candidates retain the original position while replacing the original clip; range candidates replace only the requested range while preserving the clips before and after it. If duration cannot be matched reliably, 400 is returned and the original project is retained; in this case, do not pass start_beats or end_beats. New-track candidates should be committed to an empty track saved in advance, defaulting to the source clip start point, or explicitly provide a non-overlapping range; overlapping existing clips on the same track return 400. Do not generate first and then create a new track, otherwise the version change will cause the candidate to expire.

Export Complete Song

The server reads the authoritative project state of the specified version and assembles export parameters. When start_beats and end_beats are omitted, it exports by default from the earliest start point to the latest end point of all audible clips; muted tracks/clips do not participate, and only solo tracks are selected when solo tracks exist. An empty project or no valid audible tracks returns 400. The final-state result contains render_id, audio_id, audio_url, and duration. Projects are bound to the execution environment at creation and cannot be migrated across environments or automatically failed over.
Only upload or process audio that you have legal rights to use. The Project API is currently in Beta; please persist the final audio URLs from important results.

Polling and Failure Recovery

Send the above request to /suno/tasks. A Projects task is considered successful when finished_at exists and response.success=true; response.success=false indicates failure. A submission returning HTTP 200 or a task_id only means it has been accepted, not that the audio is complete. The same Idempotency-Key with the same request will return the original result (including failures), and will not automatically regenerate or charge repeatedly. To explicitly retry a failed operation, first query the original task to confirm the failure, then use a new key; do not resubmit while the original task is still processing or the result is uncertain. Error categories include studio_unavailable / studio_model_unavailable (503, temporarily unable to process or model unavailable), studio_model_unsupported (400, the model does not support this operation), studio_state_invalid (400, the project state or export range is invalid), too_many_requests (429), studio_audio_unavailable (403, the referenced audio cannot be used for project export), and content_rejected (403). Preserve trace_id for troubleshooting.