上傳後翻唱 API
介面說明
上傳後翻唱用於提交音訊檔案或音訊 URL,並基於該來源音訊生成新的翻唱版本。
介面位址:POST /api/music/upload-cover
計費:收費,目前預設 0.6 元/次。本介面是「上傳後翻唱」,不是上傳圖片封面;實際扣費以目前後台價格設定為準。
Max Mode / Variety:本介面支援選用參數 max_mode 與 variety(0-4)。開啟 max_mode
時本次依 2 倍價格計費(0.6 → 1.2 元/次),variety 不額外計費;兩者含義與寫法見
Suno API 介面文件總覽 的「進階參數」一節。
等待時間與逾時(重要):本介面是同步介面,回應返回時才代表訂單已被受理並提交生成。實測多數請求 1–3 秒返回,約 10% 超過 30 秒,最長約 230 秒。請把用戶端逾時設為 300 秒以上;未收到回應不等於沒有生成,逾時後請勿立即重試(會重複下單、重複扣費)。 連線中斷可稍後用
GET /api/music/songs確認。詳見 Suno API 介面文件總覽的「等待時間與逾時設定」。
音訊較大時,建議把「上傳」和「翻唱」拆成兩步(推薦)
本介面要求把整個音訊放進請求主體:音訊越大,請求主體越大,一旦網路抖動或逾時傳到一半就中斷, 伺服器會回應
unexpected end of JSON input(HTTP 400,不扣費)。音訊超過約 8MB、網路不穩定、或需要複用同一份來源素材時,請改用兩步式:
POST /api/music/upload-source先上傳來源音訊——免費、可隨時重試,成功拿到clip_id;POST /api/music/generate-from-source用這個clip_id發起翻唱——計費步驟的請求主體只有約 250 位元組。詳見上傳來源音訊 API、基於來源 clip 翻唱 API, 以及本文末尾的「大檔案與請求被截斷」。
請求參數
Headers
| 參數名 | 型別 | 必填 | 說明 |
|---|---|---|---|
| Authorization | string | 是 | Bearer YOUR_API_KEY |
| Content-Type | string | 是 | application/json |
Body 參數
| 參數名 | 型別 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| model | string | 否 | suno-v6 | 對客模型名:suno-v6、suno-v6-wild 或 suno-v6-mini |
| file_url | string | 否 | - | 來源音訊 URL |
| file_base64 | string | 否 | - | Base64 音訊 |
| file_name | string | 否 | - | 檔案名稱 |
| prompt | string | 否 | - | 新歌詞或改編方向 |
| style | string | 否 | - | 風格標籤 |
| title | string | 否 | - | 標題 |
| negativeTags | string | 否 | - | 負向風格 |
| instrumental | boolean | 否 | false | 是否純音樂 |
| waitAudio | boolean | 否 | false | 是否等待音訊完成 |
| cover_start_s | number | 否 | - | 翻唱片段開始秒數 |
| cover_end_s | number | 否 | - | 翻唱片段結束秒數 |
| audio_weight | number | 否 | - | 參考音訊依賴度,範圍 0.0-1.0;僅在提供參考音訊時可傳 |
cover_start_s 和 cover_end_s 的單位是秒,可以填小數;開始時間必須小於結束時間,且不能超過來源音訊長度。兩個欄位都省略時使用整段音訊。audio_weight 會對應到 Suno 的 metadata.control_sliders.audio_weight,用於控制生成結果對參考音訊的依賴程度;取值為 0.0-1.0,只有請求中提供有效的 file_url 或 file_base64 參考音訊時才可帶上。0 是有效值,省略欄位表示不指定並沿用 Suno 預設行為。instrumental、waitAudio 必須傳 JSON 布林值,不要傳字串。
上傳介面預設非同步回傳。回應中的 clips[].status 為 pending 時,audio_url 為空是正常狀態,不代表上傳或翻唱失敗;請保存回傳的真實 song_id,透過歌曲查詢介面輪詢到完成後再讀取音訊位址。
請求範例
curl -X POST https://www.suno-api.io/api/music/upload-cover \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"file_url": "https://example.com/source.mp3",
"file_name": "source.mp3",
"prompt": "新的中文歌詞或改編方向",
"style": "Mandopop, acoustic guitar",
"title": "翻唱版本",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
回應結果
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "翻唱版本",
"status": "pending"
}
]
}
}
大檔案與請求被截斷
推薦做法:上傳與翻唱拆成兩步
一次性介面(本介面)把上傳和生成合在一步:大 body 出現在唯一那一步,一旦中斷,既不知道有沒有生成、也不好判斷有沒有扣費。
| 第 1 步 上傳 | 第 2 步 翻唱 | |
|---|---|---|
| 介面 | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| 計費 | 免費(只上傳,不生成) | 0.6 元/次;開 Max Mode 為 1.2 元/次 |
| 請求主體 | 音訊本身(base64 / multipart),或 file_url 只傳連結 |
約 250 位元組(只傳一個 sourceClipId) |
| 回傳 | clip_id(來源音訊的 clip ID) |
data.clips[].song_id(生成結果) |
| 失敗了怎麼辦 | 直接重試,不扣費、不產生生成任務 | 用戶端逾時設 ≥300 秒;逾時先用 /api/music/songs 查,不要立刻重試 |
| 來源素材複用 | 同一個 clip_id 還能繼續用於續寫 / 替換 / 分軌 |
每次都要重傳音訊 |
結論:音訊超過約 8MB、網路不穩定、或同一份素材要用多次 → 用兩步式;音訊很小且網路穩定 → 用本介面更省事。
400 unexpected end of JSON input 是什麼
它的含義是伺服器收到的 JSON 不完整(不是參數寫錯、不是權限或餘額問題)。常見原因按機率排序:
- 大 body 傳輸中途被截斷:接入層會同時記錄「用戶端聲明要送多少」和「實際到達多少」。實測案例:用戶端聲明 14.17MB,實際只到達 11.8–12.4MB,三次請求都停在約 1.6–1.7 秒處;缺的位元組數每次都不同,說明是傳輸中斷而不是固定上限(伺服器不限制請求主體大小)。
Content-Length與實際傳送位元組數不一致:在 Node.js 裡用字串.length(UTF-16 字元數)當長度,遇到中文或多位元組內容就會算錯。- 寫 body 時用了字串而不是 Buffer,實際寫出的位元組數與聲明不符。
以上三種情況都發生在扣費之前,不會產生費用。
用戶端自查清單
-
Content-Length用Buffer.byteLength(json, 'utf8')(或Buffer.from(json).length)得到,不要用json.length; - 請求主體以 Buffer 寫出,不寫字串;
- socket / 請求逾時 ≥ 300 秒;
- 音訊大於約 8MB 時:改用
file_url(請求主體只有幾百位元組),或改用upload-source的 multipart 上傳,或直接走兩步式; - multipart 請求不要手動設定
Content-Type(交給用戶端自動帶 boundary); - 印出「實際傳送位元組數」並與
Content-Length比對; - 走兩步式時,確認第 1 步回傳
clip_id、status為完成態後,再送第 2 步。
常見錯誤對照
| 報錯 | 含義 | 處理 |
|---|---|---|
unexpected end of JSON input |
請求主體不完整(被截斷) | 按上面自查;或改用兩步式 |
invalid character '-' in numeric literal |
把 multipart 的 body 送給了 JSON 介面 | JSON 介面不要用 multipart;或不要手動設 Content-Type |
one of file_path, file_base64, file_url, or multipart file is required |
沒帶音訊 | 補 file_base64 / file_url / multipart file |
model is required |
請求主體是空的合法 JSON(例如 {}) |
至少帶上 model |
Invalid request: Invalid request, ... |
請求主體解析失敗的包裝提示 | 看後半句的具體原因(通常是上面幾條之一) |
相關介面:上傳來源音訊 API(第 1 步)、基於來源 clip 翻唱 API(第 2 步)。