# 词曲分离
> 把完整混音拆成独立音轨，异步任务
> 成品是一个 zip 打包文件，内含人声与伴奏等分轨
> 用 `clip_id` 引用源音频
`POST /v1/music/generations/stemsFlowMusic`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 请求参数
- `model` (string / 必填) — 固定填 `flowmusic`，大小写不敏感。
- `clip_id` (string / 必填) — 待分离音轨的 clip_id，取自某个已成功任务的 `result.music[].clip_id`。
本接口没有其他可选参数，也没有长度或格式的额外校验规则。
## 提交响应
- `code` (integer) — 状态码，成功为 200。
- `data[].status` (string) — 初始提交时为 `submitted`。
- `data[].task_id` (string) — 任务唯一标识，用于查询进度与结果。
## 结果字段
- `result.music[].clip_id` (string) — 新结果的 clip_id。
- `result.music[].file_url` (string) — 分轨包下载地址。zip 格式。
- `result.music[].url` (string) — 与 `file_url` 相同的地址，两个字段指向同一份文件。
- `result.music[].mime_type` (string) — 固定为 `application/zip`。
- `result.music[].size_bytes` (integer) — 文件大小，单位字节。分轨包通常有 20MB 左右。
## 怎么用这个结果
返回的不是单条音频，而是一个 zip。下载后解压，里面按轨道分开：
| 文件 | 内容 |
|---|---|
| 人声轨 | 只含演唱部分 |
| 伴奏轨 | 去掉人声的器乐 |
| 其他轨 | 视模型能力，可能有鼓、贝斯等 |
拿到分轨后可以单独处理某条轨道，比如给人声加混响、替换伴奏，再重新合成。
> **Note:** 
> 解压前先确认 `size_bytes` 与实际下载大小一致。分轨包较大，网络中断时容易拿到残缺的 zip，解压会报错。建议下载后校验文件完整性。
## 与全量分轨的区别
| 接口 | 模型 | 产出 |
|---|---|---|
| 本接口 | flowmusic | 人声与伴奏为主的 zip 包 |
| 全量分轨（Suno） | suno | 鼓、贝斯、吉他、键盘等全部独立轨道 |
需要更细的乐器级拆分时，用 Suno 的全量分轨接口。
## 错误码
错误响应的格式、状态码与重试建议见[错误码与限流](../../../support/errors.html)，常见报错的排查步骤见[常见问题](../../../support/faq.html)。
## 使用示例
提交一个任务并拿到 `task_id`：
> **Note:** 
> 提交成功只表示任务已受理。真正的产物要拿返回的 `task_id` 去任务查询接口轮询，`status` 变成 `completed` 之后才有结果。
**词曲分离{Stem separation}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/music/generations/stemsFlowMusic' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "flowmusic",
    "clip_id": "c_01KA"
  }'
```
**词曲分离{Stem separation}::Python**
```
import requests
res = requests.post(
    "https://api.oairoute.com/v1/music/generations/stemsFlowMusic",
    headers={
        "Authorization": "Bearer YOUR_OAIRoute_KEY",
        "Content-Type": "application/json",
    },
    json={"model": "flowmusic", "clip_id": "c_01KA"},
)
print(res.json()["data"][0]["task_id"])
```
**词曲分离{Stem separation}::JavaScript**
```
const url = "https://api.oairoute.com/v1/music/generations/stemsFlowMusic";
const options = {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "flowmusic",
    "clip_id": "c_01KA"
  }),
};
fetch(url, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
```
**200 词曲分离{Stem separation}**
```
{
  "code": 200,
  "data": {
    "id": "task_01K8B11M0HP1GJWBJYZMKX1XS1",
    "status": "completed",
    "progress": 100,
    "created": 1763088289,
    "completed": 1763088401,
    "actual_time": 112,
    "cost": 0.024,
    "credits_cost": 0.24,
    "result": {
      "music": [
        {
          "clip_id": "c_01KC",
          "file_url": "https://cdn.oairoute.com/m/c_01KC_stems.zip",
          "url": "https://cdn.oairoute.com/m/c_01KC_stems.zip",
          "mime_type": "application/zip",
          "size_bytes": 20323367
        }
      ]
    }
  }
}
```
