# 段落替换
> 替换歌曲中的某一段，而不是删掉，异步任务
> 用新歌词填补指定区间，前后保持连贯
> 比「删除片段」更适合修补
`POST /v1/music/generations/replaceMusic`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 引用源音轨
- `task_id` (string / 必填) — 源音轨所属任务的 ID。缺失或解析不到源时，提交阶段返回 400。
- `audio_index` (integer / 可选) — 从源任务结果的 `data.result.music[]` 中选取第几首，默认 `1`，从 1 开始计数。一次生成通常为 1、2 两首。
## 替换区间
- `start_s` (number / 必填) — 替换起点，单位秒。缺失时返回 400。
- `end_s` (number / 必填) — 替换终点，单位秒。需满足 `0 ≤ start_s < end_s`，且不能超出已知的源时长。
- `infill_lyrics` (string / 可选) — 用于替换片段的新歌词。这是本接口的核心字段，写清楚这一段要唱什么。
## 生成参数
- `model` (string / 可选) — 音频模型，默认 `suno`。
- `version` (string / 可选) — 公共版本，默认 `v6`，可选 `v6-wild`、`v6-mini`。若使用 `custom_model_id`，则省略本字段。
- `custom_model_id` (string / 可选) — 创建自定义模型任务时返回的完整 UUID，不能与 `version` 同时使用。
- `prompt` (string / 可选) — 原歌词上下文。把这一段前后各一句贴进来，模型能更好地衔接。
- `title` (string / 可选) — 标题。
- `tags` (string / 可选) — 风格标签。
- `negative_tags` (string / 可选) — 需要排除的风格标签。
- `variety` (string / 可选) — 风格变化程度，可选 `off`、`normal`、`high`、`extra`、`max`。
- `max_mode` (boolean / 可选) — 启用 Max 模式，默认 `false`。按普通售价的 2 倍计费。
- `audio_format` (string / 可选) — 输出格式，可选 `mp3`、`m4a`、`wav`。本接口没有目标时长字段。
## 响应
- `code` (integer) — 响应状态码。
- `data[].status` (string) — 任务状态，提交成功时返回 `submitted`。
- `data[].task_id` (string) — 任务唯一标识，用于轮询 `GET /v1/music/tasks/{task_id}`。
## 取结果
轮询时 `status` 可能为 `pending`、`processing`、`completed` 或 `failed`。`progress` 是 0 到 100 的整数，不保证按固定节点变化。
完成后从 `data.result.music[].audio_url` 取替换后的音频。失败时 `data.error.message` 给出原因，预扣额度自动退回。生成通常需要 30 到 120 秒。
## 与删除片段的对照
| 项目 | 删除片段 | 段落替换 |
|---|---|---|
| 路径 | `removeSection` | `replaceMusic` |
| 效果 | 区间被去掉，前后直接接 | 区间被新内容填上 |
| 接缝 | 可能突兀 | 相对自然 |
| 关键字段 | `start_s`、`end_s` | 再加 `infill_lyrics` |
修一段唱错的词、换掉一段不满意的副歌，用替换。整段多余的内容，用删除。
> **Note:** 
> `prompt` 传的是**原歌词上下文**，不是新歌词。新歌词放 `infill_lyrics`。两个字段搞反是很常见的错误，表现为替换后唱的完全是另一段内容。
## 错误码
错误响应的格式、状态码与重试建议见[错误码与限流](../../../support/errors.html)，常见报错的排查步骤见[常见问题](../../../support/faq.html)。
## 使用示例
提交一个任务并拿到 `task_id`：
> **Note:** 
> 提交成功只表示任务已受理。真正的产物要拿返回的 `task_id` 去任务查询接口轮询，`status` 变成 `completed` 之后才有结果。
**段落替换{Replace section}::cURL**
```
curl -X POST https://api.oairoute.com/v1/music/generations/replaceMusic \
  -H 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  -H 'Content-Type: application/json' \
  --data '{
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "audio_index": 1,
    "start_s": 45,
    "end_s": 62.5,
    "infill_lyrics": "[Chorus]\n这一次我不再回头",
    "prompt": "上一句是这样的\n下一句接在这里",
    "tags": "pop, emotional"
  }'
```
**段落替换{Replace section}::Python**
```
import requests
res = requests.post(
    "https://api.oairoute.com/v1/music/generations/replaceMusic",
    headers={
        "Authorization": "Bearer YOUR_OAIRoute_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "suno",
        "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
        "audio_index": 1,
        "start_s": 45,
        "end_s": 62.5,
        "infill_lyrics": "[Chorus]\n这一次我不再回头",
        "prompt": "上一句是这样的\n下一句接在这里",
        "tags": "pop, emotional",
    },
)
print(res.json()["data"][0]["task_id"])
```
**段落替换{Replace section}::JavaScript**
```
const url = "https://api.oairoute.com/v1/music/generations/replaceMusic";
const options = {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "audio_index": 1,
    "start_s": 45,
    "end_s": 62.5,
    "infill_lyrics": "[Chorus]\n这一次我不再回头",
    "prompt": "上一句是这样的\n下一句接在这里",
    "tags": "pop, emotional"
  }),
};
fetch(url, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
```
**200 段落替换{Replace section}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8E22M0HP1GJWBJYZMKX1XS1" }
  ]
}
```
**只换歌词不换情绪{Lyrics only}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations/replaceMusic' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "suno",
  "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
  "start_s": 12,
  "end_s": 18,
  "infill_lyrics": "[Verse]\n改成这一句",
  "variety": "off"
}'
```
**只换歌词不换情绪{Lyrics only}::Python**
```
import requests
url = "https://api.oairoute.com/v1/music/generations/replaceMusic"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
      "model": "suno",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
      "start_s": 12,
      "end_s": 18,
      "infill_lyrics": "[Verse]\n改成这一句",
      "variety": "off"
    }
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**只换歌词不换情绪{Lyrics only}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/music/generations/replaceMusic", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "start_s": 12,
    "end_s": 18,
    "infill_lyrics": "[Verse]\n改成这一句",
    "variety": "off"
  }),
});
console.log(await res.json());
```
**200 只换歌词不换情绪{Lyrics only}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8E22M0HP1GJWBJYZMKX1XS1" }
  ]
}
```
