接入指南 · API
更新于 2026-10-22
使用个人 API Key 通过 HTTPS 调用现有工具。下面的示例以 MP3 人声分离为例,依次运行各步骤;更换工具时,请先读取它的参数与输入限制。
需要 Bash、curl 7.76+ 和 jq;所有步骤在同一个终端依次运行。
01准备与鉴权
在账户中创建“读取与执行”密钥。命令行使用 Authorization: Bearer 鉴权,无需登录 Cookie、CSRF 或定期刷新网页会话。
工具和 IP 留空表示不限;仍受账户策略约束。预算按 UTC 日/月计算,传输中断仍占用本次授权量。 新密钥继承权限与原到期时间。旧密钥最多再有效 5 分钟,请在此期间更新脚本。
创建密钥 →jq() { command jq "$@" | tr -d '\r'; }
read -rsp 'TELKNET_API_KEY: ' TELKNET_API_KEY; printf '\n'
export TELKNET_API_KEY
BASE="${TELKNET_BASE_URL:-https://telknet.cc}"
TOOL="${TELKNET_TOOL:-music-vocal-split}"
FILE="${TELKNET_FILE:-sample.mp3}"
curl --connect-timeout 10 --max-time 60 --fail-with-body "$BASE/api/v1/credits/balance" \
-H "Authorization: Bearer $TELKNET_API_KEY"02上传文件
先申请预签名地址,再 PUT 原文件。文件大小必须使用真实字节数,Content-Type 必须与申请时一致。
curl --connect-timeout 10 --max-time 60 --fail-with-body "$BASE/api/v1/tools/$TOOL/upload" \
-H "Authorization: Bearer $TELKNET_API_KEY" \
-H 'Content-Type: application/json' \
-d "$(jq -n --arg filename "$(basename "$FILE")" \
--argjson size "$(wc -c < "$FILE")" \
'{filename:$filename,content_type:"audio/mpeg",file_size:$size}')" \
-o upload.json || { cat upload.json >&2; exit 1; }
curl --connect-timeout 10 --max-time 1800 --fail-with-body --request PUT \
-H 'Content-Type: audio/mpeg' --upload-file "$FILE" \
"$(jq -r '.data.upload_url' upload.json)"预签名上传地址通常 15 分钟有效。PUT 时不要发送 API Key。示例走单次 PUT;如主动设置 multipart_supported=true,则按返回的 parts 上传并调用 upload/multipart/complete,失败时调用 abort。
03确认价格并提交
先读取所选工具/模型的基础价格,将响应原样放入 pricing,提交成功后保存 task_id。数量、预分轨等参数仍按工具规则计费;RVC 训练须先完成分析并获取训练报价。
printf '{}' > params.json
curl --connect-timeout 10 --max-time 60 --fail-with-body "$BASE/api/v1/tools/$TOOL/quote" \
-H "Authorization: Bearer $TELKNET_API_KEY" \
-H 'Content-Type: application/json' \
-d "$(jq -n --slurpfile params params.json '{params:$params[0]}')" \
-o quote.json || { cat quote.json >&2; exit 1; }
jq -n --arg tool "$TOOL" --arg key "$(jq -r '.data.s3_key' upload.json)" \
--slurpfile params params.json --slurpfile quote quote.json \
'{tool_id:$tool,file_key:$key,params:$params[0],pricing:$quote[0].data}' > request.json
REQUEST_KEY="$(date +%s)-$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"
printf '%s' "$REQUEST_KEY" > request-key.txt
curl --connect-timeout 10 --max-time 60 --fail-with-body "$BASE/api/v1/tools/$TOOL/tasks" \
-H "Authorization: Bearer $TELKNET_API_KEY" \
-H "Idempotency-Key: $REQUEST_KEY" \
-H 'Content-Type: application/json' --data-binary @request.json -o task.json || { cat task.json >&2; exit 1; }
TASK=$(jq -r '.data.task_id' task.json)报价不预留积分。409 PRICE_CHANGED 时重新读取并确认价格后再提交;不要无条件重提。音乐生成和参考翻唱必须携带所选模型对应的参数。
保存 request-key.txt 和 request.json。同一账户用相同 Idempotency-Key 和相同请求正文重放,会返回原任务;新任务使用新键。结果不明时不要把原提交当作新请求重新运行。
04查询任务进度
每 3 秒查询一次。completed 才能下载;failed、timeout、cancelled 是终态。示例最多等候两小时,退出轮询不会取消任务。
deadline=$((SECONDS + 7200))
while (( SECONDS < deadline )); do
curl --connect-timeout 10 --max-time 60 --fail-with-body "$BASE/api/v1/tasks/$TASK" \
-H "Authorization: Bearer $TELKNET_API_KEY" -o status.json || { cat status.json >&2; exit 1; }
status=$(jq -r '.data.status' status.json)
case "$status" in
completed) break ;;
failed|timeout|cancelled) cat status.json >&2; exit 1 ;;
pending|processing) sleep 3 ;;
*) cat status.json >&2; exit 1 ;;
esac
done
test "$(jq -r '.data.status' status.json)" = completed05下载结果
将 output_files 中的 s3_key 做 URL 编码后用作 fileId。proxy=true 通过同源接口传输原文件,并校验任务归属。
mkdir -p results
jq -r '.data.output_files | to_entries[] | .key' status.json | while read -r INDEX; do
FILE_ID=$(jq -r --argjson i "$INDEX" '.data.output_files[$i].s3_key | @uri' status.json)
NAME=$(basename "$(jq -r --argjson i "$INDEX" '.data.output_files[$i].name' status.json)")
curl --connect-timeout 10 --max-time 7200 --fail-with-body "$BASE/api/v1/tasks/$TASK/files/$FILE_ID?proxy=true" \
-H "Authorization: Bearer $TELKNET_API_KEY" \
--output "results/$INDEX-$NAME.part" || exit 1
EXPECTED=$(jq -r --argjson i "$INDEX" '.data.output_files[$i].size_bytes' status.json)
test "$(wc -c < "results/$INDEX-$NAME.part")" -eq "$EXPECTED" || exit 1
mv "results/$INDEX-$NAME.part" "results/$INDEX-$NAME"
done携带 Bearer 请求 /api/v1/tasks/{taskId}/download 时直接返回原文件或 ZIP。文件遵循保留期;API Key 不会转发给对象存储。
错误与恢复
读取 HTTP 状态和原始 JSON 中的 error.code、message、details。不要只依赖错误文案,也不要把错误响应保存成结果文件。
| 400 | 检查文件、参数和 JSON 结构。 |
| 401 | 密钥缺失、无效、到期或已撤销。 |
| 402 | 账户积分不足,先检查余额。 |
| 403 | 只读密钥不能执行操作,或无权访问该资源。 |
| 404 | 任务、文件或工具不存在,或不属于当前账户。 |
| 409 | 价格或任务状态发生变化;读取错误码后处理。 |
| 413 | 文件超过该工具大小上限。 |
| 429 | 请求过多,按 Retry-After 等待。 |
| 503 | 工具维护、服务或依赖暂不可用;保留错误后稍后查询。 |
429 按 Retry-After 等待;无该头时使用有上限的退避。只对查询、下载等可安全重试的读取操作重试。POST 上传申请或提交发生网络超时时,先核对原请求结果,不自动重复创建任务。
{
"ok": false,
"error": {
"code": "API_KEY_SCOPE",
"message": "此 API 密钥无权执行该操作。",
"details": []
}
}HTTP_CODE=$(curl --connect-timeout 10 --max-time 60 --silent --show-error \
-H "Authorization: Bearer $TELKNET_API_KEY" \
--output response.json --dump-header response.headers --write-out '%{http_code}' \
"$BASE/api/v1/tasks/$TASK")
if [[ "$HTTP_CODE" != 2* ]]; then
cat response.json >&2
if [[ "$HTTP_CODE" == 429 ]]; then
awk 'tolower($1)=="retry-after:" {print $2}' response.headers
fi
exit 1
fi保留 task.json 中的 task_id,恢复时从查询步骤继续。可通过任务列表核对近期提交;确认是否需要停止后再调用 cancel。
接口速查
所有地址均使用同一站点的 /api/v1 前缀。密钥仅访问本人业务资源,不能管理账户、创建其他密钥或调用后台和内部回调。
| GET | /api/v1/tools | 工具目录 |
| GET | /api/v1/tools/{toolId} | 参数与输入限制 |
| GET | /api/v1/credits/balance | 账户余额 |
| POST | /api/v1/tools/{toolId}/quote | 当前价格 |
| POST | /api/v1/tools/{toolId}/upload | 上传文件 |
| POST | /api/v1/tools/{toolId}/tasks | 确认价格并提交 |
| GET | /api/v1/tasks/{taskId} | 查询任务进度 |
| GET | /api/v1/tasks | 本人任务列表 |
| GET | /api/v1/tasks/{taskId}/files/{fileId}?proxy=true | 下载结果 |
| POST | /api/v1/tasks/{taskId}/cancel | 取消本人任务 |
midi-converter 与 midi-lyrics 在浏览器本地运行,不支持服务端上传或任务执行。其他工具的可用状态、格式、大小上限和参数,以工具详情接口为准。