ひらめきモード生成 API
インターフェースの説明
ひらめきモード生成は、ひとことの説明から完成した楽曲を作るのに向いています。システムが説明をもとに歌詞・メロディ・編曲・歌唱を自動で生成します。
エンドポイント: POST /api/music/create
課金: 有料、現在は既定で 1 回 0.6 元。通常は 1 回につき 2 曲が返ります。実際の請求額は現在の管理画面の価格設定に従います。
Max Mode / Variety: 本エンドポイントは任意パラメータ max_mode と variety(0〜4)に対応しています。
max_mode を有効にするとこの1回は 2 倍の価格で課金され(0.6 → 1.2 元/回)、variety に追加課金はありません。
両者の意味と書き方は新版 API 概要の「高度なパラメータ」の節をご覧ください。
推奨モデル: suno-v6
待ち時間とタイムアウト(重要): 本エンドポイントは同期インターフェースで、レスポンスが返った時点で初めて注文が受理され生成に投入されます。実測では多くのリクエストが 1〜3 秒で返り、約 10% が 30 秒を超え、最長は約 230 秒です。クライアントのタイムアウトは 300 秒以上に設定してください。レスポンスが無いことは未生成を意味せず、タイムアウト直後の再試行は注文の重複と二重課金につながります。 接続が切れた場合は少し後に
GET /api/music/songsで確認できます。詳しくは新版 API 概要の「待ち時間とタイムアウト設定」をご覧ください。
リクエストパラメータ
Headers
| パラメータ名 | 型 | 必須 | 説明 |
|---|---|---|---|
| Authorization | string | はい | Bearer YOUR_API_KEY |
| Content-Type | string | はい | application/json |
Body パラメータ
| パラメータ名 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| description | string | はい | - | 楽曲の説明。多言語対応。最大 3000 文字(超過は 400 を返し、課金されません) |
| model | string | いいえ | suno-v6 | 対客モデル名: suno-v6、suno-v6-wild、suno-v6-mini |
| instrumental | boolean | いいえ | false | インストゥルメンタル(純音楽)かどうか |
| wait_completion | boolean | いいえ | false | 生成完了まで待ってから返すかどうか |
| references | array | いいえ | - | 参考素材のリスト。参考楽曲 / 従来の音色 / 参考画像を指定できます。楽曲は最大 5 曲、音色は 1 つ、画像は 1 枚。下の「参考素材 references(任意)」を参照 |
リクエスト例
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "夏の海をテーマにした軽快な中国語ポップス",
"instrumental": false,
"wait_completion": false
}'
参考素材 references(任意)
references は今回の生成に「参考資料」を付ける配列です。省略できます(省略時は従来と完全に同じ動作)。1 種類だけでも、任意の組み合わせでも付けられます。
要素の種類
| type | 必須フィールド | 任意フィールド | 上限数 | 説明 |
|---|---|---|---|---|
song |
song_id |
style_prompt、lyrics、duration_s |
5 | 参考楽曲。song_id は楽曲照会と履歴 API が返す値を使い、楽曲は完了済みである必要があります |
voice |
voice_id |
- | 1 | 従来の音色(歌声)。voice_id は音声クローンと指定音声での生成 API から取得します |
image |
base64 |
- | 1 | 参考画像。data:image/jpeg;base64,... 形式の base64 を送ります |
ルール
- 参考楽曲の順序が意味の順序です:表現したい順に渡してください(例:「1 曲目のメロディ、2 曲目の歌声」)。
style_prompt/lyrics/duration_sはすべて省略可能で、プラットフォームが楽曲情報から補完します。指定した場合は指定が優先されます。- 純インストゥルメンタルの楽曲では
lyricsに""または"[Instrumental]"を渡せます。 - 参考画像は
jpeg/png/webpに対応し、1 枚 10MB 以下。base64 形式でリクエスト本文と一緒に送ります。 - 参考楽曲を複数付ける場合は、あわせて
accept_mode=async(上の「受理レシートモード」)の使用をおすすめします。サーバー側で参考素材の準備が必要なため、同期の待ち時間が長くなることがあります。
例:参考楽曲を 2 曲付ける
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "これらのひらめきを 1 曲にまとめる",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "song", "song_id": "a90438d2-35fc-4443-88f4-56531e6e5d24" }
]
}'
例:参考楽曲 + 従来の音色
{
"model": "suno-v6",
"description": "この音色でこのひらめきを歌う",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "voice", "voice_id": "5813cbe1-36f1-414a-a9a8-4d399dfeb292" }
]
}
例:参考楽曲 + 参考画像
{
"model": "suno-v6",
"description": "この画像の雰囲気を参考にする",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
パラメータエラー
次の場合は HTTP 400 を返し、課金前に弾かれるため費用は発生しません:
| 状況 | エラーメッセージ |
|---|---|
| 参考楽曲が 5 曲を超えた | references supports at most 5 song references |
| 音色が 1 つを超えた | references supports at most 1 voice reference |
| 参考画像が 1 枚を超えた | references supports at most 1 image reference |
type の値が不正 |
references[0].type must be one of song, voice, image |
楽曲に song_id が無い |
references[0].song_id is required |
| 楽曲がまだ完了していない | references[0].song_id must be a real completed clip |
| 同じ楽曲を重複して指定した | references[0].song_id is duplicated |
references[0]の数字は配列内のその要素の添字で、どの項目がエラーかを特定しやすくしています。
レスポンス
楽曲の配列を返し、通常は 2 件のタスクまたは楽曲を含みます。
[
{
"song_id": "clip_id",
"song_title": "夏の海風",
"status": "pending",
"description": "夏の海をテーマにした軽快な中国語ポップス",
"audio_url": "",
"cover_url": "",
"video_url": "",
"model_version": "suno-v6",
"generation_type": "generate",
"created_at": "2026-05-21T10:00:00Z"
}
]
受理レシートモード(任意。長い接続を持ちたくないクライアントに推奨)
既定では本エンドポイントは同期です。レスポンスが返った時点で注文が受理されたことを意味し、実測では最長で約 230 秒待つことがあります。 クライアントが長い接続に適さない場合は受理レシートモードを有効にできます。次のどちらか一方で構いません:
- リクエスト本文に
"accept_mode": "async"を追加する - リクエストヘッダに
X-Accept-Mode: asyncを追加する
有効にすると本エンドポイントはただちに HTTP 202 を返します。これは「受理済みで生成キューに入った」ことだけを意味し、生成はバックグラウンドで続きます:
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "queued",
"accepted_at": 1789896434,
"pre_consumed_quota": 300000,
"tasks": [
{ "index": 0, "status": "queued" },
{ "index": 1, "status": "queued" }
]
}
}
受理段階では
song_idは返りません。 この時点で実在する楽曲 ID は無く、request_idもtasks[].indexも楽曲 ID ではありません。song_idとして保存しないでください。実際のsong_idは 下の進捗照会に現れます。
受理の進捗を照会する
エンドポイント:GET /api/music/requests/{request_id}(無料。同じ API Key で認証します)
curl "https://www.suno-api.io/api/music/requests/ac_20260920092714315816800d76fv3nq" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "processing",
"tasks": [
{ "index": 0, "status": "processing", "song_id": "f3fa09f5-3d55-4953-826c-0d23f043ec57" },
{ "index": 1, "status": "processing", "song_id": "5fcafe3e-3fae-4d64-8f66-c01bc027b0c3" }
]
}
}
status の値と意味:
| status | 意味 |
|---|---|
queued |
受理済み。まだ具体的な楽曲に紐づいていない(tasks が空配列のことがあります) |
processing |
生成に投入済み |
partial |
2 件のうち 1 件が完了 |
completed |
2 件とも完了し、tasks[].song_id が読める |
failed |
投入に失敗。費用は全額返金済みで、error_message に理由が出ます |
各タスクには独自の tasks[].status もあり、値は楽曲照会 API と同じです:
pending(投入済み・生成中)、processing、completed、failed。タスク項目には title、
duration、すでに登録済みの audio_url が含まれることもあります。無ければまだ生成されていないだけです。
実際の song_id を取得したら、あとは楽曲照会 API やダウンロード用エンドポイントで続けられます。
Python の例
import time
import requests
BASE = "https://www.suno-api.io"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}
accepted = requests.post(
f"{BASE}/api/music/create",
headers={**HEADERS, "Idempotency-Key": "your-own-unique-key"},
json={"description": "軽快なポップス", "model": "suno-v6", "accept_mode": "async"},
timeout=300,
).json()["data"]
request_id = accepted["request_id"]
while True:
time.sleep(5)
progress = requests.get(
f"{BASE}/api/music/requests/{request_id}", headers=HEADERS, timeout=60
).json()["data"]
if progress["status"] in ("completed", "failed"):
print(progress)
break
互換性と注意点
accept_modeを付けない場合、動作は従来と完全に同じです:同期で待ち、200と楽曲配列を返します。既存の接続側はコード変更が不要です。- このスイッチは現在
POST /api/music/createとPOST /api/music/create/customでのみ有効で、他の生成系エンドポイントは未対応です。 Idempotency-Key(自分で決める一意な文字列、128 文字以下)もあわせて送ることをおすすめします。同じキーの再送は 1 回だけ受理され、再送時は同じレシートが返り、二重課金になりません。非同期モードでは特に重要です。accept_mode=asyncのときwait_completionは無視されます(レシートが即座に返り、楽曲の完成は待ちません)。- 費用は受理時に前受金として差し引かれます。生成失敗時は全額が自動で返金されます。
- テキストフィールドの上限:
descriptionは最大 3000 文字(Unicode 文字で数え、漢字 1 字は 1 と数えます)。超過はただちに HTTP400を返し、生成にも入らず課金もされません。エラーメッセージには実測文字数が入ります。例:description must not exceed 3000 characters; received 4120。本エンドポイントに歌詞・スタイルのフィールドはありません。それらを使う場合はプロモード生成 APIの「テキストフィールドの上限」をご覧ください。共通の決まりは新版 API 概要の「テキストフィールドの上限」にあります。 referencesを付けない場合、動作・価格・レスポンスは従来と完全に同じです:既存の接続側はコード変更が不要です。- 参考素材を付ける場合(特に参考楽曲が複数の場合)は、同期の長時間待ちを避けるため
accept_mode=asyncの受理レシートモードへの切り替えをおすすめします。参考素材の準備時間は素材の数と取得元によって変わります。
次のステップ
レスポンス時に楽曲がまだ完成していない場合は、楽曲照会 API で最終結果を取得してください。
Node/Electron での接続例
Electron のメインプロセス、Node.js サーバー、デスクトップクライアントで通常の生成を接続する場合は、次の流れをおすすめします:
POST /api/music/createを呼び出して生成タスクを作成します。- レスポンスから
song_idまたはidを読み取ります。 - 2 秒ごとに
POST /api/music/queryを呼び出して状態を確認します。 - 照会結果に
audio_urlが現れたら生成完了とみなします。
古いパス POST /api/generate や GET /api/clip?id=... は使わないでください。これらは現在推奨している公開接続経路ではありません。
const http = require('http');
const https = require('https');
const BASE_URL = 'https://www.suno-api.io';
const MODEL = 'suno-v6';
const POLL_INTERVAL_MS = 2000;
const MAX_POLL_ATTEMPTS = 60;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function requestJson(urlString, apiKey, body) {
const url = new URL(urlString);
const transport = url.protocol === 'https:' ? https : http;
const payload = JSON.stringify(body);
return new Promise((resolve, reject) => {
const req = transport.request(
{
method: 'POST',
hostname: url.hostname,
port: url.port || undefined,
path: `${url.pathname}${url.search}`,
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
},
(res) => {
let raw = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
raw += chunk;
});
res.on('end', () => {
const data = raw ? JSON.parse(raw) : {};
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(`Suno API request failed: HTTP ${res.statusCode} ${raw}`));
return;
}
resolve(data);
});
}
);
req.on('error', reject);
req.write(payload);
req.end();
});
}
function getPayload(response) {
return response && response.data !== undefined ? response.data : response;
}
function toSongList(payload) {
if (Array.isArray(payload)) return payload;
if (Array.isArray(payload?.songs)) return payload.songs;
if (Array.isArray(payload?.clips)) return payload.clips;
return payload ? [payload] : [];
}
function collectSongIds(createResponse) {
return toSongList(getPayload(createResponse))
.map((song) => song.song_id || song.id)
.filter(Boolean);
}
async function generateSunoSong({ apiKey, description, instrumental = false }) {
const createResponse = await requestJson(`${BASE_URL}/api/music/create`, apiKey, {
description,
model: MODEL,
instrumental,
wait_completion: false,
});
const songIds = collectSongIds(createResponse);
if (songIds.length === 0) {
throw new Error(`Suno API did not return song ids: ${JSON.stringify(createResponse)}`);
}
for (let attempt = 0; attempt < MAX_POLL_ATTEMPTS; attempt += 1) {
await sleep(POLL_INTERVAL_MS);
const queryResponse = await requestJson(`${BASE_URL}/api/music/query`, apiKey, {
song_ids: songIds,
model: MODEL,
});
const songs = toSongList(getPayload(queryResponse));
const completed = songs.find((song) => song.audio_url);
if (completed) {
return {
audioUrl: completed.audio_url,
title: completed.song_title || completed.title || 'Suno Song',
duration: completed.duration,
};
}
const allFailed = songs.length > 0 && songs.every((song) =>
['failed', 'error', 'rejected'].includes(String(song.status || '').toLowerCase())
);
if (allFailed) {
throw new Error(`Suno generation failed: ${JSON.stringify(songs)}`);
}
}
throw new Error('Suno generation timed out after 120 seconds. Please query again later.');
}
// Usage:
// generateSunoSong({
// apiKey: process.env.SUNO_API_KEY,
// description: 'A bright pop song about the ocean in summer',
// }).then(console.log).catch(console.error);
実際のプロジェクトでは API Key をサーバーの環境変数、デスクトップクライアントの設定、または安全なストレージに置き、フロントエンドのコードに書いたりリポジトリにコミットしたりしないでください。