영감 모드 생성 API

2026-09-18 업데이트 · Suno-API 팀

인터페이스 설명

영감 모드 생성은 한 문장 설명으로 완성된 곡을 만드는 데 적합합니다. 시스템이 설명을 바탕으로 가사, 멜로디, 편곡, 보컬을 자동으로 생성합니다.

엔드포인트: POST /api/music/create

과금: 유료, 현재 기본 1회 0.6위안. 보통 1회 호출에 2곡이 반환되며, 실제 청구 금액은 현재 백오피스 가격 설정을 따릅니다.

Max Mode / Variety: 이 엔드포인트는 선택 파라미터 max_mode와 variety(0-4)를 지원합니다. max_mode를 켜면 이번 호출은 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는 이번 생성에 "참고 자료"를 붙이는 배열입니다. 생략할 수 있으며(생략하면 기존과 완전히 동일하게 동작), 한 종류만 붙이거나 임의로 조합할 수 있습니다.

요소 타입

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를 전송합니다

규칙

예시: 참고 곡 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": "이 영감들을 한 곡으로 합쳐 주세요",
    "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초까지 기다릴 수 있습니다. 클라이언트가 긴 연결에 적합하지 않다면 접수 영수증 모드를 켤 수 있습니다. 둘 중 하나만 하면 됩니다:

켜면 이 엔드포인트는 즉시 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 두 곡 중 하나가 완료됨
completed 두 곡 모두 완료되어 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

호환성과 주의 사항

다음 단계

응답 시점에 곡이 아직 완료되지 않았다면 곡 조회 API로 최종 결과를 조회하세요.

Node/Electron 연동 사례

Electron 메인 프로세스, Node.js 서버, 데스크톱 클라이언트에서 일반 생성을 연동할 때는 아래 흐름을 권장합니다:

  1. POST /api/music/create를 호출해 생성 작업을 만듭니다.
  2. 응답에서 song_id 또는 id를 읽습니다.
  3. 2초마다 POST /api/music/query를 호출해 상태를 조회합니다.
  4. 조회 결과에 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를 서버 환경 변수, 데스크톱 클라이언트 설정 또는 안전한 저장소에 두고, 프런트엔드 코드에 넣거나 저장소에 커밋하지 마세요.

다음프로 모드 생성 API

API 키 발급

가입 후 콘솔에서 API 키를 만들 수 있습니다. 1회 0.6위안으로 2곡이 생성되고, 다운로드는 횟수 제한이 없으며 휴대폰 번호는 필요하지 않습니다.

API 키 받기 개요로 돌아가기