跳转到内容

原生接口

AMLL 词库的原生接口,提供最完整的匹配与搜索能力

在词库中搜索符合条件的歌词

GET/v1/lyrics/search

至少需要提供以下任意一个参数。可以组合多个参数以提高精确度

  • 如果同时传入 q 和其他参数,则忽略 q,优先使用其他参数
  • 多个非 q 参数之间为 AND 交集关系
  • 空字符串参数视为未传入
  • 建议使用 musicName、artistName 和 albumName 而不是 q 来提高搜索精确度
参数名 类型 匹配逻辑 说明
q string 模糊包含 模糊搜索歌曲名、歌手名、专辑名和歌词正文
musicName string 模糊包含 限定匹配曲名
artistName string 模糊包含 限定匹配歌手名
albumName string 模糊包含 限定匹配专辑名
lyricText string 全文检索 限定匹配歌词正文,不区分大小写
authorId string 严格全等 TTML 贡献者的 GitHub ID
authorUsername string 严格全等 TTML 贡献者的 GitHub 用户名

以下参数用于翻页,均为可选。它们不计入上方「至少提供一个搜索参数」的要求,也不会影响 q 与其他参数之间的优先级判定

参数名 类型 默认值 取值范围 说明
page number 1 >= 1 页码,从 1 开始
pageSize number 50 1–100 每页返回的条目数
  • 传入非正整数、0 或超出范围的值将返回 400
  • 传入空值(如 ?page=)视为未传入,使用默认值
  • 仅传分页参数而不带任何搜索参数仍会返回 400
  1. 结果按匹配相关性降序排序,相关性相同时按时间戳降序排序,仍相同时按 id 升序排序
  2. 排序结果稳定,同一查询条件下重复请求的分页结果一致,相邻页之间不会重复或遗漏

请求成功时返回 200 状态码及如下结构

export interface PaginationInfo {
/** 当前页码(游标分页模式下省略) */
page?: number;
/** 每页条目数 */
pageSize: number;
/** 匹配到的总条目数 */
total: number;
/** 总页数,`total` 为 0 时该值为 0(游标分页模式下省略) */
totalPages?: number;
/** 当前页之后是否还有更多结果 */
hasMore: boolean;
/** 下一页游标,格式为 `<createdAt>_<id>`,当还有更多结果时提供 */
nextCursor?: string;
}
type SearchLyricsResponse = ApiResponse<{
items: SongItem[];
pagination: PaginationInfo;
}>;

字段说明:

  • ApiResponse<T>: 全局泛型响应包装结构,详见 ApiResponse 模型
  • items: 搜索到的歌曲列表,元素类型为 SongItem 模型
    • 包含 createdAt 创建时间戳
    • 搜索结果中每项的 lyrics 固定为 undefined
    • 仅在歌词正文包含搜索词时,matchContext 存在且包含 snippet 高亮代码片段
    • 长度不会超过 pageSize,末页可能少于 pageSize
  • pagination: 包含当前请求的分页元信息对象,详见 PaginationInfo 模型
    • page: 当前页码
    • pageSize: 每页条目数
    • total: 当前查询条件匹配到的总条目数,不受 page / pageSize 影响
    • totalPages: 总页数,total 为 0 时该值为 0
    • hasMore: 等价于 page < totalPages,可直接用于判断是否继续请求下一页
  • 请求的 page 超过 totalPages 时,items 为空数组,其余字段照常返回
示例响应
{
"status": 200,
"data": {
"items": [
{
"id": 8713122671638320,
"filename": "1702791169000-50747104-65652a93.ttml",
"createdAt": 1702791169000,
"musicNames": [
"ME! (feat. Brendon Urie of Panic! At The Disco)"
],
"artistNames": [
"Taylor Swift",
"Brendon Urie"
],
"albumNames": [
"ME! (feat. Brendon Urie of Panic! At The Disco)"
],
"ncmMusicIds": [
"1361348080"
],
"qqMusicIds": [],
"appleMusicIds": [],
"spotifyIds": [],
"isrcs": [],
"authorIds": [
"50747104"
],
"authorUsernames": [
"Xionghaizi001"
],
"matchContext": {
"snippet": "I never want to see you walk away\n<mark>'Cause one of these things is not like the others</mark>\nLiving in winter I am your summer"
}
},
{
"id": 8489623513658892,
"filename": "1689481280000-132769718-1028454c.ttml",
"createdAt": 1689481280000,
"musicNames": [
"ME! (feat. Brendon Urie of Panic! At The Disco)"
],
"artistNames": [
"Taylor Swift",
"Brendon Urie"
],
"albumNames": [
"ME! (feat. Brendon Urie of Panic! At The Disco)"
],
"ncmMusicIds": [
"1361348080"
],
"qqMusicIds": [],
"appleMusicIds": [],
"spotifyIds": [],
"isrcs": [],
"authorIds": [
"132769718"
],
"authorUsernames": [
"Y-CIAO"
],
"matchContext": {
"snippet": "And there's a lot of lame guys out there\n<mark>'Cause one of these things is not like the others</mark>\nLiving in winter I am your summer"
}
}
],
"pagination": {
"page": 1,
"pageSize": 50,
"total": 2,
"totalPages": 1,
"hasMore": false
}
}
}

遍历或浏览词库中的歌词条目,支持排序、精确结构化过滤、传统偏移分页与增量游标分页

GET/v1/lyrics/list

所有过滤参数均为可选,多个过滤参数之间为 AND 交集关系。空字符串参数视为未传入

参数名 类型 匹配逻辑 说明
authorId string 严格全等 TTML 贡献者的 GitHub ID
authorUsername string 严格全等 TTML 贡献者的 GitHub 用户名
hasId string 集合包含 必须包含的外部平台 ID 或编码。多个取值用逗号分隔(如 ncmMusicId,isrc),必须同时具备
missingId string 集合排除 必须缺失的外部平台 ID 或编码。多个取值用逗号分隔(如 spotifyId,qqMusicId),必须全部缺失
since number 闭区间 >= 条目创建时刻起始时间戳(Unix 毫秒),筛选 createdAt >= since
until number 闭区间 <= 条目创建时刻截止时间戳(Unix 毫秒),筛选 createdAt <= until

外部标识枚举值(适用于 hasId 与 missingId):

  • ncmMusicId: 网易云音乐歌曲 ID
  • qqMusicId: QQ 音乐歌曲 ID
  • appleMusicId: Apple Music 歌曲 ID
  • spotifyId: Spotify 歌曲 ID
  • isrc: 国际标准音像制品编码 (ISRC)
参数名 类型 默认值 可选值 说明
sort string createdAt createdAt, id, musicName, artistName, albumName 排序字段维度
order string desc desc, asc 排序方向:desc 为降序,asc 为升序
  • 无论指定何种排序维度,底层均自动以 id 升序作为稳定二级排序,保证分页顺序的严格确定性
  • 传入未支持的 sort 或 order 取值将返回 400

接口支持两种分页模式:传统偏移分页与增量游标分页。两种模式互斥,不可混用

参数名 类型 默认值 取值范围 说明
page number 1 >= 1 页码,从 1 开始。与 cursor / before 互斥
pageSize number 50 1–100 每页返回的条目数
cursor string 无 复合游标串 下一页游标,格式为 <createdAt>_<id>。仅在 sort=createdAt 时可用
before string 无 复合游标串 cursor 的等价别名,两者行为完全一致

在词库持续更新的场景下,传统基于 page 的偏移分页(Offset Pagination)在翻到深页时,若有新歌词入库会导致后续数据整体后移,产生深翻页漂移(部分条目被重复读取或遗漏)。

为了支持全量遍历与稳定同步,接口提供了基于创建时间戳与唯一 ID 的复合游标分页:

  1. 首次请求时无需传 cursor(或请求第 1 页),响应中的 pagination.nextCursor 会返回下一页的游标串(例如 "1787382687321_1002")
  2. 后续请求携带 cursor=<nextCursor>(或 before=<nextCursor>)即可获取紧随其后的下一页数据
  3. 当 hasMore 为 false 时,表示已无后续数据,nextCursor 不再返回

请求成功时返回 200 状态码及如下结构:

type ListLyricsResponse = ApiResponse<{
items: SongItem[];
pagination: PaginationInfo;
}>;

字段说明:

  • ApiResponse<T>: 全局泛型响应包装结构,详见 ApiResponse 模型
  • items: 歌词条目列表,元素类型为 SongItem 模型
    • 列表结果中每项的 lyrics 和 matchContext 固定为 undefined
    • 包含 createdAt 字段(条目创建时刻 Unix 毫秒时间戳)
    • 长度不超过 pageSize
  • pagination: 分页元信息对象,详见 PaginationInfo 模型
    • 传统偏移分页模式:包含 page、pageSize、total、totalPages、hasMore;若 hasMore 为 true,同时提供 nextCursor
    • 游标分页模式:省略 page 与 totalPages;包含 pageSize、total、hasMore;若 hasMore 为 true,提供 nextCursor
示例响应(传统偏移分页第 1 页,附带下一页游标)
{
"status": 200,
"data": {
"items": [
{
"id": 5440178231786117,
"filename": "1787382687321-330521690-test2.ttml",
"createdAt": 1787382687321,
"musicNames": [
"Test Song Two"
],
"artistNames": [
"Artist Beta"
],
"albumNames": [],
"ncmMusicIds": [
"1002"
],
"qqMusicIds": [
"qq1002"
],
"appleMusicIds": [],
"spotifyIds": [
"sp1002"
],
"isrcs": [],
"authorIds": [
"330521690"
],
"authorUsernames": [
"beta_author"
]
},
{
"id": 699269132670751,
"filename": "1689087424000-108002475-test1.ttml",
"createdAt": 1689087424000,
"musicNames": [
"Test Song One"
],
"artistNames": [
"Artist Alpha"
],
"albumNames": [],
"ncmMusicIds": [
"1001"
],
"qqMusicIds": [],
"appleMusicIds": [],
"spotifyIds": [
"sp1001"
],
"isrcs": [
"USRC17607839"
],
"authorIds": [
"108002475"
],
"authorUsernames": [
"alpha_author"
]
}
],
"pagination": {
"page": 1,
"pageSize": 50,
"total": 2,
"totalPages": 1,
"hasMore": true,
"nextCursor": "1689087424000_699269132670751"
}
}
}
示例响应(游标分页模式)
{
"status": 200,
"data": {
"items": [
{
"id": 699269132670751,
"filename": "1689087424000-108002475-test1.ttml",
"createdAt": 1689087424000,
"musicNames": [
"Test Song One"
],
"artistNames": [
"Artist Alpha"
],
"albumNames": [],
"ncmMusicIds": [
"1001"
],
"qqMusicIds": [],
"appleMusicIds": [],
"spotifyIds": [
"sp1001"
],
"isrcs": [
"USRC17607839"
],
"authorIds": [
"108002475"
],
"authorUsernames": [
"alpha_author"
]
}
],
"pagination": {
"pageSize": 1,
"total": 2,
"hasMore": false
}
}
}

通过 ID 获取一首歌曲的元数据及其完整的 TTML 歌词

GET/v1/lyrics/get

至少需要提供以下任意一个参数

参数优先级:

  1. id 为最高优先级,传入时忽略其他所有参数
  2. filename 为次高优先级,传入时忽略平台 ID 参数
  3. 如果仅提供多个不同平台的 ID,将使用交集进行匹配,且只返回匹配结果中最新的一条。如果需要获取旧歌词,请使用 id 或 filename 精确匹配
参数名 类型 必填 说明
id number 否 由文件名生成的 53 位整数 ID,精确匹配
filename string 否 歌词文件名,精确匹配。必须以 .ttml 结尾
ncmMusicId string[] 否 网易云音乐 ID
qqMusicId string[] 否 QQ 音乐 ID
appleMusicId string[] 否 Apple Music ID
spotifyId string[] 否 Spotify ID
isrc string[] 否 ISRC 编码
format string 否 保留字段,默认为 ttml。传入其他值将返回 400

请求成功时返回 200 状态码及如下结构

type GetLyricResponse = ApiResponse<SongItem>;

关联模型说明:

  • ApiResponse<T>: 全局泛型响应包装结构,详见 ApiResponse 模型
  • data: 歌曲及完整歌词元数据,类型为 SongItem 模型,包含完整的 lyrics TTML 字符串
示例响应
{
"status": 200,
"data": {
"id": 269710089745311,
"filename": "1768754400682-250306205-r6IrpmBd.ttml",
"createdAt": 1768754400682,
"musicNames": [
"ME!",
"ME! (feat. Brendon Urie of Panic! At The Disco)"
],
"artistNames": [
"Brendon Urie",
"Taylor Swift"
],
"albumNames": [
"Lover"
],
"ncmMusicIds": [
"1361348080",
"1382781549"
],
"qqMusicIds": [
"0032UZe62rZk9K"
],
"appleMusicIds": [
"1468058706"
],
"spotifyIds": [
"2Rk4JlNc2TPmZe2af99d45"
],
"isrcs": [
"USUG11901494"
],
"authorIds": [
"108002475",
"132769718",
"207428447",
"250306205",
"34237075",
"50747104"
],
"authorUsernames": [
"SteamFinder",
"Xionghaizi001",
"Y-CIAO",
"apoint123",
"kid1412520",
"kid141252010"
],
"lyrics": "<已省略>",
"format": "ttml"
}
}