# 生成音乐
> Suno 的主生成接口，异步任务
> 两种模式：灵感模式（给描述）与自定义模式（给歌词）
> 通常 30 到 120 秒出结果
`POST /v1/music/generations`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 两种模式
| 模式 | `custom` | `prompt` 的含义 | 生效的字段 |
|---|---|---|---|
| 灵感模式 | `false`（默认） | 创意描述，不超过 3000 字符 | 只有 `prompt` 与版本 |
| 自定义模式 | `true` | 歌词正文，不超过 5000 字符 | `title`、`style`、`negative_tags`、`auto_lyrics`、`persona_id` 等 |
灵感模式下，`title`、`style`、`negative_tags`、`auto_lyrics`、`persona_id` 全部被忽略。
- `style_weight` (number) — 两种模式都生效。
- `weirdness_constraint` (number) — 两种模式都生效。
- `audio_weight` (number) — 两种模式都生效。
- `vocal_gender` (string) — 两种模式都生效。
## 请求参数
- `model` (string / 可选) — 音频模型，目前只传 `suno`，不传也按 `suno` 处理。
- `custom` (boolean / 可选) — 默认 `false`。`false` 时按灵感模式理解 `prompt` 为创意描述；`true` 时按自定义模式把 `prompt` 当歌词。
- `instrumental` (boolean / 可选) — 默认 `false`。为 `true` 时输出纯音乐，不含人声。
- `version` (string / 可选) — 公共版本号，取值 `v6`、`v6-wild`、`v6-mini`。 **与 `custom_model_id` 至少提供一个**，若改用自定义模型则不要填本字段。
- `custom_model_id` (string / 可选) — 填创建自定义模型任务时返回的完整 UUID。与 `version`、`persona_id` 三者互斥，填了按自定义模型价格档计费。
- `prompt` (string / 视情况) — 灵感模式下是描述性提示词，**必填**且上限 3000 字符。 自定义模式且非纯音乐时必填，上限 5000 字符。自定义纯音乐可以不填。
- `title` (string / 可选) — 歌曲标题，上限 80 字符。**只在自定义模式有用**，灵感模式下会被丢弃。
- `style` (string / 可选) — 风格标签，上限 1000 字符。只在自定义模式有用。 注意本端点叫 `style`，其他操作端点叫 `tags`。
- `negative_tags` (string / 可选) — 列出不想出现的风格。自定义模式才校验。
- `auto_lyrics` (boolean / 可选) — 为 `true` 会对你给的歌词再做一次加工改写。自定义模式才生效。
- `persona_id` (string / 可选) — 绑定某个 Persona 风格。自定义模式才生效，且不能与 `custom_model_id` 同用。
- `vocal_gender` (string / 可选) — 人声性别。取值 `Male`、`Female`，简写 `m`、`f`、`male`、`female` 由后端归一化。
- `style_weight` (number / 可选) — 风格权重，取值 0.00 到 1.00。两种模式都校验并生效。
- `weirdness_constraint` (number / 可选) — 创意/怪异度，取值 0.00 到 1.00。两种模式都生效。
- `audio_weight` (number / 可选) — 音频权重，取值 0.00 到 1.00。两种模式都生效。
- `variety` (string / 可选) — 风格变化幅度，取值 `off`、`normal`、`high`、`extra`、`max`。可不传，官方未给固定默认值。
- `max_mode` (boolean / 可选) — 开启 Max 模式，默认 `false`。**前提是 `custom: true`**，按常规价格两倍收费。
- `audio_format` (string / 可选) — 输出音频格式，取值 `mp3`、`m4a`、`wav`。不填由服务端自行决定。
- `duration` (integer / 可选) — 期望时长，取值 10 到 360 秒。**仅自定义模式可用**，最终时长以任务实际结果为准。
## 响应
- `code` (integer) — 状态码，200 表示已受理。
- `data[].status` (string) — 提交后为 `submitted`。
- `data[].task_id` (string) — 任务 ID，用于轮询。
## 取结果
用 `GET /v1/music/tasks/{task_id}` 轮询。任务查询的字段说明见「Suno 通用约定与任务查询」。
完成后结果在 `data.result.music[]`，每一项含：
| 字段 | 说明 |
|---|---|
| `audio_url` | 音频地址 |
| `image_url` | 封面图 |
| `video_url` | 视频地址（部分任务返回） |
| `title` | 曲目标题 |
| `duration` | 实际时长 |
失败时 `data.error.message` 给出原因，预扣额度会自动退回。
## 几个容易踩的点
**灵感模式下 title 和 style 会被丢掉。** 想要指定标题与风格标签，必须 `custom: true`。
**Max 模式需要两个条件。** `max_mode: true` 之外还要 `custom: true`，否则不生效。
**version 和 custom_model_id 不能同时给。** 同时发送会报错。
**歌词用段落标记。** 以 `[Verse]`、`[Chorus]` 这类标记开头，换行在 JSON 里写成 `\n`。
## 错误码
| HTTP | type | 说明 |
|---|---|---|
| 400 | invalid_request_error | 请求参数无效 |
| 401 | authentication_error | 身份验证失败，请检查您的API密钥 |
| 402 | payment_required | 账户余额不足，请充值后再试 |
| 429 | rate_limit_error | 请求过于频繁，请稍后再试 |
更多状态码与重试建议见[错误码与限流](../../../support/errors.html)，常见报错的排查步骤见[常见问题](../../../support/faq.html)。
## 使用示例
提交一个任务并拿到 `task_id`：
> **Note:** 
> 提交成功只表示任务已受理。真正的产物要拿返回的 `task_id` 去任务查询接口轮询，`status` 变成 `completed` 之后才有结果。
**生成音乐{Generate music}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "suno",
    "custom": false,
    "version": "v6",
    "prompt": "深夜城市 lo-fi 钢琴配雨声"
  }'
```
**生成音乐{Generate music}::Python**
```
import requests
res = requests.post(
    "https://api.oairoute.com/v1/music/generations",
    headers={
        "Authorization": "Bearer YOUR_OAIRoute_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "suno",
        "custom": False,
        "version": "v6",
        "prompt": "深夜城市 lo-fi 钢琴配雨声",
    },
)
task_id = res.json()["data"][0]["task_id"]
print("任务号", task_id)
```
**生成音乐{Generate music}::JavaScript**
```
const url = "https://api.oairoute.com/v1/music/generations";
const options = {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "suno",
    "custom": false,
    "version": "v6",
    "prompt": "深夜城市 lo-fi 钢琴配雨声"
  }),
};
fetch(url, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
```
**200 生成音乐{Generate music}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K" }
  ]
}
```
**纯音乐{Instrumental}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "suno",
  "custom": true,
  "instrumental": true,
  "version": "v6",
  "title": "清晨咖啡馆",
  "style": "acoustic guitar, warm, mellow",
  "duration": 120
}'
```
**纯音乐{Instrumental}::Python**
```
import requests
url = "https://api.oairoute.com/v1/music/generations"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
      "model": "suno",
      "custom": true,
      "instrumental": true,
      "version": "v6",
      "title": "清晨咖啡馆",
      "style": "acoustic guitar, warm, mellow",
      "duration": 120
    }
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**纯音乐{Instrumental}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/music/generations", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "suno",
    "custom": true,
    "instrumental": true,
    "version": "v6",
    "title": "清晨咖啡馆",
    "style": "acoustic guitar, warm, mellow",
    "duration": 120
  }),
});
console.log(await res.json());
```
**200 纯音乐{Instrumental}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K" }
  ]
}
```
