# 续写延长
> 在已有歌曲的指定时间点之后续写，异步任务
> 用 `continue_at` 精确控制接续位置
> 与「生成音乐」共享大部分参数
`POST /v1/music/generations/extend`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 引用源音轨
- `task_id` (string / 必填) — 产出源音轨那次任务的 task_id。缺失或无法定位源音轨时，**提交阶段即返回 400**。
- `audio_index` (integer / 可选) — 指定源任务结果 `data.result.music[]` 中的第几首，默认 `1`。一次生成一般产出两首。
- `continue_at` (number / 必填) — 从源音轨的第几秒开始接续。取值不小于 1，且**小于源音轨实际时长**，可用小数。
> **Note:** 
> 引用源音轨只需 `task_id` 与 `audio_index`，不需要额外记录任何 id。上界取决于源音频多长，所以先查一次源任务的 `duration` 再决定 `continue_at`。
## 请求参数
- `model` (string / 可选) — 音频模型，默认 `suno`，当前只有这一个取值。
- `version` (string / 可选) — 公共模型版本，取值 `v6`（默认）、`v6-wild`、`v6-mini`。使用 `custom_model_id` 时不要传本字段。
- `custom_model_id` (string / 可选) — 创建模型任务返回的完整 UUID。与 `version`、`persona_id` 三者互斥，只能取其一。
- `custom` (boolean / 可选) — **默认 `true`**。为 `true` 时按 `prompt` 歌词续写；只有显式传 `false` 才改用 `gpt_description` 引导方向。
- `prompt` (string / 可选) — 续写用的歌词，`custom` 为 `true` 时生效。
- `gpt_description` (string / 可选) — 灵感描述，**仅在显式传入 `custom: false` 时生效**。
- `title` (string / 可选) — 标题，仅 `custom` 为 `true` 时生效。
- `tags` (string / 可选) — 风格标签，仅 `custom` 为 `true` 时生效。注意本端点叫 `tags`，「生成音乐」那边叫 `style`。
- `negative_tags` (string / 可选) — 需要排除的风格标签，仅 `custom` 为 `true` 时生效。
- `vocal_gender` (string / 可选) — 人声性别，取值 `Male` 或 `Female`。两种模式都生效。
- `style_weight` (number / 可选) — 风格权重，取值 0.00 到 1.00。**超出范围在提交阶段返回 400**。仅 `custom` 为 `true` 时生效。
- `weirdness` (number / 可选) — 创意度权重，取值 0.00 到 1.00。兼容旧字段名 `weirdness_constraint`，新请求建议用 `weirdness`。
- `audio_weight` (number / 可选) — 音频权重，取值 0.00 到 1.00。仅 `custom` 为 `true` 时生效。
- `auto_lyrics` (boolean / 可选) — 为 `true` 时对输入歌词做二次创作。仅 `custom` 为 `true` 时生效。
- `persona_id` (string / 可选) — Persona 风格 ID。仅 `custom` 为 `true` 时生效，且与 `custom_model_id` 互斥。
- `duration_s` (integer / 可选) — 目标生成时长，取值 10 到 360 秒。仅 `custom` 为 `true` 时可用，实际时长以结果为准。
- `variety` (string / 可选) — 风格变化程度，取值 `off`、`normal`、`high`、`extra`、`max`。可省略。
- `max_mode` (boolean / 可选) — 启用 Max 模式，默认 `false`。**要求 `custom: true`**，按普通售价的 2 倍计费。
- `audio_format` (string / 可选) — 输出音频格式，取值 `mp3`、`m4a`、`wav`。
## 响应
- `code` (integer) — 响应状态码，成功为 200。
- `data[].status` (string) — 提交成功为 `submitted`。
- `data[].task_id` (string) — 任务唯一标识，用于轮询。
轮询时 `status` 取值 `pending`、`processing`、`completed`、`failed`，`progress` 是 0 到 100 的整数但不保证按固定节点推进。完成后从 `data.result.music[]` 取 `audio_url`。失败时 `data.error.message` 给出原因，并自动退回预扣额度。
## 与生成音乐的区别
| 项目 | 生成音乐 | 续写延长 |
|---|---|---|
| 风格字段 | `style` | `tags` |
| 时长字段 | `duration` | `duration_s` |
| 创意度字段 | `weirdness_constraint` | `weirdness`（兼容旧名） |
| `custom` 默认值 | `false` | **`true`** |
| 必需引用 | 无 | `task_id` 加 `continue_at` |
字段名不一致是这套接口最容易出错的地方。照抄生成音乐的请求体过来，`style` 和 `duration` 都不会生效。
## 错误码
错误响应的格式、状态码与重试建议见[错误码与限流](../../../support/errors.html)，常见报错的排查步骤见[常见问题](../../../support/faq.html)。
## 使用示例
提交一个任务并拿到 `task_id`：
> **Note:** 
> 提交成功只表示任务已受理。真正的产物要拿返回的 `task_id` 去任务查询接口轮询，`status` 变成 `completed` 之后才有结果。
**续写延长{Extend track}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations/extend' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "audio_index": 1,
    "continue_at": 62.5,
    "custom": true,
    "prompt": "[Verse]\n风还在吹",
    "tags": "folk, warm",
    "duration_s": 90
  }'
```
**续写延长{Extend track}::Python**
```
import requests
res = requests.post(
    "https://api.oairoute.com/v1/music/generations/extend",
    headers={
        "Authorization": "Bearer YOUR_OAIRoute_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "suno",
        "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
        "audio_index": 1,
        "continue_at": 62.5,
        "custom": True,
        "prompt": "[Verse]\n风还在吹",
        "tags": "folk, warm",
        "duration_s": 90,
    },
)
print(res.json()["data"][0]["task_id"])
```
**续写延长{Extend track}::JavaScript**
```
const url = "https://api.oairoute.com/v1/music/generations/extend";
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,
    "continue_at": 62.5,
    "custom": true,
    "prompt": "[Verse]\n风还在吹",
    "tags": "folk, warm",
    "duration_s": 90
  }),
};
fetch(url, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
```
**200 续写延长{Extend track}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8C11M0HP1GJWBJYZMKX1XS1" }
  ]
}
```
**灵感模式续写{Inspiration-mode extension}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations/extend' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "suno",
  "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
  "continue_at": 40,
  "custom": false,
  "gpt_description": "接一段更激烈的器乐间奏"
}'
```
**灵感模式续写{Inspiration-mode extension}::Python**
```
import requests
url = "https://api.oairoute.com/v1/music/generations/extend"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
      "model": "suno",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
      "continue_at": 40,
      "custom": false,
      "gpt_description": "接一段更激烈的器乐间奏"
    }
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**灵感模式续写{Inspiration-mode extension}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/music/generations/extend", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "continue_at": 40,
    "custom": false,
    "gpt_description": "接一段更激烈的器乐间奏"
  }),
});
console.log(await res.json());
```
**200 灵感模式续写{Inspiration-mode extension}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8C11M0HP1GJWBJYZMKX1XS1" }
  ]
}
```
