API 文档
电音基调查询库 · KEY & BPM 数据库开放接口。基础地址:https://www.a.core2vst.com
对接流程:① 调登录接口换取 Token → ② 用 RSA 私钥对请求签名 → ③ 调基调查询接口。
· 安全提醒:私钥请妥善保管,请勿硬编码在可分发的程序中明文暴露;
· 限速:接口存在频率限制,超限返回
· 安全提醒:私钥请妥善保管,请勿硬编码在可分发的程序中明文暴露;
· 限速:接口存在频率限制,超限返回
429,请控制调用节奏。
0. 概述
| 步骤 | 接口 | 方法 | 说明 |
|---|---|---|---|
| — | 搜索 | GET | /music/search —— 公开,无需登录 |
| — | 统计 | GET | /music/stats —— 公开,无需登录 |
| ① | 登录 | POST | /music/login —— 换取访问 Token |
| ② | 基调查询 | POST | /music/lookup —— RSA 签名 + Token,返回歌曲调性 |
1. 通用返回与错误码
所有接口返回统一的 JSON 结构:
{
"code": 200,
"data": { ... },
"msg": "success"
}
| code | 含义 | 处理建议 |
|---|---|---|
| 200 | 成功,data 有数据 | 正常解析 |
| 301 | 未命中(miss) | 无结果,不是错误 |
| 400 | 缺少必填参数 | 检查参数名与必填项 |
| 401 | 未登录或无权限 | 先登录 / 确认该接口权限 |
| 429 | 请求过于频繁(存在频率限制) | 降速重试 |
| 500 | 服务异常 | 稍后重试 / 联系平台 |
| 10003 | 认证失败(未登录 / 账号密码错误 / Token 无效 / 账号禁用) | 重新登录 |
| 10006 | 签名校验失败 | 检查签名串与密钥 |
| 10008 | 请求已过期(时间戳超 ±300 秒) | 用当前时间重新签名 |
| 10019 | 会员已过期 | 提示用户续费 |
data 中所有字段值均为字符串类型。
2. 搜索接口公开
GET /music/search —— 按歌名 / 歌手检索,返回匹配的 KEY、大小调等信息(分页)。
请求参数
| 参数 | 必填 | 默认 | 说明 |
|---|---|---|---|
| q | 是 | — | 关键词,最长 100 字符;多个词用空格分隔(AND 匹配) |
| type | 否 | all | all 全部 / song 标题 / artist 歌手 |
| quality | 否 | all | all / official 官方 / user 用户 / dead 已失效 |
| page | 否 | 1 | 页码,≥1 |
| size | 否 | 20 | 每页条数,1–50 |
请求示例
GET /music/search?q=Faded&type=all&quality=all&page=1&size=2
命中返回(code=200)
{
"code": 200,
"data": {
"total": "384",
"page": "1",
"size": "2",
"items": [
{"id":"150473","song":"7爷、Faded、浪子康、扎职 - Gangsta Walk (DJ版)","code":"0","basic":"Ab","basic_t":"273","scale":"小调","recog":"n","recog_link":""}
]
},
"msg": "success"
}
未命中返回(code=301)
{"code":301,"data":{"total":"0","page":"1","size":"20","items":[]},"msg":"未命中"}
排序:官方 (official) → 用户 (user) → 已失效 (dead),同级按歌名升序。
3. 统计接口公开
GET /music/stats —— 返回数据库中按质量分类的记录总数。
GET /music/stats
{
"code": 200,
"data": {"total":"803146","official":"114221","user":"390384","dead":"298541"},
"msg": "success"
}
4. 登录接口公开
POST /music/login —— 获取访问 Token。支持两种协议,二选一:
方式 A(推荐,客户端已登录会员时):user_token + machine_code
| 参数 | 必填 | 说明 |
|---|---|---|
| user_token | 是 | 会员系统真实 token(与会员后台共用设备会话) |
| machine_code | 是 | 设备机器码 |
POST /music/login
Content-Type: application/x-www-form-urlencoded
user_token=xxxx&machine_code=yyyy
方式 B(账号密码):account + password
| 参数 | 必填 | 说明 |
|---|---|---|
| account | 是 | 账号 / 手机号 / 邮箱 |
| password | 是 | 明文密码,服务端按 sha1(md5(password)) 校验 |
POST /music/login
Content-Type: application/x-www-form-urlencoded
account=your_account&password=your_password
常见返回
| 场景 | 返回 |
|---|---|
| 成功 | {"code":200,"data":{...},"msg":"success"} |
| 账号密码错误 / token 失效 | {"code":10003,"msg":"用户名或密码错误"} 或 登录已失效,请重新登录 |
| 账号被禁用 | {"code":10003,"msg":"账号已被禁用"} |
| 会员过期 | {"code":10019,"msg":"会员已过期"} |
| 参数缺失 | {"code":400,"msg":"缺少参数 account 或 password"} |
5. 签名规则(RSA)
鉴权接口(lookup / feedback)需要 RSA 签名,规则如下:
| 项目 | 说明 |
|---|---|
| 算法 | RSA 2048-bit,PKCS#1 v1.5 |
| 哈希 | SHA-256 |
| 密钥 | 客户端私钥签名(client_private_key),服务端公钥验签 |
| 输出 | Base64 编码 |
| 时间戳有效期 | ±300 秒,超时返回 10008 |
签名字符串
act=<act>&t=<t>#<JSON字符串>
其中 <act> 为动作名,<t> 为当前时间戳(秒),<JSON字符串> 为 POST body 中 D 参数的原始 JSON(未 urlencode 之前)。
请求格式
POST /music/lookup?act=lookup&t=<时间戳>&sign=<Base64签名>
Content-Type: application/x-www-form-urlencoded
D=<urlencode(JSON)>
6. 基调查询接口需签名
POST /music/lookup —— 按歌名精确查询单首歌曲(大小写不敏感,不做模糊匹配)。
URL 参数
| 参数 | 必填 | 说明 |
|---|---|---|
| act | 是 | 固定 lookup |
| t | 是 | 当前时间戳(秒),±300 秒有效 |
| sign | 是 | RSA 签名(Base64) |
POST Body
| 参数 | 必填 | 说明 |
|---|---|---|
| D | 是 | JSON 的 urlencode 编码:{"token":"...","song":"..."} |
JSON 字段:token(登录返回的 Token)、song(歌名,最长 200 字符)。
请求示例
POST /music/lookup?act=lookup&t=1725446400&sign=abc123...
Content-Type: application/x-www-form-urlencoded
D=%7B%22token%22%3A%22xxx%22%2C%22song%22%3A%22Faded%22%7D
返回
// 命中
{"code":200,"data":{...单条记录...},"msg":"success"}
// 未命中
{"code":301,"data":null,"msg":"未命中"}
// 参数缺失
{"code":400,"data":null,"msg":"缺少参数 act / t / sign"}
7. data 字段说明
| 字段 | 说明 |
|---|---|
| id | 记录 ID |
| song | 歌曲名(常含歌手前缀) |
| code | 内部编码 |
| basic | 调性,如 Ab、Eb minor |
| basic_t | BPM / 音调数值 |
| scale | 大小调:大调 / 小调 |
| recog | 是否官方识别:y / n |
| recog_link | 识别来源链接(可为空) |
8. 完整调用示例
cURL
curl "https://www.a.core2vst.com/music/search?q=Faded&type=all&page=1&size=20"
cURL(搜索接口,无需鉴权)
curl "https://www.a.core2vst.com/music/search?q=Faded&type=all&page=1&size=20"
Python(登录 → 签名 → 查询 完整流程)
import requests, time, json, urllib.parse
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
BASE = "https://www.a.core2vst.com"
PRIV = serialization.load_pem_private_key(open("client_private_key.pem","rb").read(), None)
# ① 登录取 Token
r = requests.post(BASE + "/music/login",
data={"account": "your_account", "password": "your_password"}).json()
token = r["data"]["token"]
# ② 构造业务 JSON 并签名
payload = json.dumps({"token": token, "song": "Faded"}, separators=(",", ":"))
t = str(int(time.time()))
sign_str = "act=lookup&t=" + t + "#" + payload
sign = base64.b64encode(PRIV.sign(sign_str.encode(), padding.PKCS1v15(), hashes.SHA256())).decode()
# ③ 查询
r2 = requests.post(BASE + "/music/lookup?act=lookup&t=" + t + "&sign=" + sign,
data={"D": urllib.parse.quote(payload)}).json()
if r2["code"] == 200:
print("调性:", r2["data"]["basic"], r2["data"]["scale"])
else:
print("失败:", r2["code"], r2["msg"])
PHP
<?php
$base = "https://www.a.core2vst.com";
// ① 登录
$login = json_decode(file_get_contents($base . "/music/login", false,
stream_context_create(["http" => ["method" => "POST", "header" => "Content-Type: application/x-www-form-urlencoded",
"content" => http_build_query(["account" => "your_account", "password" => "your_password"])]])), true);
$token = $login["data"]["token"];
// ② 签名(私钥文件 client_private_key.pem)
$payload = json_encode(["token" => $token, "song" => "Faded"]);
$t = time();
openssl_sign("act=lookup&t=" . $t . "#" . $payload, $sign, file_get_contents("client_private_key.pem"), OPENSSL_ALGO_SHA256);
$sign = base64_encode($sign);
// ③ 查询
$ch = curl_init($base . "/music/lookup?act=lookup&t=" . $t . "&sign=" . urlencode($sign));
curl_setopt_array($ch, [CURLOPT_POST => 1, CURLOPT_POSTFIELDS => ["D" => urlencode($payload)], CURLOPT_RETURNTRANSFER => 1]);
$r = json_decode(curl_exec($ch), true);
if ($r["code"] == 200) { echo $r["data"]["basic"], " ", $r["data"]["scale"]; }