【Recomendado】 API de perfil de voz
✅ Se recomienda esta cadena para integraciones nuevas. Según las evaluaciones reales de muchos usuarios, las canciones generadas con esta cadena conservan muy bien la voz original: la voz de la pista final se parece más a la persona de la muestra que subiste, así que es la ruta que recomendamos actualmente a los clientes.
Comparación: la API de clonación de voz y generación con voz anterior sigue funcionando, pero el menú la marca como "no recomendado" y ya no se recomienda para integraciones nuevas.
- Fecha del documento: 2026-09-26
- Capacidades cubiertas: crear tu propia voz → usarla para versionar una canción concreta / cantar una canción nueva → consultar el progreso → descargar los resultados
- Todos los endpoints, campos y respuestas se han verificado con llamadas reales (lo marcado como "medido" se verificó en detalle)
Nota: este documento solo describe los endpoints que tienes que llamar. El tratamiento de materiales, la planificación de tareas y la validación de contenido los hace el servidor automáticamente; el cliente no los implementa.
0. Empezar en cinco minutos
Con cuatro pasos obtienes dos canciones terminadas a partir de una muestra vocal.
① Crear la voz POST /api/music/voice-profile/create → obtienes voice_id (status=ready)
② Versionar POST /api/music/voice-profile/cover → obtienes 2 song_id al momento
③ Consultar POST /api/music/query → sondea hasta status=completed
④ Descargar GET /api/music/download?song_id=…&kind=mp3
Ejemplo mínimo (curl):
API_KEY="sk-tu-clave"
BASE="https://www.suno-api.io"
# ① Crear la voz (sube una muestra vocal; se recomiendan 10 s o más y menos de 10 MB)
curl -sS -X POST "$BASE/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@./my-voice.mp3" \
-F "title=Mi voz" \
-F "source_kind=upload"
# → {"success":true,"message":"","data":{"voice_id":"vp_2026…","status":"ready", …}}
# ② Versionar una canción con esa voz (song_clip_id = el clip id de la canción a versionar)
curl -sS -X POST "$BASE/api/music/voice-profile/cover" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Create-Ui-Client-Request-Id: cover-$(date +%s)" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"voice_id": "vp_2026…",
"song_clip_id": "5b773e9a-…",
"lyrics": "[Verse 1]\ntexto de la letra…",
"style_requirements": "folk lento, guitarra acústica",
"audio_weight": 0.85,
"max_mode": false
}'
# → {"code":200,"message":"success","data":{"resolved_scene":"cover","clips":[{…},{…}]}}
# ③ Sondear (envía varios ids a la vez, separados por comas)
curl -sS -X POST "$BASE/api/music/query" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"suno-v6","song_ids":"id1,id2"}'
# ④ Descargar el mp3 cuando termine (solo con status=completed obtienes archivo)
curl -sS -L "$BASE/api/music/download?song_id=id1&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song1.mp3
1. Convenciones comunes
1.1 Dominio y entorno
| Entorno | Base URL | Uso |
|---|---|---|
| Producción | https://www.suno-api.io |
Tráfico real de clientes |
Todas las rutas siguientes son relativas a la Base URL; por ejemplo, la dirección completa de POST /api/music/voice-profile/create es
https://www.suno-api.io/api/music/voice-profile/create.
1.2 Autenticación
Todos los endpoints usan la misma cabecera de petición, y su valor es la clave API que creaste en la consola:
Authorization: Bearer sk-xxxxxxxx
- El prefijo
Beareres opcional; el prefijosk-también (Authorization: sk-xxxfunciona igual). - Clave ausente o inválida → HTTP 401, con un cuerpo como
{"success":false,"message":"…"}(el texto varía según el idioma de la petición). - Cada clave solo puede ver y solo puede operar sobre las canciones y voces de su propia cuenta.
1.3 Formatos del cuerpo de la petición
- Crear una voz: se recomienda
multipart/form-data(subir un archivo); también se admiteapplication/json(una URL o base64). - El resto de endpoints:
application/json.
1.4 Dos envoltorios de respuesta (el cliente solo necesita conocer estos dos)
Los endpoints de "gestión de voces" (create / create-from-clip / list / detail / delete) usan el envoltorio de negocio:
{ "success": true, "message": "", "data": { } }
{ "success": false, "message": "voice_id is required" }
El "versionado con voz" pasa por el canal de generación y usa el envoltorio de generación: el éxito es code/message/data y el fallo un objeto error:
{ "code": 200, "message": "success", "data": { } }
{ "error": { "message": "voice not found: vp_xxx", "type": "bad_response_status_code", "param": "", "code": "bad_response_status_code" } }
Cómo decidir: mira primero el código de estado HTTP, luego success === false y por último code !== 200 o la presencia de error.
Un fallo de negocio no garantiza un HTTP distinto de 200 (los endpoints de gestión de voces siguen devolviendo HTTP 200 al fallar), así que no puedes guiarte solo por el código de estado.
1.5 Idempotencia
Crear una voz (incluido "crear desde audio existente") es realmente idempotente: bajo la misma clave, reenviar el mismo client_request_id crea una sola voz y el segundo intento devuelve directamente el primer resultado (success=true, el mismo voice_id). El uso previsto es que el cliente genere un id propio (un UUID, por ejemplo) y reutilice el mismo valor al reintentar tras un tiempo de espera agotado.
El envío de un versionado no deduplica a nivel de petición (es una generación facturable), así que ten en cuenta dos cosas:
- El identificador de envío va en la cabecera
X-Create-Ui-Client-Request-Id: <tu id de envío>. Se escribe en el registro de tareas del servidor para facilitar la investigación posterior; no evita un cargo duplicado. - Que se agote el tiempo de espera ≠ fallo: puede que la petición ya se haya aceptado y esté generando. Antes de reintentar, consulta
GET /api/music/songs?p=1&page_size=20(los parámetros de paginación sonp/page_size; la grafía compatiblepstambién sirve) para ver si ya ha aparecido una canción nueva congeneration_type=voice_profile_cover, y solo reenvía la misma petición si no es así.
Los cuerpos de create y create-from-clip también aceptan un campo client_request_id (ver §3 y §4).
1.6 Resumen de facturación
| Acción | Endpoint | Precio | Notas |
|---|---|---|---|
| Crear una voz (estándar) | POST /api/music/voice-profile/create |
Gratis | Subir una muestra no consume créditos de Suno |
| Crear una voz (desde audio existente) | POST /api/music/voice-profile/create-from-clip |
Gratis | El servidor solo registra una referencia al material; no se vuelve a subir nada |
| Clonación reforzada | Igual, enhanced=true |
Al "precio de subida reforzada" (10 ¥ por llamada por defecto) | Asíncrona; devolución automática si falla |
| Versionado con voz | POST /api/music/voice-profile/cover |
1,2 ¥ por llamada; 2,4 ¥ por llamada con max_mode=true |
Devuelve 2 canciones por llamada |
| Consultar / listar / detalle / eliminar | — | Gratis | |
| Descargar (tomar el enlace directo) | El audio_url de la respuesta |
Gratis | Reproduce/procesa la dirección que entregamos |
| Descargar (convertir a wav / letras, etc.) | POST /api/music/free2 |
0,2 ¥ por canción correcta | Ver §8 |
Los precios se pueden leer en cualquier momento desde un endpoint público, así que no los fijes en el código (ver §9):
curl -sS https://www.suno-api.io/api/pricing/catalog | jq '.data.catalog.meta'
# {
# "generation_price": "0.6",
# "voice_generation_price": "1.2", ← precio base del versionado con voz
# "max_mode_factor": "2",
# "enhanced_upload_price": "10", ← precio de la clonación reforzada
# "voice_auto_verify_price": "5",
# "voice_long_term_clone_price": "5"
# }
El versionado usa cargo previo + devolución si falla:
- Una petición rechazada (parámetros incorrectos, un 4xx/5xx de la plataforma, saldo insuficiente en sí) no se cobra: al enviar con una voz inexistente el saldo no cambió en absoluto en las pruebas (delta = 0);
- Una tarea aceptada que finalmente falla (incluido un error de servicio de la plataforma) pasa por la vía de devolución del servidor y devuelve el importe precargado.
1.7 Diccionario de estados
El status de la voz:
| Valor | Significado | Sirve para versionar |
|---|---|---|
ready |
Lista | ✅ |
processing |
Solo aparece en una clonación reforzada (enhanced=true); en proceso |
❌ (espera a ready) |
failed |
La creación falló; mira error_message; la clonación reforzada ya se devolvió |
❌ |
El status de la canción (el valor que devuelven los endpoints de consulta):
| Valor | Significado | Descargable |
|---|---|---|
submitted / queued / processing |
Generando (puede que ya exista un flujo de preescucha) | ❌ |
completed |
Terminada | ✅ |
failed |
Falló; el cargo se ha devuelto | ❌ |
2. Resumen de endpoints
| # | Método | Ruta | Función | Facturación |
|---|---|---|---|---|
| 1 | POST | /api/music/voice-profile/create |
Crear una voz (subida / URL / base64) | Gratis (salvo enhanced=true) |
| 2 | POST | /api/music/voice-profile/create-from-clip |
Crear una voz desde audio propio | Gratis |
| 3 | GET | /api/music/voice-profile/list |
Lista de voces | Gratis |
| 4 | GET | /api/music/voice-profile/{voice_id} |
Detalle de la voz (incluye el progreso de la clonación reforzada) | Gratis |
| 5 | POST | /api/music/voice-profile/delete |
Eliminar una voz | Gratis |
| 6 | POST | /api/music/voice-profile/cover |
Versionar con la voz / cantar una canción nueva | 1,2 ¥ (MAX 2,4) |
| 7 | POST | /api/music/query |
Consulta por lotes del estado de canciones | Gratis |
| 8 | GET | /api/music/songs/{song_id} |
Detalle de una canción | Gratis |
| 9 | GET | /api/music/download |
Descargar el archivo terminado | Gratis (mp3/enlace de reproducción) |
| 10 | POST | /api/music/free2 |
Convertir a wav / obtener letras, etc. | 0,2 ¥ por canción correcta |
| 11 | POST | /api/music/free2/cached |
Obtener una dirección de descarga ya archivada | Gratis |
| 12 | GET | /api/music/songs |
Mi lista de trabajos, paginada | Gratis |
3. Crear una voz
POST /api/music/voice-profile/create
Registra un fragmento de audio vocal como "voz" y obtén un voice_id. Para la plataforma una voz es simplemente "un audio + su clip en el catálogo", así que una vez creada con éxito ese audio de origen se conserva de forma permanente (para los versionados posteriores).
3.1 Tres formas de entrada (elige una)
Forma A: subida de archivo multipart (recomendada)
Content-Type: multipart/form-data
file=<binario de audio> # obligatorio
title=<nombre de la voz> # opcional; si va vacío se usa el nombre de archivo sin extensión
file_name=<nombre original del archivo>
source_file_name=<nombre original del archivo>
source_kind=upload|record # opcional, marca de origen (subida / grabación); por defecto upload
enhanced=false|true # opcional, true = clonación reforzada (ver §3.5)
client_request_id=<clave de idempotencia> # opcional
voice_id=<ID propio> # opcional, rara vez se usa
curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@./my-voice.mp3;type=audio/mpeg" \
-F "file_name=my-voice.mp3" \
-F "source_file_name=my-voice.mp3" \
-F "title=Mi voz" \
-F "source_kind=upload"
Forma B: JSON + una URL de audio pública
curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_url": "https://your-cdn.example.com/voice/my-voice.mp3",
"file_name": "my-voice.mp3",
"title": "Mi voz"
}'
- La URL debe ser un enlace directo HTTPS accesible públicamente; el servidor lo descarga una vez y lo guarda en nuestro almacenamiento de objetos.
- También puedes poner la dirección en el campo
audio_url, con el mismo efecto (si envías ambos, ganafile_url). - Cuando la dirección ya está en el almacenamiento de objetos de esta plataforma (
*.myqcloud.com/create-ui/voice-source/...) no se descarga de nuevo: se registra directamente.
Forma C: JSON + base64
{
"file_base64": "data:audio/mpeg;base64,//uQxAAA…",
"file_name": "my-voice.mp3",
"title": "Mi voz"
}
- Se admiten tanto el prefijo
data:audio/xxx;base64,como base64 puro. - El tamaño está limitado (base64 infla un 1,33×), así que usa la forma A para archivos grandes.
3.2 Requisitos del audio
| Elemento | Requisito | Notas |
|---|---|---|
| Tamaño | ≤ 10 MB | Por encima del límite la pasarela trunca el cuerpo, lo que se manifiesta como "rechazado por Suno"; comprime o recorta antes |
| Duración | Al menos 6 s; se recomiendan 10–60 s | Por debajo de 6 s la plataforma lo rechaza: Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
| Formato | mp3 / wav / m4a / aac / flac / ogg | Se decide por la extensión del archivo |
| Contenido | Voz limpia; evita versiones finales o canciones originales con acompañamiento | Un audio muy parecido a una grabación existente del catálogo se rechaza: This audio matches an existing recording in our catalog. (medido) |
3.3 Respuesta
{
"success": true,
"message": "",
"data": {
"voice_id": "vp_20260926080618509168500DXXrxe",
"clip_id": "91cc5935-389f-4193-b56b-cc796c15562d",
"song_id": "91cc5935-389f-4193-b56b-cc796c15562d",
"account_id": "acc_1790085275308",
"title": "Mi voz",
"source_file_name": "my-voice.mp3",
"audio_url": "https://suno-api-p-1437223057.cos.ap-guangzhou.myqcloud.com/create-ui/voice-source/2026/09/26/xxx.mp3",
"image_url": "https://cdn2.suno.ai/image_91cc5935-389f-4193-b56b-cc796c15562d.jpeg",
"duration_s": 29.18,
"enhanced": false,
"source_kind": "upload",
"status": "ready",
"client_request_id": "",
"created_at": 1790409978,
"updated_at": 1790409998
}
}
Referencia de campos (create / list / detail comparten el mismo conjunto de campos):
| Campo | Tipo | Notas |
|---|---|---|
voice_id |
string | El ID de voz; los versionados lo usan después |
clip_id / song_id |
string | El clip id de ese audio de voz en el lado de Suno (los dos son iguales); para diagnóstico |
account_id |
string | La cuenta que lo soporta (para diagnóstico; al cliente no le hace falta) |
title |
string | Nombre de la voz |
source_file_name |
string | Nombre original del archivo |
audio_url |
string | Enlace directo de largo plazo al audio de origen, utilizable para preescucha; se conserva de forma permanente |
image_url |
string | Portada de la voz (la que Suno genera para el audio vocal); cuando no hay portada la clave no aparece en absoluto |
duration_s |
number | Duración de la muestra de voz en segundos |
enhanced |
bool | Si se creó como clonación reforzada |
source_kind |
string | upload / record / clip (tomada de audio existente) |
status |
string | ready / processing / failed |
error_message |
string | Motivo del fallo; solo aparece con failed |
task_id |
number | Número de tarea subyacente de la clonación reforzada; solo tiene valor con enhanced=true |
pre_consumed_quota |
number | Cuota precargada (solo con clonación reforzada) |
created_at / updated_at |
number | Segundos Unix |
created_at/updated_atson marcas de tiempo en segundos (10 dígitos), no milisegundos.
3.4 Errores habituales
| HTTP | message | Causa y tratamiento |
|---|---|---|
| 200 | one of file_path, file_base64, or file_url is required |
No se incluyó contenido de audio |
| 200 | Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
La muestra es demasiado corta; usa ≥6 s (≥10 s recomendado) |
| 200 | This audio matches an existing recording in our catalog. |
La muestra se parece mucho a una grabación existente del catálogo; usa una voz seca distinta y limpia |
| 200 | upload succeeded without clip or account identity |
La respuesta de la plataforma fue anómala; reintenta |
| 200 | audio file exceeds 30 MB limit |
Supera el límite del servidor (de cara al cliente mantente en 10 MB) |
| 401 | invalid token |
Clave API incorrecta |
3.5 Clonación reforzada (enhanced=true)
Para casos en los que "la propia muestra de voz lleva letras con derechos / hace falta una subida reforzada". Se factura al precio de subida reforzada (10 ¥ por llamada por defecto, con devolución automática si falla):
- La respuesta es inmediatamente
status=processing+task_id(todavía sinclip_id) y se ejecuta de forma asíncrona; - Mientras se ejecuta, usa
GET /api/music/voice-profile/{voice_id}para consultar el progreso, que devuelveprogress_percent/progress_stage/progress_message; - Al terminar
statuspasa areadyy se rellenanclip_id,audio_url,image_url; - Si falla,
status=failedyerror_messagedice algo como "la subida reforzada ha fallado; el importe se ha devuelto automáticamente, inténtalo más tarde"; - Una clonación reforzada tarda bastante más que una creación estándar (minutos), así que no la esperes con un tiempo de espera síncrono.
curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@./my-voice.mp3" -F "title=Mi voz" -F "enhanced=true"
4. Crear una voz desde audio existente
Si prefieres no volver a subir: copia directamente un audio que ya hayas subido o ya hayas generado como voz. Gratis e idempotente.
POST /api/music/voice-profile/create-from-clip
Content-Type: application/json
{
"source_song_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
"title": "Xu Qing Qiang",
"client_request_id": "vp-clip-1789…"
}
source_song_id: el clip id de un audio terminado de tu cuenta (equivalente alsong_idde la canción).- Reenviar el mismo clip no crea un registro nuevo: devuelve directamente la voz existente con
reused: true(medido).
La respuesta son todos los campos de §3.3 más dos campos de solo lectura:
| Campo | Notas |
|---|---|
reused |
true = este audio ya era tu voz y se reutiliza |
source_type |
De dónde viene el audio: generate / custom_generate / voice_generate / upload_source / enhanced_upload |
{
"success": true,
"data": {
"voice_id": "vp_20260926081712557959800Z5gvlt",
"clip_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
"title": "Xu Qing Qiang",
"status": "ready",
"enhanced": true,
"reused": true,
"source_type": "enhanced_upload"
}
}
Errores (el message tal cual se devuelve; se recomienda mostrarlo o localizarlo):
| message | Significado |
|---|---|
source audio not found |
El clip no existe o no es tuyo |
source audio is invalid |
Ese audio todavía se está generando / es un producto intermedio y aún no sirve |
source_song_id is required |
No se envió source_song_id |
5. Lista / detalle / eliminación de voces
5.1 Lista
GET /api/music/voice-profile/list
GET /api/music/voice-profile/list?include_deleted=true
{
"success": true,
"message": "",
"data": {
"items": [ { "voice_id": "vp_…", "title": "Mi voz", "status": "ready", "audio_url": "…", "image_url": "…" } ],
"total": 1
}
}
Los campos son exactamente los de §3.3. Por defecto no se devuelven las voces eliminadas.
5.2 Detalle
GET /api/music/voice-profile/{voice_id}
Devuelve un único objeto de voz (data es el objeto en sí, no un array). Mientras una clonación reforzada está en curso, añade además:
| Campo | Notas |
|---|---|
progress_percent |
Entero de 0 a 100 |
progress_stage |
Identificador de la fase, por ejemplo media_preparing |
progress_message |
Texto de progreso para mostrar al usuario |
5.3 Eliminar
POST /api/music/voice-profile/delete
Content-Type: application/json
{ "voice_id": "vp_2026…" }
{ "success": true, "message": "", "data": { "voice_id": "vp_2026…", "status": "deleted" } }
- Tras eliminarla, la voz desaparece de la lista y ya no puede usarse para versionados nuevos: enviar con ese
voice_iddevuelve 400 (ver §6.4). - Las canciones ya generadas con ella no se ven afectadas en absoluto; reproducción, descarga, continuación, sustitución y separación funcionan igual.
- Eliminar una voz inexistente, o que no pertenece a esta cuenta, devuelve
{"success":false,"message":"voice not found"}.
6. Versionar con una voz (el endpoint central)
POST /api/music/voice-profile/cover
Content-Type: application/json
Un envío genera 2 canciones (igual que la generación normal).
6.1 Dos escenarios
| Escenario | Disparador | Notas |
|---|---|---|
| A. Versionar una canción concreta | Se envió song_clip_id |
Canta esa canción con tu voz (melodía / ritmo / secciones siguen el original; la voz pasa a ser la tuya) |
| B. Cantar una canción nueva con la voz | No se envió song_clip_id |
Solo la voz + letra (opcional) + requisitos de estilo; el modelo compone una melodía nueva en ese estilo y la canta |
El resolved_scene de la respuesta devuelve cover o sing, para que puedas confirmar qué ruta se siguió.
6.2 Campos de la petición
| Campo | Tipo | Obligatorio | Por defecto | Notas |
|---|---|---|---|---|
model |
string | Sí | — | Nombre de modelo de cara al cliente, ver §6.5. Si no se envía devuelve model is required (HTTP 500) |
voice_id |
string | Uno de los dos | — | ID de voz (vp_…); debe estar status=ready |
voice_clip_id |
string | Uno de los dos | — | También sirve el clip id de la voz; si envías ambos gana voice_id |
song_clip_id |
string | No | vacío | Clip id (song_id) de la canción a versionar. No enviarlo = escenario B |
lyrics |
string | No | vacío | Letra completa, enviada carácter a carácter sin reescribir ni truncar; ≤ 3000 caracteres |
cover_requirements |
string | No | vacío | Instrucciones de versionado en lenguaje natural, por ejemplo "articula más claro". Se concatenan a un prompt fijo |
style_requirements |
string | No | vacío | Requisitos de estilo, por ejemplo "folk lento, guitarra acústica" |
title |
string | No | vacío | El título de estas dos canciones en el espacio de trabajo (afecta al song_title que devuelven las consultas posteriores) |
negative_tags |
string | No | vacío | Estilos excluidos, por ejemplo electrónico, rap; ≤ 1000 caracteres |
vocal_gender |
string | No | vacío | m / f (también acepta male / female); vacío = cualquiera |
duration |
number | No | vacío | Duración deseada en segundos, un entero de 1 a 480; vacío = lo decide la plataforma. El mínimo real de la plataforma ronda los 30 s: con valores menores las pruebas seguían dando canciones de unos 30 segundos |
audio_weight |
number | No | 0,85 | Audio Influence, un decimal de 0 a 1. Cuanto más alto, más se acerca a la muestra de voz |
style_weight |
number | No | vacío | Influencia del estilo, un decimal de 0 a 1 |
weirdness_constraint |
number | No | vacío | Creatividad, un decimal de 0 a 1 (si tu interfaz usa porcentajes, divide entre 100) |
variety |
number | No | vacío | Variedad, un entero de 0 a 4 (no un porcentaje), solo en los modelos v6 |
max_mode |
boolean | No | false |
Max Mode, precio ×2 |
client_request_id |
string | No | vacío | Identificador de envío; se escribe en el registro de tareas del servidor para diagnóstico (no deduplica) |
Se recomienda enviar también la cabecera X-Create-Ui-Client-Request-Id: <el mismo id de envío>: solo eso se escribe en el registro de tareas del servidor y sirve de clave principal para la investigación posterior (ver §1.5).
Unidades a vigilar: audio_weight / style_weight / weirdness_constraint son decimales de 0 a 1, variety es un entero de 0 a 4 y duration va en segundos. Mezclarlos provoca rechazos o resultados raros.
La letra es opcional en el escenario B (el modelo se apaña solo), pero envía siempre lyrics cuando necesites que se cante un contenido concreto.
6.3 Respuesta
{
"code": 200,
"message": "success",
"data": {
"voice_id": "vp_20260926081712557959800Z5gvlt",
"voice_clip_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
"song_clip_id": "5b773e9a-a035-4134-a4a4-29c9961d3ccb",
"resolved_scene": "cover",
"model": "suno-v6",
"audio_weight": 0.85,
"clips": [
{
"song_id": "0f2a…",
"status": "processing",
"song_title": "",
"model_version": "suno-v6",
"audio_url": "",
"play_url": "https://media.suno-api.io/play/0f2a…?expires=…&signature=…",
"lyrics": "",
"description": "[Tarea] Esto es un versionado. … (la parte estructural fija del servidor + los requisitos de versionado/estilo que rellenaste)"
},
{
"song_id": "7c91…",
"status": "processing",
"model_version": "suno-v6",
"audio_url": ""
}
],
"source_updates": []
}
}
Puntos clave:
- Identifica las canciones terminadas con
clips[].song_id(este endpoint no devuelve un campoid). - Obtienes 2 valores de
song_idde inmediato, mientrasstatussigue enprocessing(solo significa que se aceptaron) yaudio_urlestá vacío; hay que sondear hastacompletedantes de descargar.play_urles el flujo de preescucha de la plataforma, puede aparecer ya en el envío y caducará. descriptiones el prompt que finalmente envía el servidor (la parte estructural fija + loscover_requirements/style_requirementsque rellenaste); es muy útil para investigar resultados.source_updateses el resultado del tratamiento de materiales del servidor y el cliente puede ignorarlo.- El
titleque envías se escribe en el registro de tareas del servidor y aparece comosong_titleen las consultas posteriores; queclips[].song_titlevenga vacío en la respuesta del envío es normal.
6.4 Errores
{ "error": { "message": "esta voz no existe o ha sido eliminada (voice_id=vp_xxx)…", "type": "new_api_error", "param": "", "code": "invalid_request" } }
| HTTP | message | Causa |
|---|---|---|
| 500 | model is required |
Al cuerpo le falta model (es un campo obligatorio para elegir el canal) |
| 400 | voice_id is required and must be a ready voice |
No se envió voice_id, o se envió un valor de marcador de posición / una voz no lista |
| 400 | esta voz no existe o ha sido eliminada (voice_id=vp_xxx)… |
La voz fue eliminada, no existe o no está en la cuenta actual. Usa otra voz disponible o crea una nueva |
| 400 | esta voz ha sido eliminada (voice_id=vp_xxx)… |
Al pasar material directamente con voice_clip_id, la voz de ese material ha sido eliminada; mismo tratamiento que arriba |
| 400 | voice is not ready yet (status=processing) |
La voz aún se está creando; espera a ready e inténtalo de nuevo |
| 400 | song_clip_id must be a real completed clip |
song_clip_id es un marcador de posición / no está terminado |
| 400 | song_clip_id must differ from the voice clip |
El objetivo del versionado no puede ser la propia muestra de voz |
| 400 | audio_weight must be a number between 0 and 1 |
Unidad equivocada en el deslizador (se envió un porcentaje) |
| 400 | duration must be an integer between 1 and 480 seconds |
La duración no es un entero de 1 a 480 |
| 400 | vocal_gender must be one of m, f, male, female |
Valor de género inválido |
| 400 | variety must be an integer between 0 and 4 / variety is only supported on v6 models |
Valor de variedad inválido o modelo no compatible |
Un saldo insuficiente devuelve un error de facturación directamente en el envío y nunca deja una tarea a medias.
6.5 Modelos disponibles (nombres de cara al cliente)
| Nombre de modelo | Notas |
|---|---|
suno-v6 |
Por defecto, recomendado |
suno-v6-wild |
Más desatado |
suno-v6-mini |
Ligero |
Usa los nombres de modelo de cara al cliente (los de arriba). chirp-* son nombres internos de la plataforma y no deben usarse directamente.
7. Consultar el progreso
7.1 Consulta por lotes (recomendada)
POST /api/music/query
Content-Type: application/json
{ "model": "suno-v6", "song_ids": "id1,id2" }
song_idses una cadena separada por comas (no un array).- La respuesta es un array desnudo (directamente
[...], sin envoltoriosuccess/data):
[
{
"song_id": "0f2a…",
"song_title": "Dos tigres",
"status": "completed",
"audio_url": "https://suno-api-hk-1437223057.cos.ap-hongkong.myqcloud.com/assets/0f2a…-mp3.mp3",
"cover_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
"duration": 115.15,
"model_version": "suno-v6",
"generation_type": "voice_profile_cover",
"play_url": "https://media.suno-api.io/play/…?expires=…&signature=…",
"lyrics": "[Verse 1]…",
"prompt": "[Verse 1]…",
"description": "[Tarea] Esto es un versionado. … (el prompt final del servidor)",
"style_tags": "…",
"created_at": "2026-09-25T18:19:09.918Z",
"video_url": ""
}
]
| Campo | Notas |
|---|---|
status |
Ver §1.7; solo completed cuenta como terminada |
audio_url |
Enlace directo mp3; solo se rellena al llegar a completed |
cover_url |
Dirección de la portada |
duration |
Duración real en segundos |
generation_type |
Las canciones producidas por un versionado con voz son siempre voice_profile_cover |
play_url |
Dirección de preescucha firmada (caduca) |
song_title |
Título de la tarea (el title que enviaste; si no enviaste ninguno el servidor pone uno por defecto) |
lyrics / prompt |
Letra terminada / texto original de la letra |
description |
El prompt final que envía el servidor (incluida la parte estructural fija) |
style_tags |
La descripción final del estilo |
created_at |
Una cadena ISO 8601 (ojo: difiere de los segundos Unix del endpoint de detalle) |
Consejo de sondeo: cada 5–10 segundos, con un tiempo de espera total de 10–15 minutos (la cuenta fría más lenta medida tardó unos 4,5 minutos; muy pocas tardan más). No juzgues la finalización por si audio_url está vacío: usa status.
Nota de compatibilidad: este endpoint identifica las canciones por
song_id; en algunas respuestas antiguas apareció un campoid, así querow.song_id || row.ides la forma segura de leerlo.
7.2 Detalle de una canción
GET /api/music/songs/{song_id}
{
"success": true,
"data": {
"song_id": "0f2a…",
"title": "Dos tigres",
"status": "completed",
"generation_type": "voice_profile_cover",
"model": "suno-v6",
"duration": 115.15,
"audio_url": "https://…/assets/0f2a…-mp3.mp3",
"image_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
"wav_url": "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=wav",
"video_url": "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=video",
"created_at": 1790411012,
"completed_at": 1790411500,
"parameters": {
"prompt": "[Verse 1]…",
"style_tags": "…",
"title": "Dos tigres",
"model": "suno-v6",
"generation_type": "voice_profile_cover",
"source_song_id": "5b773e9a-…"
},
"parameter_retention": {
"core_parameters_available": true,
"extended_parameters_available": false,
"sources": ["suno_tasks"],
"unavailable_fields": ["negative_tags", "vocal_gender", "style_weight", "weirdness_constraint"]
}
}
}
- Aquí
created_at/completed_atson segundos Unix (a diferencia de las cadenas ISO de la consulta por lotes, así que los clientes deben distinguirlos). wav_url/video_urlson las entradas de descarga de esta plataforma (relativas al dominio actual) y unGETobtiene el archivo; son cadenas vacías cuando la plataforma no ha producido ese material.parameter_retentionindica a qué parámetros de envío se puede rastrear esa canción:core_parameters_available=truesignifica que los parámetros centrales (letra / estilo / origen) se pueden consultar, y conextended_parameters_available=falselos parámetros extendidos listados arriba no se conservaron (los versionados con voz están actualmente en esta categoría).
7.3 Mi lista de trabajos
GET /api/music/songs?p=1&page_size=20
GET /api/music/songs?status=completed&q=palabra clave
Parámetros de paginación: p (número de página, desde 1) / page_size (elementos por página; ps es una grafía compatible). Opcionales status y q (una palabra clave del título). Por defecto se ordena por fecha de creación descendente.
{
"success": true,
"data": {
"page": 1,
"page_size": 20,
"total": 42,
"items": [
{
"song_id": "0f2a…",
"title": "Dos tigres",
"status": "completed",
"generation_type": "voice_profile_cover",
"model": "suno-v6",
"duration": 115.15,
"audio_url": "https://…/assets/0f2a…-mp3.mp3",
"image_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
"created_at": 1790411012,
"completed_at": 1790411500
}
]
}
}
Usa generation_type=voice_profile_cover para distinguir "las canciones producidas por un versionado con voz" de otros resultados de generación.
8. Descargar las canciones terminadas
8.1 Tomar el mp3 directamente (recomendado, gratis)
Sirve cualquiera de las tres; elige una:
- Usar el
audio_urldel resultado de la consulta (un enlace directo al almacenamiento de objetos, lo más cómodo). GET /api/music/download?song_id=<id>&kind=mp3→ devuelve directamente el flujo de bytes de audio (con el nombre de archivo ya enContent-Disposition).POST /api/music/download-url(para obtener una dirección temporal firmada).
curl -sS -L "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song.mp3
Valores de kind: mp3 (equivalente a song) / playback (reproducción en streaming) / wav / video / lyrics / timestamped_lyrics.
timestamped_lyrics (.lrc) solo está disponible para algunas canciones por ahora; si falla, genera el archivo tú mismo con la API de letras con marcas de tiempo.
La respuesta es el flujo de bytes del archivo, con Content-Type y Content-Disposition (nombre de archivo) ya puestos; los wav_url / video_url que devuelve GET /api/music/songs/{song_id} son la misma entrada con kind=wav|video.
8.2 Convertir a wav / obtener letras / metadatos (de pago)
POST /api/music/free2
Content-Type: application/json
{ "song_ids": ["0f2a…"], "files": ["mp3", "wav", "lyrics"] }
{
"success": true,
"data": {
"songs": [
{ "song_id": "0f2a…", "files": [ { "type": "mp3", "url": "https://…" }, { "type": "wav", "url": "https://…" } ] }
],
"requested_songs": 1,
"succeeded_songs": 1,
"price": 0.2
}
}
filesadmite:mp3/wav/lyrics/metadata, hasta 10 canciones a la vez.- Se factura por canción correcta (0,2 ¥ cada una); una canción que falla entera no se cobra, y un formato que falla aparece solo en
songs[].errors. - Para volver a obtener archivos ya obtenidos antes, usa primero el gratuito
POST /api/music/free2/cached(los mismossong_ids+files) para conseguir direcciones archivadas; susongs[].missing_fileslista los formatos que no están en caché y hay que preparar de nuevo.
9. Consultar precios
GET /api/pricing/catalog
Un endpoint público que no requiere autenticación. Todos los precios unitarios que el cliente necesita mostrar están en data.catalog.meta (cadenas):
| Clave | Significado | Valor actual |
|---|---|---|
generation_price |
Generación normal | 0,6 |
voice_generation_price |
Precio base del versionado con voz | 1,2 |
max_mode_factor |
Multiplicador de Max Mode | 2 |
enhanced_upload_price |
Clonación reforzada / subida reforzada | 10 |
voice_auto_verify_price |
Verificación automática de voz | 5 |
voice_long_term_clone_price |
Clonación de voz a largo plazo | 5 |
Los precios se ajustan en el back-office, así que léelos en vivo en lugar de fijarlos en el cliente. El cargo real del versionado = voice_generation_price × (max_mode_factor otra vez si max_mode es verdadero).
10. Límites y advertencias
- Tamaño de subida: ≤ 10 MB (el servidor admite más, pero la pasarela de entrada trunca los cuerpos sobredimensionados en 10 MiB, lo que se manifiesta como "rechazado por Suno", así que bloquéalo antes en tu lado).
- Duración de la muestra: al menos 6 s, se recomiendan 10–60 s; si es demasiado corta la plataforma la rechaza.
- Contenido de la muestra: voz limpia; evita cualquier cosa muy parecida a una grabación existente (la comparación del catálogo la rechaza).
- Límites de texto:
lyrics≤ 3000 caracteres; se aconseja questyle_requirements/negative_tags/titlese mantengan en 1000 / 1000 / 100 caracteres respectivamente (los requisitos de estilo y de versionado se concatenan al prompt, así que mantén el total dentro de 3000 caracteres). - La letra no se reescribe: se canta lo que pases (carácter a carácter), sin truncado local.
- Cada canción produce 2 pistas; no asumas un único resultado.
- El audio de origen se conserva de forma permanente: eliminar una voz no limpia su audio de origen; así se mantienen posibles los versionados posteriores y la trazabilidad de cumplimiento.
- La voz debe estar lista: una voz en
processingno puede usarse para versionados. - Tiempo de espera de la petición: en una cuenta fría el primer envío tardó hasta unos 4,5 minutos en las pruebas, así que configura el tiempo de espera del cliente en ≥ 6 minutos. Los versionados no deduplican a nivel de petición, así que tras un tiempo de espera agotado comprueba si ya ha aparecido una canción nueva (§1.5) antes de decidir reenviar.
- Titularidad de la voz: las voces pertenecen a quien las crea; un versionado solo acepta voces listas y no eliminadas. Una voz que no existe, ha sido eliminada o pertenece a otra cuenta devuelve 400:
esta voz no existe o ha sido eliminada (voice_id=…).
11. Preguntas frecuentes (FAQ)
Q1. ¿Crear una voz cuesta dinero? La creación estándar y "crear desde audio existente" son gratis; solo se facturan los versionados (1,2 ¥ / MAX 2,4 ¥) y las clonaciones reforzadas (10 ¥ por defecto).
Q2. ¿Puedo usar como muestra una canción terminada con acompañamiento?
No se recomienda. Cualquier cosa con música, o muy parecida a una grabación existente del catálogo, la rechaza la plataforma (This audio matches an existing recording in our catalog.). Usa una grabación puramente vocal y seca.
Q3. ¿Por qué audio_url está vacío después de enviar un versionado?
El envío solo significa que se aceptó y status sigue en processing. Una dirección reproducible/descargable aparece cuando hayas sondeado /api/music/query hasta status=completed.
Q4. ¿Hay que enviar letra en el escenario B (sin song_clip_id)?
Es opcional. Envía lyrics para cantar un contenido concreto; sin él el modelo se apaña solo, pero con menos control.
Q5. ¿Puede usarse directamente como voz un audio subido por el cliente?
Sí: mediante la forma file_url de create, o subiéndolo primero como canción y llamando después a create-from-clip.
Q6. ¿Se devuelve el dinero si falla?
Una petición rechazada de plano (parámetros incorrectos / error de la plataforma) no se cobra, según las mediciones; una tarea aceptada que finalmente falla devuelve el importe precargado. En el fallo terminal la tarea informa status=failed más error_message.
Q7. Tras eliminar una voz, ¿puedo seguir escuchando canciones generadas antes con ella? Sí. La eliminación solo afecta a si esa voz puede usarse para versionados nuevos.
Q8. ¿Qué longitud de canción puedo versionar de una vez?
duration acepta de 1 a 480 segundos; si lo omites lo decide la plataforma a partir de la canción original / el material. Ojo: las pistas terminadas de la plataforma tienen como mínimo unos 30 segundos; con un valor menor las pruebas seguían dando 29,96 / 29,76 segundos.
Apéndice A: ejemplo completo (Node.js, con sondeo y descarga)
const BASE = "https://www.suno-api.io";
const KEY = process.env.SUNO_API_KEY;
const H = { Authorization: `Bearer ${KEY}` };
// ① Crear la voz (multipart)
async function createVoice(filePath, title) {
const fd = new FormData();
fd.set("file", new Blob([await (await import("node:fs/promises")).readFile(filePath)], { type: "audio/mpeg" }), "my-voice.mp3");
fd.set("file_name", "my-voice.mp3");
fd.set("source_file_name", "my-voice.mp3");
fd.set("title", title);
fd.set("client_request_id", `vp-create-${Date.now()}`);
const res = await fetch(`${BASE}/api/music/voice-profile/create`, { method: "POST", headers: H, body: fd });
const body = await res.json();
if (!body.success) throw new Error(body.message);
return body.data; // { voice_id, status, audio_url, ... }
}
// ② Versionar
async function cover(voiceId, songClipId, lyrics) {
const submissionId = `vp-cover-${Date.now()}`;
const res = await fetch(`${BASE}/api/music/voice-profile/cover`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json", "X-Create-Ui-Client-Request-Id": submissionId },
body: JSON.stringify({
model: "suno-v6",
voice_id: voiceId,
song_clip_id: songClipId || "",
lyrics: lyrics || "",
style_requirements: "folk lento, guitarra acústica",
audio_weight: 0.85,
max_mode: false,
client_request_id: submissionId,
}),
});
const body = await res.json();
if (body.error) throw new Error(body.error.message);
return body.data; // { resolved_scene, clips: [{ song_id, status }] }
}
// ③ Sondear hasta terminar (cada 5 segundos, máximo 15 minutos)
async function waitUntilCompleted(songIds) {
const deadline = Date.now() + 15 * 60 * 1000;
while (Date.now() < deadline) {
const res = await fetch(`${BASE}/api/music/query`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json" },
body: JSON.stringify({ model: "suno-v6", song_ids: songIds.join(",") }),
});
const songs = await res.json(); // array desnudo
if (songs.every((s) => s.status === "completed" || s.status === "failed")) return songs;
await new Promise((r) => setTimeout(r, 5000));
}
throw new Error("timeout waiting for cover");
}
// ④ Descargar
async function download(songId, outPath) {
const res = await fetch(`${BASE}/api/music/download?song_id=${encodeURIComponent(songId)}&kind=mp3`, { headers: H });
if (!res.ok) throw new Error(`download failed: ${res.status}`);
(await import("node:fs/promises")).writeFile(outPath, Buffer.from(await res.arrayBuffer()));
}
const voice = await createVoice("./my-voice.mp3", "Mi voz");
const result = await cover(voice.voice_id, "5b773e9a-a035-4134-a4a4-29c9961d3ccb", "[Verse 1]\nletra…");
const ids = result.clips.map((c) => c.song_id);
const songs = await waitUntilCompleted(ids);
for (const [i, s] of songs.entries()) {
if (s.status === "completed") await download(s.song_id, `./out-${i}.mp3`);
}
Apéndice B: registro de cambios
| Fecha | Cambio |
|---|---|
| 2026-10-15 | Semántica de eliminación explicada sin rodeos (§5.3); un versionado con un voice_id "eliminado / sin permiso" ahora devuelve 400 antes de cualquier cargo previo, con la tabla de errores y las FAQ actualizadas (junto con la puerta de eliminación de voces publicada ese día) |
| 2026-10-13 | Añadida la nota "por qué recomendamos esta cadena" al principio: según las evaluaciones reales de muchos usuarios, las canciones generadas con esta cadena conservan mucho mejor la voz original |
| 2026-09-26 | Primera versión: crear una voz (tres formas de entrada) / crear desde audio existente / listar, detalle y eliminar / versionado con voz (escenarios A y B) / sondeo del progreso / descarga / lectura de precios, con pruebas medidas |
Obtener una clave de API
Crea una clave de API en la consola después de registrarte. Cada generación cuesta 0,6 ¥ y devuelve 2 pistas, las descargas son ilimitadas y no hace falta número de teléfono.
Obtener clave de API Volver al resumen