Replace a section
curl --request POST \
--url https://apistable.ai/api/v1/tasks/create_task \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "suno_replace_section",
"input": {
"audio_id": "YOUR_AUDIO_ID",
"prompt": "[Verse] A new beginning",
"tags": "Pop",
"title": "New verse",
"infill_start_s": 20,
"infill_end_s": 40,
"full_lyrics": "Original full lyrics"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'suno_replace_section',
input: {
audio_id: 'YOUR_AUDIO_ID',
prompt: '[Verse] A new beginning',
tags: 'Pop',
title: 'New verse',
infill_start_s: 20,
infill_end_s: 40,
full_lyrics: 'Original full lyrics'
}
})
};
fetch('https://apistable.ai/api/v1/tasks/create_task', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.ai/api/v1/tasks/create_task"
payload = {
"model": "suno_replace_section",
"input": {
"audio_id": "YOUR_AUDIO_ID",
"prompt": "[Verse] A new beginning",
"tags": "Pop",
"title": "New verse",
"infill_start_s": 20,
"infill_end_s": 40,
"full_lyrics": "Original full lyrics"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"code": 200,
"msg": "success",
"data": {
"task_id": "<string>"
}
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}Suno
Replace a section
Select a time range within a song and rewrite that section with new lyrics or style.
POST
/
api
/
v1
/
tasks
/
create_task
Replace a section
curl --request POST \
--url https://apistable.ai/api/v1/tasks/create_task \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "suno_replace_section",
"input": {
"audio_id": "YOUR_AUDIO_ID",
"prompt": "[Verse] A new beginning",
"tags": "Pop",
"title": "New verse",
"infill_start_s": 20,
"infill_end_s": 40,
"full_lyrics": "Original full lyrics"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'suno_replace_section',
input: {
audio_id: 'YOUR_AUDIO_ID',
prompt: '[Verse] A new beginning',
tags: 'Pop',
title: 'New verse',
infill_start_s: 20,
infill_end_s: 40,
full_lyrics: 'Original full lyrics'
}
})
};
fetch('https://apistable.ai/api/v1/tasks/create_task', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.ai/api/v1/tasks/create_task"
payload = {
"model": "suno_replace_section",
"input": {
"audio_id": "YOUR_AUDIO_ID",
"prompt": "[Verse] A new beginning",
"tags": "Pop",
"title": "New verse",
"infill_start_s": 20,
"infill_end_s": 40,
"full_lyrics": "Original full lyrics"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"code": 200,
"msg": "success",
"data": {
"task_id": "<string>"
}
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}{
"code": 123,
"msg": "<string>",
"data": null
}Operations are enabled individually by server configuration. Disabled operations return 503 without a task. Music credit deduction is currently disabled.
Using this operation
Select a time range within a song and rewrite that section with new lyrics or style.-
- Prepare the fields shown in the example below. Replace sample URLs and IDs with resources you can access.
-
- Set model to suno_replace_section and place the parameters inside input. Submit once and save the returned task_id.
-
- Query the saved task or receive its callback. A processing result is not a reason to submit the operation again.
- Read songs from result.data.data. Each song has its own APIstable id, which can be used as audio_id in a later task.
Create task
Send model and input to the common task endpoint. callback_url is an optional top-level public HTTPS address. All resource IDs are APIstable IDs owned by your account. Music credit deduction is currently disabled.{
"model": "suno_replace_section",
"input": {
"audio_id": "YOUR_AUDIO_ID",
"prompt": "[Verse] A new beginning",
"tags": "Pop",
"title": "New verse",
"infill_start_s": 20,
"infill_end_s": 40,
"full_lyrics": "Original full lyrics"
}
}
Acceptance response
HTTP 200 confirms acceptance, not completion. Query GET /api/v1/tasks/{task_id} until data.status is succeeded or failed. Read data.result only after success; a failed task has its error in data.message.{
"code": 200,
"msg": "success",
"data": {
"task_id": "YOUR_TASK_ID"
}
}
Parameter reference
| Field | Type | Required | Description and limits |
|---|---|---|---|
| vocal_gender | string | No / conditional | m or f. A vocal tendency, not a guaranteed voice identity. When generating music, requires custom mode. values: m, f |
| style_weight | number | No / conditional | Style influence, 0–1 with at most two decimal places. When generating music, requires custom mode. min: 0; max: 1 |
| weirdness_constraint | number | No / conditional | Creativity constraint, 0–1 with at most two decimal places. When generating music, requires custom mode. min: 0; max: 1 |
| audio_weight | number | No / conditional | Audio influence, 0–1 with at most two decimal places. Generation requires custom, non-instrumental mode. min: 0; max: 1 |
| variety | integer | No / conditional | Variety: integer 0–4, default 1 in custom generation. min: 0; max: 4 |
| persona_id | string | No / conditional | APIstable Voice or Persona ID; provider root and artist mapping remain server-side. maxLength: 200 |
| persona_model | string | No / conditional | style_persona or voice_persona; must match the resource’s actual origin. values: style_persona, voice_persona |
| audio_id | string | Yes | APIstable song ID belonging to your account. Cover/extend accept this ID only, without a source task_id or external URL. maxLength: 200 |
| prompt | string | Yes | Required replacement prompt, up to 5000 characters. lyrics does not replace this field. maxLength: 5000 |
| tags | string | Yes | Musical style for this operation, up to 1000 characters. maxLength: 1000 |
| title | string | Yes | Title. Generate/cover: up to 80 characters; extend and other operations: up to 100. Required for custom generation. maxLength: 100 |
| infill_start_s | number | Yes | Replacement start in seconds, at most two decimal places. min: 0 |
| infill_end_s | number | Yes | Replacement end in seconds, at most two decimal places, within the source. Replace 10–120 seconds and no more than half the source duration. min: 0 |
| full_lyrics | string | Yes | Full song lyrics with the replacement in its intended position. maxLength: 5000 |
| lyrics | string | No / conditional | Optional lyrics for the replacement segment, up to 5000 characters; defaults to prompt. Does not replace full_lyrics or the main prompt. maxLength: 5000 |
| negative_tags | string | No / conditional | Styles to exclude; required for adding instrumental backing or vocals. maxLength: 1000 |
| result_mode | string | No / conditional | Extension/replacement: full_song (default) or segment. Added stem: mixed (default) or stem. Full/mixed results wait for assembly. values: full_song, segment; default: full_song |
Inputs and limits
The schema lists supported fields, types and basic limits. Also follow Important conditions: cross-field and source-resource checks are not fully represented in JSON Schema. Unknown parameters are rejected. URL fields accept public HTTPS URLs, never file objects.{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"vocal_gender": {
"type": "string",
"enum": [
"m",
"f"
],
"description": "m or f. A vocal tendency, not a guaranteed voice identity. When generating music, requires custom mode."
},
"style_weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Style influence, 0–1 with at most two decimal places. When generating music, requires custom mode."
},
"weirdness_constraint": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Creativity constraint, 0–1 with at most two decimal places. When generating music, requires custom mode."
},
"audio_weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Audio influence, 0–1 with at most two decimal places. Generation requires custom, non-instrumental mode."
},
"variety": {
"type": "integer",
"minimum": 0,
"maximum": 4,
"description": "Variety: integer 0–4, default 1 in custom generation."
},
"persona_id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "APIstable Voice or Persona ID; provider root and artist mapping remain server-side."
},
"persona_model": {
"type": "string",
"enum": [
"style_persona",
"voice_persona"
],
"description": "style_persona or voice_persona; must match the resource's actual origin."
},
"audio_id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "APIstable song ID belonging to your account. Cover/extend accept this ID only, without a source task_id or external URL."
},
"prompt": {
"type": "string",
"maxLength": 5000,
"description": "Required replacement prompt, up to 5000 characters. lyrics does not replace this field."
},
"tags": {
"type": "string",
"maxLength": 1000,
"description": "Musical style for this operation, up to 1000 characters."
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "Title. Generate/cover: up to 80 characters; extend and other operations: up to 100. Required for custom generation."
},
"infill_start_s": {
"type": "number",
"minimum": 0,
"description": "Replacement start in seconds, at most two decimal places."
},
"infill_end_s": {
"type": "number",
"minimum": 0,
"description": "Replacement end in seconds, at most two decimal places, within the source. Replace 10–120 seconds and no more than half the source duration."
},
"full_lyrics": {
"type": "string",
"maxLength": 5000,
"description": "Full song lyrics with the replacement in its intended position."
},
"lyrics": {
"type": "string",
"maxLength": 5000,
"description": "Optional lyrics for the replacement segment, up to 5000 characters; defaults to prompt. Does not replace full_lyrics or the main prompt."
},
"negative_tags": {
"type": "string",
"maxLength": 1000,
"description": "Styles to exclude; required for adding instrumental backing or vocals."
},
"result_mode": {
"default": "full_song",
"type": "string",
"enum": [
"full_song",
"segment"
],
"description": "Extension/replacement: full_song (default) or segment. Added stem: mixed (default) or stem. Full/mixed results wait for assembly."
}
},
"required": [
"audio_id",
"prompt",
"tags",
"title",
"infill_start_s",
"infill_end_s",
"full_lyrics"
],
"additionalProperties": false
}
Important conditions
- The range must lie inside the source song, be at least 10 seconds, at most 120 seconds and no longer than half the source duration. Start/end accept at most two decimal places. prompt remains required; lyrics only overrides the replacement-segment lyrics. full_lyrics is the complete intended song text.
- Persona-based replacement is not enabled. Requests containing persona_id return HTTP 422/code 42201.
- full_song/mixed results wait for assembly; segment/stem returns the requested part. An assembly failure is not reported as a complete song. Partial song success is identified by the result message.
- Song audio may be MP3 or M4A. Use suno_export_mp3 for an actual MP3 file. Unavailable optional cover art may be null; audio remains usable.
- Uploaded files last 24 hours, generated files 14 days and task details 30 days. Reused files keep their original expiry. Valid Voice/Persona identity mappings are separate from task-log cleanup. Download files you need to retain.
Result schema
The creation response is {code:200,msg:“success”,data:{task_id}}. Poll GET /api/v1/tasks/{task_id}. On success, data.result is an object matching the schema below; it is otherwise null. input remains a JSON string.{
"type": "object",
"required": [
"code",
"msg",
"data"
],
"properties": {
"code": {
"const": 200
},
"msg": {
"type": "string"
},
"data": {
"type": "object",
"required": [
"callbackType",
"task_id",
"data"
],
"properties": {
"callbackType": {
"const": "complete"
},
"task_id": {
"type": "string"
},
"data": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"audio_url",
"stream_audio_url",
"image_url",
"prompt",
"lyrics",
"model_name",
"title",
"createTime",
"duration",
"tags",
"source_audio_url",
"source_image_url",
"source_stream_audio_url"
],
"properties": {
"id": {
"type": "string"
},
"audio_url": {
"type": "string"
},
"stream_audio_url": {
"type": [
"string",
"null"
]
},
"image_url": {
"type": [
"string",
"null"
]
},
"prompt": {
"type": "string"
},
"lyrics": {
"type": [
"string",
"null"
]
},
"model_name": {
"type": [
"string",
"null"
]
},
"title": {
"type": [
"string",
"null"
]
},
"createTime": {
"type": [
"integer",
"null"
]
},
"duration": {
"type": [
"number",
"null"
]
},
"tags": {
"type": [
"string",
"null"
]
},
"source_audio_url": {
"type": "string"
},
"source_image_url": {
"type": [
"string",
"null"
]
},
"source_stream_audio_url": {
"type": [
"string",
"null"
]
}
}
}
}
}
}
}
}
Song duration is in seconds; task duration is in milliseconds. createTime is a Unix timestamp in milliseconds or null. Current stream_audio_url and source_stream_audio_url are null. source_audio_url/source_image_url refer to the same APIstable-hosted copies as audio_url/image_url, not provider links. Process the actual song array; upload registration does not imply two newly generated songs.
Related workflows
Voice: all four steps File uploads CallbacksAuthorizations
Every valid key can submit and query its own account. Revoked keys are rejected.
Body
application/json