# 歌词时间轴
> 生成逐句对齐的歌词时间轴，用于卡拉 OK 类应用，异步任务
> 结果含对齐数据与波形数据
> 只返回数据，不产出音频
`POST /v1/music/generations/alignedLyrics`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 请求参数
- `model` (string / 可选) — 音频模型，默认 `suno`。
- `task_id` (string / 必填) — 生成源音轨那次任务的 task_id。缺失或无法解析源音轨时，提交阶段直接返回 400。
- `audio_index` (integer / 可选) — 引用源任务结果 `data.result.music[]` 中的第几首，默认 `1`，从 1 开始。一次生成通常 2 首。
本端点没有 `version` 参数，传入会被忽略，不影响计费。
## 响应
- `code` (integer) — 响应状态码。
- `data[].status` (string) — 任务状态，取值 `submitted`。
- `data[].task_id` (string) — 任务唯一标识，用于后续轮询。
## 轮询结果
- `result.alignment` (array) — 逐句对齐结果，优先读取这个字段。
- `result.waveform_data` (array) — 波形数据，优先读取。
- `music[].aligned_words` (string) — 历史任务可能返回该字段。
- `music[].aligned_lyrics` (string) — 历史任务可能返回该字段。
- `music[].waveform_data` (array) — 历史任务可能返回该字段。
> **Note:** 
> 返回结构有新旧两套。新任务读 `result.alignment` 与 `result.waveform_data`；老任务的数据在 `music[]` 下的三个字段里。接的时候按这两个位置分别兜底，否则老数据会读出空值。
## 怎么用这份数据
卡拉 OK 类应用需要三样东西：每句歌词、该句的起止时间、当前播放位置。
```javascript
// 播放时按时间轴滚动高亮
function highlight(audio, alignment) {
  audio.addEventListener("timeupdate", () => {
    const t = audio.currentTime;
    const idx = alignment.findIndex(
      (line) => t >= line.start && t < line.end
    );
    document.querySelectorAll(".lyric-line").forEach((el, i) => {
      el.classList.toggle("active", i === idx);
    });
  });
}
```
字段名（`start`、`end`）以实际返回为准，第一次接的时候先打印一条看结构。
`waveform_data` 可以用来画波形进度条，比单纯的时间条更有节奏感。
## 错误码
| 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` 之后才有结果。
**歌词时间轴{Aligned lyrics}::cURL**
```
curl -X POST https://api.oairoute.com/v1/music/generations/alignedLyrics \
  -H 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  -H 'Content-Type: application/json' \
  --data '{
    "model": "suno",
    "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
    "audio_index": 1
  }'
```
**歌词时间轴{Aligned lyrics}::Python**
```
import requests
res = requests.post(
    "https://api.oairoute.com/v1/music/generations/alignedLyrics",
    headers={
        "Authorization": "Bearer YOUR_OAIRoute_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "suno",
        "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K",
        "audio_index": 1,
    },
)
print(res.json()["data"][0]["task_id"])
```
**歌词时间轴{Aligned lyrics}::JavaScript**
```
const url = "https://api.oairoute.com/v1/music/generations/alignedLyrics";
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
  }),
};
fetch(url, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
```
**200 歌词时间轴{Aligned lyrics}**
```
{
  "code": 200,
  "data": [
    { "status": "submitted", "task_id": "task_01K8D88M0HP1GJWBJYZMKX1XS1" }
  ]
}
```
