SDK
安装内置类型定义的 RunAPI SDK,使用 API Key 完成身份验证,并为应用选择合适的任务处理方式。
RunAPI SDK 为 JavaScript、Python、PHP、Java、Ruby 和 Go 提供内置类型定义的模型客户端。请按应用使用的模型系列和编程语言选择对应的软件包。
安装模型 SDK
安装与语言和模型系列匹配的软件包。例如,安装 Suno JavaScript SDK:
npm install @runapi.ai/[email protected]
同一模型系列可通过每个受支持运行时的软件包管理器安装:
pip install runapi-suno==0.4.3
composer require runapi-ai/suno:0.3.1
gem install runapi-suno --version 0.4.3
go get github.com/runapi-ai/suno-sdk/[email protected]
Java 可通过 Gradle 或 Maven 添加 Suno 模块:
dependencies {
implementation("ai.runapi:runapi-suno:0.3.2")
}
<dependency>
<groupId>ai.runapi</groupId>
<artifactId>runapi-suno</artifactId>
<version>0.3.2</version>
</dependency>
验证客户端
创建客户端前,在环境中设置 RUNAPI_API_KEY。SDK 使用 RunAPI API Key,并与 REST 请求和 CLI 工作流使用同一个账户上下文。
export RUNAPI_API_KEY="runapi_..."
请在身份验证指南中创建和轮换密钥。请将密钥保存在密钥管理服务中,而不是应用源码中。
使用 Files 与 Uploads
每个模型客户端都通过核心软件包提供持久文件资源 files 和分片上传资源 uploads。现有的 files.create 方法仍用于创建临时 URL;创建持久文件对象时,JavaScript、Java 和 PHP 使用 files.createFile,Python 和 Ruby 使用 files.create_file,Go 使用 Files.CreateFile。
const file = await client.files.createFile({
file: new Blob([fileBytes], { type: "application/pdf" }),
filename: "knowledge.pdf",
purpose: "user_data",
});
const bytes = await client.files.content(file.id);
await client.files.deleteFile(file.id);
将文件拆分为多个分片上传时,使用 uploads.create、addPart、complete 和 cancel。Python 和 Ruby 使用 add_part,Go 使用 AddPart。限制、REST 示例和完整生命周期请查看 Files 与 Uploads。
同步转写音频
OpenAI Transcription SDK 上传本地音频文件,并在同一次请求中返回完整转写结果。JSON 响应格式返回对应语言的原生对象;text、SRT 与 VTT 格式返回未经改写的响应字符串。
import { OpenaiTranscriptionClient } from "@runapi.ai/openai-transcription";
const client = new OpenaiTranscriptionClient();
const transcript = await client.speechToText.run({
file: new Blob([audioBytes], { type: "audio/mpeg" }),
filename: "interview.mp3",
response_format: "json",
});
文件格式、模型专属字段与响应格式请查看音频转写 API 参考。
处理异步 Task
许多媒体操作是异步的。使用 create 提交 Task 并立即取得 id,使用 get 获取当前状态,或使用 run 提交后持续轮询,直到 Task 到达终态。在 Web 请求处理程序中,请优先使用 create 加 callback 或之后的 get 轮询,避免请求持续占用 worker。
JavaScript
import { SunoClient } from "@runapi.ai/suno";
const client = new SunoClient();
const result = await client.textToMusic.run({
model: "suno-v5",
vocal_mode: "auto_lyrics",
prompt: "A short piano theme",
});
console.log(result.audios[0].audio_url);
Python
from runapi.suno import SunoClient
client = SunoClient()
result = client.text_to_music.run(
model="suno-v4.5-plus",
vocal_mode="auto_lyrics",
prompt="A short piano theme",
)
print(result.audios[0].audio_url)
PHP
<?php
use RunApi\Suno\SunoClient;
$client = new SunoClient();
$result = $client->textToMusic->run([
'model' => 'suno-v5.5',
'vocal_mode' => 'auto_lyrics',
'prompt' => 'A short piano theme',
]);
print_r($result->toArray());
Ruby
require "runapi/suno"
client = RunApi::Suno::Client.new
result = client.text_to_music.run(
model: "suno-v4.5-plus",
vocal_mode: "auto_lyrics",
prompt: "A short piano theme"
)
puts result.dig("audios", 0, "audio_url")
Go
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/runapi-ai/core-sdk/go/option"
"github.com/runapi-ai/suno-sdk/go/suno"
)
func main() {
client, err := suno.NewClient(option.WithAPIKey(os.Getenv("RUNAPI_API_KEY")))
if err != nil {
log.Fatal(err)
}
result, err := client.TextToMusic.Run(context.Background(), suno.TextToMusicParams{
SunoBaseParams: suno.SunoBaseParams{Model: suno.ModelV45Plus},
VocalMode: suno.VocalModeAutoLyrics,
Prompt: "A short piano theme",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.ID)
}
Java
import ai.runapi.suno.SunoClient;
import ai.runapi.suno.types.CompletedTextToMusicResponse;
import ai.runapi.suno.types.TextToMusicModel;
import ai.runapi.suno.types.TextToMusicParams;
SunoClient client = SunoClient.builder()
.apiKey(System.getenv("RUNAPI_API_KEY"))
.build();
CompletedTextToMusicResponse result = client.textToMusic().run(
TextToMusicParams.builder()
.model(TextToMusicModel.SUNO_V5)
.vocalMode("auto_lyrics")
.prompt("A short piano theme")
.build()
);
复用 Style Persona
从公开音频 URL 创建 Style Persona,再把返回的 persona.id 复用于四个支持的音乐操作。persona_type: "style" 用于复用风格和情绪特征;它不保证克隆源录音的原声、无损保留源音频风格,也不保证与源音频达到特定相似度。
import { SunoClient } from "@runapi.ai/suno";
const client = new SunoClient();
const referenceAudioUrl = "https://cdn.runapi.ai/public/samples/music.mp3";
const sampled = await client.addSamples.run({
model: "suno-v5",
audio_url: referenceAudioUrl,
start_seconds: 0,
end_seconds: 30,
});
const sourceAudioId = sampled.audios?.[0]?.id;
if (!sourceAudioId) throw new Error("采样 Task 未返回 audio ID");
const { persona } = await client.generatePersona.run({
task_id: sampled.id,
audio_id: sourceAudioId,
name: "Studio Style",
description: "A warm and expressive acoustic pop style.",
});
const textToMusic = await client.textToMusic.run({
model: "suno-v5",
vocal_mode: "auto_lyrics",
prompt: "An uplifting acoustic pop song about a rainy city night",
persona_id: persona.id,
persona_type: "style",
});
const coverAudio = await client.coverAudio.run({
model: "suno-v5",
upload_url: referenceAudioUrl,
vocal_mode: "auto_lyrics",
prompt: "Rework the reference track as acoustic pop",
persona_id: persona.id,
persona_type: "style",
});
const createMashup = await client.createMashup.run({
model: "suno-v5",
upload_url_list: [
referenceAudioUrl,
"https://cdn.runapi.ai/public/samples/audio-2.mp3",
],
vocal_mode: "auto_lyrics",
prompt: "Blend both tracks into an energetic acoustic pop mashup",
persona_id: persona.id,
persona_type: "style",
});
const extendMusic = await client.extendMusic.run({
model: "suno-v5",
upload_url: referenceAudioUrl,
parameter_mode: "custom",
instrumental: false,
prompt: "Continue the arrangement with a brighter chorus",
style: "Acoustic pop with warm piano",
title: "Brighter Chorus",
continue_at: 60,
persona_id: persona.id,
persona_type: "style",
});
console.log({
textToMusic: textToMusic.audios[0]?.audio_url,
coverAudio: coverAudio.audios[0]?.audio_url,
createMashup: createMashup.audios[0]?.audio_url,
extendMusic: extendMusic.audios[0]?.audio_url,
});
选择下一步工作流
当应用需要带类型定义的请求构造器和对应语言的任务辅助方法时,使用 SDK。对于 shell 自动化、本地检查和回调调试,请使用 RunAPI CLI。精确的请求字段、任务响应与错误请查看 API 参考。