Tài liệu
Tạo nhạc
Chuyển văn bản thành nhạc bằng Suno V5 / V5.5 — điều khiển giọng hát, lời bài hát và phong cách. Có hai dạng API: điểm cuối đồng bộ một lần chờ cho đến khi các bản nhạc sẵn sàng, và cặp API bất đồng bộ kiểu gửi yêu cầu rồi thăm dò (có webhook ký số) dành cho môi trường production.
Các điểm cuối: POST /v1/audio/music (đồng bộ, trình bày trước), và POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id} (bất đồng bộ, khuyến nghị cho production). Mỗi yêu cầu tạo ra hai bản nhạc; quá trình tạo mất khoảng 1–3 phút. Giá: $0.09 cho mỗi yêu cầu tạo trên suno-v5, $0.09 trên suno-v5-5 — tính phí một lần cho cả hai bản nhạc, trừ từ số dư trả trước; lần tạo thất bại sẽ không bị tính phí.
Bắt đầu nhanh (đồng bộ)
Gửi một prompt và model Suno. Yêu cầu sẽ chờ cho đến khi cả hai bản nhạc sẵn sàng, sau đó trả về URL vĩnh viễn của chúng.
import os
import requests
API_KEY = os.environ["KUNAVO_API_KEY"]
# Synchronous: one request blocks until the tracks are ready (1-3 min).
resp = requests.post(
"https://api.kunavo.com/v1/audio/music",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "suno-v5",
"prompt": "upbeat lofi hip hop for late-night coding, mellow piano",
"instrumental": True,
},
timeout=600, # generation can take a few minutes
)
# Suno returns ~2 tracks per request.
for track in resp.json()["data"]:
print(track["url"], track.get("image_url"))Hàm fetch tích hợp sẵn của Node ngừng chờ header phản hồi sau 300 giây, bất kể bạn đặt thời gian chờ là bao nhiêu: khi gọi từ Node, hãy dùng API bất đồng bộ, hoặc gọi hàm fetch từ gói undici với tùy chọn dispatcher: new Agent({ headersTimeout: 600_000 }).
Tham số
| Tham số | Loại | Ghi chú |
|---|---|---|
model | string (bắt buộc) | Slug model nhạc — suno-v5 hoặc suno-v5-5. |
prompt | string (bắt buộc) | Mô tả nhạc (hoặc lời bài hát ở chế độ tùy chỉnh). |
instrumental | bool | true = không có giọng hát. Mặc định là false. |
customMode | bool | Chế độ Suno nâng cao — điều khiển rõ ràng cấu trúc / lời bài hát / phong cách. |
style | string | Gợi ý phong cách / thể loại, ví dụ "lofi, jazz, chill". |
title | string | Tiêu đề bản nhạc. |
webhook_url | string (https) | Chỉ dành cho API bất đồng bộ — gửi sự kiện kết thúc có chữ ký đến đây. Xem Webhooks. |
Model nhạc
| Slug | Nhà cung cấp | Ghi chú |
|---|---|---|
suno-v5 | Suno | Suno V5 — giọng hát, lời bài hát, pha trộn phong cách. |
suno-v5-5 | Suno | Suno V5.5 — phiên bản mới nhất, độ trung thực cao hơn và thời lượng tạo dài hơn. |
Kiểm tra /models để xem danh sách hiện hành và giá cho từng lệnh gọi.
API bất đồng bộ (gửi yêu cầu + thăm dò)
Các điểm cuối: POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id}. Cách hoạt động tương tự API video bất đồng bộ, nên cùng một mã thăm dò / webhook dùng được cho cả hai loại nội dung.
Điểm cuối đồng bộ giữ kết nối HTTP mở trong nhiều phút — tiện cho tập lệnh nhưng không đáng tin cậy trên mạng di động. Cặp API bất đồng bộ trả về ngay một ID msc_*; bạn thăm dò GET /v1/audio/music/jobs/{id} cho đến khi status là completed hoặc failed. Cùng model, cùng mức giá, cùng URL CDN vĩnh viễn.
import os
import time
import requests
API_KEY = os.environ["KUNAVO_API_KEY"]
# 1. Submit — returns immediately with a msc_ task id. No long-lived connection.
submit = requests.post(
"https://api.kunavo.com/v1/audio/music/jobs",
headers={
"Authorization": f"Bearer {API_KEY}",
# Optional: a repeat under the same key returns the original task
# rather than submitting again. A new task needs a new key.
"Idempotency-Key": "my-song-uuid",
},
json={
"model": "suno-v5",
"prompt": "dreamy synthwave with a driving bassline",
"title": "Midnight Drive",
},
timeout=60,
).json()
task_id = submit["id"] # "msc_abc..."
status = submit["status"] # "queued"
# 2. Poll until terminal. Recommended cadence: 5s, backing off to 30s.
while status not in ("completed", "failed"):
time.sleep(5)
r = requests.get(
f"https://api.kunavo.com/v1/audio/music/jobs/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
).json()
status = r["status"]
if status == "failed":
raise RuntimeError(r["error"]["message"])
for track in r["output"]["tracks"]:
print(track["url"])Cấu trúc phản hồi
| Trường | Loại | Ghi chú |
|---|---|---|
id | string | ID tác vụ có tiền tố msc_. |
object | string | "music". |
status | string | đang chờ | đang xử lý | đã hoàn tất | thất bại. |
model | string | Slug model bạn đã gửi. |
created_at | int | Thời điểm Unix tính bằng giây khi chúng tôi chấp nhận yêu cầu. |
completed_at | int | null | Thời điểm Unix tính bằng giây khi tác vụ kết thúc — null khi đang chờ. |
expires_at | int | Giây Unix, 30 ngày sau khi gửi: có thể truy vấn tác vụ ít nhất cho đến lúc đó. URL kết quả của tác vụ không hết hạn. |
progress | int | Bằng 0 cho đến khi tác vụ kết thúc, sau đó là 100. |
output | object | null | {tracks[], archived} khi hoàn tất. |
output. | array | Mỗi mục: {url, stream_url, image_url}. url / image_url là các liên kết CDN vĩnh viễn. |
error | object | null | {code, message} khi thất bại. |
Tiêu đề và quy ước
Idempotency-Key(không bắt buộc, ≤128 ký tự) — gửi hai lần cùng khóa trên một tài khoản sẽ trả về tác vụ ban đầu thay vì tạo tác vụ trùng lặp.- Một khóa idempotency ứng với một yêu cầu: khóa đã được dùng để bắt đầu một tác vụ trên endpoint khác, cho model khác, hoặc cho một yêu cầu có prompt khác hay tham số khác sẽ bị từ chối với lỗi 400. Khóa dài hơn 128 ký tự và khóa được gửi kèm một yêu cầu đồng bộ cũng vậy. URL hình ảnh không được so sánh: yêu cầu dùng URL được ký lại vẫn là cùng một yêu cầu.
POST /v1/audio/music/jobstrả về 202 Accepted khi gửi tác vụ mới và 200 OK khi khóa idempotency phát lại một kết quả.GETđược giới hạn theo chủ sở hữu: truy vấn tác vụ thuộc tài khoản khác sẽ trả về 404.- Nhịp thăm dò được khuyến nghị: 5 s, tăng dần đến 30 s.
Webhook
Gửi webhook_url (https) khi tạo tác vụ; ngay khi tác vụ kết thúc, Kunavo sẽ POST sự kiện music.completed / music.failed có chữ ký đến đó — gửi kèm cơ chế thử lại với thời gian chờ tăng dần. Trường data của sự kiện chính xác là nội dung phản hồi GET ở trên.
# Pass webhook_url on submit to be pushed a signed event on terminal —
# instead of (or alongside) polling:
# {"model": "suno-v5", "prompt": "...", "webhook_url": "https://you.com/hook"}
#
# Verify the HMAC signature on your receiver (Flask shown):
import hmac, hashlib
from flask import request, abort
# secret: your account's webhook secret ("kwh_..."), from Settings → Webhooks
# in the dashboard. Keep it out of your code: read it from the environment.
def verify(secret: str) -> dict:
ts = request.headers["X-Kunavo-Webhook-Timestamp"]
sig = request.headers["X-Kunavo-Webhook-Signature"] # "sha256=<hex>"
raw = request.get_data(as_text=True)
expected = "sha256=" + hmac.new(
secret.encode(), f"{ts}.{raw}".encode(), hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, sig):
abort(401)
return request.get_json()
# Event body:
# { "id": "evt_...", "object": "event",
# "type": "music.completed" | "music.failed",
# "created_at": 1700000000,
# "data": { ...the GET /v1/audio/music/jobs/{id} payload... } }Nếu webhook_url không phải là URL https, hoặc có chứa tên người dùng hay mật khẩu, yêu cầu sẽ bị từ chối với lỗi 400, và không có gì được tạo ra hay bị tính phí.
Khóa bí mật webhook của bạn nằm trong bảng điều khiển, tại Cài đặt → Webhooks. Khóa này bắt đầu bằng kwh_, và cùng một khóa bí mật được dùng để ký mọi sự kiện hình ảnh, video và nhạc của tài khoản bạn. Bạn có thể thay khóa tại đó; mọi sự kiện được gửi sau khi thay khóa, kể cả các lần thử lại, đều được ký bằng khóa bí mật mới.
HMAC-SHA256 trên {timestamp}.{rawBody}, được gửi dưới dạng X-Kunavo-Webhook-Signature: sha256=<hex>. Cách làm giống webhook video, nên một bộ xác minh xử lý được cả hai.Khi nào nên dùng model nào
| Đồng bộ /v1/ | Bất đồng bộ /v1/ | |
|---|---|---|
| Phù hợp nhất cho | Tập lệnh dùng một lần, notebook | Production, ứng dụng di động, webhook |
| Mạng | Giữ kết nối mở trong 1-3 phút | Gửi trong vài giây; thăm dò hoặc nhận dữ liệu được đẩy về |
| Khôi phục sau sự cố | Mất phản hồi = mất kết quả | Truy vấn lại ID bất kỳ lúc nào trước khi expires_at hết hạn |
| Webhook | — | Sự kiện music. |
Phản hồi và lưu trữ
url (âm thanh) và image_url (ảnh bìa) của mỗi bản nhạc là các liên kết vĩnh viễn files.kunavo.com — Kunavo lưu trữ mọi kết quả trên CDN riêng, nên khác với URL Suno gốc, chúng không bao giờ hết hạn. stream_url là liên kết phát trực tuyến gốc của Suno (tiện để phát ngay). Mỗi bản nhạc cũng xuất hiện trong /app/assets.
output.archived sẽ là false và URL sẽ chuyển về các liên kết tạm thời của Suno (hết hạn sau khoảng 24h) — trong trường hợp đó, hãy tự lưu trữ lại.