26j文档
试一试 →

下载音频文件

  • 将 Suno 歌曲下载为 MP3、M4A 或 WAV 文件
  • 支持一次请求多个格式,返回对应的文件 URL
  • 使用源任务 task_id 和 audio_index 指定要下载的歌曲
  • 异步提交任务,通过音乐任务查询接口获取结果

原 POST /v1/music/generations/wav 接口已弃用。旧接口暂时兼容,等价于调用新接口并传入 formats: ["wav"];新代码请统一使用 POST /v1/music/generations/download。

指定源歌曲: 传入生成源音轨时获得的 task_id,并用 audio_index 指定结果 data.result.music[] 中的第几首歌曲。audio_index 从 1 开始,默认值为 1。

请求示例
curl --request POST \
  --url https://26j.cn/v1/music/generations/download \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "suno",
    "task_id": "task_01JGXXXXXXXXXXXX",
    "audio_index": 1,
    "formats": ["mp3", "wav"]
  }'
import requests

url = "https://26j.cn/v1/music/generations/download"

payload = {
    "model": "suno",
    "task_id": "task_01JGXXXXXXXXXXXX",
    "audio_index": 1,
    "formats": ["mp3", "wav"],
}

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
const response = await fetch(
  "https://26j.cn/v1/music/generations/download",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "suno",
      task_id: "task_01JGXXXXXXXXXXXX",
      audio_index: 1,
      formats: ["mp3", "wav"],
    }),
  },
);

console.log(await response.json());
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    payload := map[string]interface{}{
        "model":       "suno",
        "task_id":     "task_01JGXXXXXXXXXXXX",
        "audio_index": 1,
        "formats":     []string{"mp3", "wav"},
    }

    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest(
        http.MethodPost,
        "https://26j.cn/v1/music/generations/download",
        bytes.NewBuffer(body),
    )
    req.Header.Set("Authorization", "Bearer <token>")
    req.Header.Set("Content-Type", "application/json")

    response, _ := http.DefaultClient.Do(req)
    defer response.Body.Close()
    result, _ := io.ReadAll(response.Body)
    fmt.Println(string(result))
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        String payload = """
        {
          "model": "suno",
          "task_id": "task_01JGXXXXXXXXXXXX",
          "audio_index": 1,
          "formats": ["mp3", "wav"]
        }
        """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://26j.cn/v1/music/generations/download"))
            .header("Authorization", "Bearer <token>")
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient().send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );
        System.out.println(response.body());
    }
}
<?php

$url = "https://26j.cn/v1/music/generations/download";
$payload = [
    "model" => "suno",
    "task_id" => "task_01JGXXXXXXXXXXXX",
    "audio_index" => 1,
    "formats" => ["mp3", "wav"]
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer <token>",
    "Content-Type: application/json"
]);

echo curl_exec($ch);
curl_close($ch);
?>
require "net/http"
require "json"

uri = URI("https://26j.cn/v1/music/generations/download")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer <token>"
request["Content-Type"] = "application/json"
request.body = {
  model: "suno",
  task_id: "task_01JGXXXXXXXXXXXX",
  audio_index: 1,
  formats: ["mp3", "wav"]
}.to_json

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

puts response.body
import Foundation

let url = URL(string: "https://26j.cn/v1/music/generations/download")!
let payload: [String: Any] = [
    "model": "suno",
    "task_id": "task_01JGXXXXXXXXXXXX",
    "audio_index": 1,
    "formats": ["mp3", "wav"]
]

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

URLSession.shared.dataTask(with: request) { data, _, error in
    if let error = error {
        print(error)
        return
    }
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}.resume()
响应示例
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01JHXXXXXXXXXXXX"
    }
  ]
}
{
  "error": {
    "message": "`formats` contains unsupported format `flac`. Supported: mp3 / m4a / wav",
    "type": "invalid_request_error",
    "code": "invalid_source_reference"
  }
}
{
  "error": {
    "code": 401,
    "message": "身份验证失败,请检查您的 API 密钥",
    "type": "authentication_error"
  }
}
{
  "error": {
    "code": 402,
    "message": "账户余额不足,请充值后再试",
    "type": "payment_required"
  }
}
{
  "error": {
    "code": "model_price_not_configured",
    "message": "模型价格未配置",
    "type": "permission_error"
  }
}
{
  "error": {
    "code": 429,
    "message": "请求过于频繁,请稍后再试",
    "type": "rate_limit_error"
  }
}
{
  "error": {
    "code": 500,
    "message": "服务器内部错误,请稍后重试",
    "type": "server_error"
  }
}

认证

Authorizationstring必填

所有接口均使用 Bearer Token 认证。访问 API Key 管理页面 获取 API Key。

Authorization: Bearer YOUR_API_KEY

请求参数

modelstring默认 suno

模型名称。当前填写 suno;省略时默认为 suno。

task_idstring必填

生成源歌曲时返回的任务 ID。

源任务必须:

  • 属于当前账户
  • 已完成
  • 包含可下载的音轨

音乐生成、延长、翻唱、分轨等音频任务均可作为来源;歌词、BPM 等仅返回文本的任务无法下载。

audio_indexinteger默认 1

要下载源任务结果 data.result.music[] 中的第几首歌曲。

  • 从 1 开始计数
  • 默认:1
  • 不得超过源任务实际包含的歌曲数量
formatsstring[]

要下载的文件格式数组,至少包含一项。

可选值:

  • mp3
  • m4a
  • wav

支持同时请求多个格式;格式名大小写不敏感,重复值会自动去重。结果顺序与请求顺序一致。

formatstring

只下载一种格式时,可使用此字段代替 formats。

示例:"format": "mp3"

formats 和 format 选择一种写法即可。两者均未提供或格式列表为空时,请求会返回 HTTP 400。

提交响应

成功提交后返回下载任务自己的 task_id:

{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01JHXXXXXXXXXXXX"
    }
  ]
}

返回的 data 是数组,请读取 data[0].task_id。它是新建的下载任务 ID,与请求中的源歌曲 task_id 不同。

查询下载结果

使用提交响应中的下载任务 ID 查询:

GET /v1/music/tasks/{task_id}

文件通常已在提交阶段准备完成,因此提交后可以立即查询一次。如果状态不是 completed 或 failed,再每 2 秒轮询一次,最多等待 60 秒。

下载完成

{
  "code": 200,
  "data": {
    "id": "task_01JHXXXXXXXXXXXX",
    "status": "completed",
    "progress": 100,
    "created": 1756800000,
    "completed": 1756800003,
    "actual_time": 3,
    "cost": 0.01,
    "credits_cost": 0.1,
    "result": {
      "music_id": "518c74ee-62ac-4ccd-b3d9-7003acd12ad7",
      "files": [
        {
          "format": "mp3",
          "url": "https://assets.26j.cn/audio/example.mp3"
        },
        {
          "format": "wav",
          "url": "https://assets.26j.cn/audio/example.wav"
        }
      ],
      "wavUrl": "https://assets.26j.cn/audio/example.wav"
    }
  }
}

读取 result.files[] 获取下载文件:

字段 类型 说明
format string 文件格式:mp3 / m4a / wav
url string 文件下载地址

result.wavUrl 仅用于兼容旧 WAV 接口。新代码请统一读取 result.files[]。

处理中

{
  "code": 200,
  "data": {
    "id": "task_01JHXXXXXXXXXXXX",
    "status": "processing",
    "progress": 50,
    "created": 1756800000
  }
}

此时没有 result 字段,请继续轮询。

下载失败

{
  "code": 200,
  "data": {
    "id": "task_01JHXXXXXXXXXXXX",
    "status": "failed",
    "progress": 100,
    "cost": 0,
    "error": {
      "message": "文件处理失败"
    }
  }
}

失败任务会自动退款,cost 为 0。可向用户显示 error.message 并提供重试操作。

文件 URL

下载结果通常使用 26j.cn 文件域名。返回的文件 URL 可能存在有效期,请在任务完成后及时下载并保存。

请在获得 URL 后尽快下载并保存文件,不要将临时 URL 作为长期存储地址。

错误处理

提交期参数错误会返回 HTTP 400,不创建任务、不扣费:

错误信息 原因
formats is required / must contain at least one 未提供下载格式
unsupported format 包含 mp3 / m4a / wav 以外的格式
task_id is required / invalid task_id format 源任务 ID 缺失或格式错误
source task not found 源任务不存在或不属于当前账户
audio_index N out of range 歌曲序号超出源任务音轨数量
track #N has no music_id 源任务未完成或对应歌曲没有音频

HTTP 403 且错误码为 model_price_not_configured 时,表示后台未配置 suno@download 价格,请联系平台支持。

计费与重复下载

下载接口按请求计费:

  • 一次请求选择多个格式只收取一次费用
  • 再次提交同一首歌曲,即使格式相同,也会产生新费用
  • 下载另一种格式需要新建任务,也会产生新费用
  • 下载失败会自动退款

请保存已返回的文件 URL,并在请求处理中禁用下载按钮,避免重复提交和重复扣费。

从旧接口迁移

项目 旧接口 新接口
请求路径 /v1/music/generations/wav /v1/music/generations/download
格式 仅 WAV MP3 / M4A / WAV,可多选
新增参数 — formats 或 format
结果字段 result.wavUrl result.files[]
兼容字段 result.wavUrl 请求 WAV 时仍可能返回 result.wavUrl

旧接口仍可暂时使用,但新功能和新代码应切换到 /generations/download。

Response

codeinteger

响应状态码,成功时为 200

dataarray

提交响应数据。

This documentation is built and hosted on Mintlify, a developer documentation platform.

© 2026 26j.cn · AI 模型中转站