Referencia de la API
URL base https://api.vocallab.ai. Cada solicitud necesita Authorization: Bearer vl_live_... (consulta Claves de API).
GET /api/v1/ping
Prueba de conexión y autenticación. Devuelve tu saldo de puntos.
{ "ok": true, "points": 12345, "unit": "points (1 pt ≈ 1 second of audio)" }
GET /api/v1/voices
Las voces que puedes usar: primero tus voces clonadas y diseñadas, después el catálogo público. Usa el id devuelto como voice al generar. Las voces del catálogo también aceptan su slug.
| Parámetro | Por defecto | Notas |
|---|---|---|
limit | (ninguno) | Cuántas devolver, 1–500. Si se omite devuelve la lista completa: unas 260 voces |
offset | 0 | Cuántas omitir, para paginar |
q | — | Filtro sin distinción de mayúsculas sobre el id, el slug y el name de la voz, p. ej. ?q=ashley |
type | — | preset, clone, designed |
Cada respuesta incluye total, count, offset y has_more, así que puedes paginar sin adivinar. Los mismos cuatro parámetros (menos type) funcionan en GET /api/v1/voices/clones y GET /api/v1/voices/designs.
curl "https://api.vocallab.ai/api/v1/voices?q=narrator&limit=20" \
-H "Authorization: Bearer vl_live_..."
{ "voices": [
{ "id": "Ashley", "slug": "warm-natural-female-explainer-voice-for-youtube-podcasts",
"name": "Warm Natural Female Explainer Voice for YouTube & Podcasts",
"type": "preset", "languages": ["en"], "category": "Narration" },
{ "id": "default-abc123__my-voice", "name": "My Narrator", "type": "clone", "languages": ["en"] }
] }
GET /api/v1/models
Los modelos de voz seleccionables. Pasa una key como model en POST /api/v1/tts (por defecto v-pro). Las claves de API pueden usarlos todos. Consulta Modelos de voz para conocer las diferencias.
{ "default": "v-pro", "models": [
{ "key": "v-studio", "label": "VocalLab Studio", "steerable": true, "costMultiplier": 1,
"supportsTemperature": false, "supportsDeliveryMode": true },
{ "key": "v-flash", "label": "VocalLab Studio Flash", "steerable": false, "costMultiplier": 0.75,
"supportsTemperature": false, "supportsDeliveryMode": false },
{ "key": "v-pro", "label": "VocalLab Pro", "steerable": false, "costMultiplier": 1,
"supportsTemperature": true, "supportsDeliveryMode": false },
{ "key": "v-lite", "label": "VocalLab Lite", "steerable": false, "costMultiplier": 0.5,
"supportsTemperature": true, "supportsDeliveryMode": false }
] }
POST /api/v1/tts
Genera voz.
| Campo | Obligatorio | Notas |
|---|---|---|
text | sí | Hasta 2.000 caracteres. Cada llamada se sintetiza como una única solicitud — para textos más largos, divide el texto en varias llamadas |
voice | sí | Un id de voz de /api/v1/voices |
model | no | v-studio (el más nuevo, dirigible, más de 200 idiomas), v-flash (más de 200 idiomas, ~5× más rápido, ¾ de puntos), v-pro (predeterminado — máxima fidelidad, 15 idiomas) o v-lite (rápido, ½ puntos). Consulta GET /api/v1/models |
speed | no | Número 0.5–1.5 (paso 0.05). Por defecto, el valor de la voz |
temperature | no | Número 0.7–1.5 (paso 0.05). Más alto = más expresivo y variable. Ignorado por v-studio y v-flash — en v-studio usa delivery_mode. Por defecto, el valor de la voz |
delivery_mode | no | STABLE, BALANCED o CREATIVE — cuánto varía el modelo su interpretación. Solo v-studio; enviarlo con otro modelo devuelve 422 |
enhance_generation | no | true reduce el ruido del audio generado. Funciona en todos los modelos. Por defecto false: puede dejar la voz demasiado suavizada |
format | no | Uno de MP3 (predeterminado), WAV, FLAC, OGG_OPUS, LINEAR16, PCM, ALAW, MULAW |
bit_rate | no | Entero 32000–320000. Solo MP3 y OGG_OPUS; se ignora en otros formatos |
sample_rate | no | Uno de 8000, 16000, 22050, 24000, 32000, 44100, 48000 (Hz) |
captions | no | true (o "phrase" / "word") devuelve también los subtítulos SRT en captions, así no necesitas una segunda llamada. Consulta GET /api/v1/tts/:id/captions |
curl -X POST https://api.vocallab.ai/api/v1/tts \
-H "Authorization: Bearer vl_live_..." \
-H "Content-Type: application/json" \
-d '{"text":"Hello from VocalLab","voice":"Ashley"}'
Devuelve el audio en línea (base64) más un id. La URL alojada aparece una vez que finaliza la subida; consúltala con GET /api/v1/tts/:id.
Cada solicitud está limitada a 2.000 caracteres y corresponde exactamente a una síntesis de voz: no hay divisiones ni ramificaciones ocultas, por lo que el coste y la latencia por llamada se mantienen predecibles. Las solicitudes se contabilizan sobre tu saldo de puntos y pasan por una cola de uso justo, de modo que la automatización intensiva nunca bloquea la aplicación. Para narrar un texto más largo, divídelo en fragmentos de ≤ 2.000 caracteres y envíalos como llamadas separadas (respetando el límite de 60 solicitudes/minuto).
{ "id": "...", "status": "pending", "audio_base64": "data:audio/mp3;base64,...",
"audio_url": null, "stream_url": "https://api.vocallab.ai/api/v1/tts/.../audio",
"captions_url": "https://api.vocallab.ai/api/v1/tts/.../captions",
"format": "MP3", "model": "v-pro", "points_used": 12 }
Modelo y coste.
v-flashfactura ¾ (points = ⌈ characters ÷ 20 ⌉) yv-litela mitad (÷ 30) de los puntos dev-pro/v-studio(÷ 15).v-studioes el único modelo que sigue instrucciones de expresión/dirección; consulta Modelos de voz y Dirección de voz.
Pausas
Inserta un silencio de duración exacta con una etiqueta <break /> autocerrada dentro de text:
{ "text": "Déjame pensar <break time=\"1.5s\" /> Sí, ya lo he pensado.", "voice": "Ashley" }
- Segundos o milisegundos —
1.5s=1500ms. - Hasta 20 etiquetas break por solicitud, en todos los idiomas admitidos.
- Las etiquetas break cuentan para el límite de 2.000 caracteres y se eliminan de los subtítulos/SRT.
GET /api/v1/tts/:id
Estado de la generación y la URL del audio alojado cuando está lista.
{ "id": "...", "status": "ready", "audio_url": "https://...",
"stream_url": "https://api.vocallab.ai/api/v1/tts/.../audio",
"captions_url": "https://api.vocallab.ai/api/v1/tts/.../captions", "format": "MP3" }
GET /api/v1/tts/:id/audio
Transmite directamente los bytes de audio del clip finalizado, como alternativa al blob base64 audio_base64. Se sirve inline (se reproduce en un navegador o reproductor multimedia) y admite la cabecera HTTP Range para que los clientes puedan avanzar. Devuelve 409 mientras el clip aún se está finalizando: consulta GET /api/v1/tts/:id hasta que status sea ready y luego transmite.
curl -L https://api.vocallab.ai/api/v1/tts/GENERATION_ID/audio \
-H "Authorization: Bearer vl_live_..." \
-o speech.mp3
El mismo enlace se devuelve como stream_url en POST /api/v1/tts y GET /api/v1/tts/:id.
GET /api/v1/tts/:id/captions
Subtítulos de una generación, como archivo .srt. Los cues se sincronizan con el habla real (tiempos por palabra devueltos con la síntesis) y se eliminan las marcas [emotion] y las pausas <break />, de modo que solo las palabras habladas llegan al archivo.
Los subtítulos se construyen a partir de los tiempos guardados, no del archivo de audio: están disponibles de inmediato, incluso mientras status sigue en pending.
| Consulta | Por defecto | Notas |
|---|---|---|
format | srt | srt devuelve el archivo de subtítulos; json devuelve { srt, words, duration } para renderizarlos a tu manera |
mode | phrase | phrase = líneas de subtítulo legibles (cortadas en pausas y finales de frase u oración). word = un cue por palabra, para resaltado tipo karaoke |
max_words | 4 | Palabras por línea en modo phrase, 2–7 |
uppercase | false | true pone el texto en MAYÚSCULAS |
curl -L "https://api.vocallab.ai/api/v1/tts/GENERATION_ID/captions" \
-H "Authorization: Bearer vl_live_..." \
-o speech.srt
1
00:00:00,000 --> 00:00:01,240
Hello from VocalLab,
2
00:00:01,240 --> 00:00:03,100
this is your narrator speaking.
Con format=json:
{ "id": "...", "mode": "phrase", "duration": 3.1,
"srt": "1\n00:00:00,000 --> 00:00:01,240\nHello from VocalLab,\n\n...",
"words": [ { "word": "Hello", "start": 0, "end": 0.32 } ] }
El mismo enlace se devuelve como captions_url en POST /api/v1/tts y GET /api/v1/tts/:id. Para recibir el SRT junto con el audio en una sola llamada, envía "captions": true en POST /api/v1/tts.
Devuelve 409 captions_unavailable cuando una generación no tiene tiempos de palabra guardados (algunos clips antiguos); el audio no se ve afectado.
DELETE /api/v1/tts/:id
Elimina de forma permanente una generación de tu propiedad: tanto el archivo de audio almacenado como su registro en la base de datos. Útil para limpiar tras una descarga o para atender una solicitud de eliminación de datos. Un id que no existe, o que no es tuyo, devuelve 404.
curl -X DELETE https://api.vocallab.ai/api/v1/tts/GENERATION_ID \
-H "Authorization: Bearer vl_live_..."
{ "ok": true, "id": "...", "deleted": true }
GET /api/v1/voices/languages
Novedad:
GET /api/v1/voices/languagesahora devuelve más de 470 idiomas con sus variantes de acento (por ejemploen-GB,pt-PT).codees una etiqueta BCP-47; los valores antiguos (EN_US,PT_BR, …) yOtherse siguen aceptando.
Los idiomas y los límites de grabación que se aplican a la clonación y al diseño de voz. Consúltalo en lugar de fijar la lista en tu código: es la misma fuente de verdad que usa el formulario de subida del Studio.
{ "languages": [
{ "name": "English", "code": "EN_US", "experimental": false },
{ "name": "Other", "code": "AUTO", "experimental": true }
],
"sample_limits": { "max_samples": 1, "max_base64_length": 4194304,
"allowed_formats": ["mp3", "wav", "webm"] } }
Diseño de voz
Inventa una voz completamente nueva a partir de una descripción escrita, sin grabar nada. Son dos llamadas: generar previsualizaciones candidatas y guardar la que prefieras.
POST /api/v1/voices/designs/previews
Genera hasta tres voces candidatas. Se cobra en points: cada previsualización es una síntesis real de preview_text a la tarifa de la API (⌈caracteres ÷ 15⌉ por previsualización).
Todavía no se guarda nada, así que esto no usa una plaza de diseño, pero sí requiere una libre. Si tus diseños ya están en el límite del plan, la llamada devuelve 409 design_limit y no se gasta ningún point, porque no tiene sentido pagar por una voz que no podrías guardar.
| Campo | Obligatorio | Notas |
|---|---|---|
prompt | sí | Describe la voz en inglés, de 30 a 1000 caracteres: género, edad, acento, tono, ritmo e interpretación. |
language | no | Idioma que hablará la voz (English, ES_ES, …). Por defecto auto: se deduce de la descripción. |
preview_text | no | Lo que dicen las previsualizaciones, hasta 1000 caracteres. Por defecto, una frase de muestra. |
count | no | Cuántas candidatas generar, 1–3 (por defecto 3). Cada una se cobra. |
include_audio | no | true también devuelve cada previsualización en base64. Todas incluyen ya un preview_url, así que los bytes son opcionales. |
curl -X POST https://api.vocallab.ai/api/v1/voices/designs/previews \
-H "Authorization: Bearer vl_live_..." \
-H "Content-Type: application/json" \
-d '{"prompt":"A warm, unhurried British woman in her forties, low and reassuring, like a documentary narrator.","count":2}'
{ "previews": [
{ "preview_id": "...", "text": "Hello! This is a preview of my voice...",
"preview_url": "https://api.vocallab.ai/api/v1/audio/..." }
],
"points_used": 12, "expires_in": 1800 }
Un preview_id todavía no es una voz utilizable, y es válido durante unos 30 minutos.
Las previsualizaciones que no conserves se descartan. Guarda la que quieras antes de generar otro lote: volver a llamar a este endpoint descarta tus previsualizaciones anteriores y sus preview_url dejan de funcionar, y guardar una descarta el resto de su lote. En ningún caso queda nada atrás.
POST /api/v1/voices/designs
Conserva una previsualización como voz permanente. No cuesta points (las previsualizaciones ya se cobraron), pero ocupa una de las plazas de diseño de tu plan. El id devuelto funciona de inmediato como voice en POST /api/v1/tts.
| Campo | Obligatorio | Notas |
|---|---|---|
preview_id | sí | Un preview_id de la llamada de previsualizaciones, dentro de los 30 minutos. |
name | sí | Nombre visible, hasta 80 caracteres. |
description | no | Nota libre, hasta 500 caracteres. |
tags | no | Hasta 10 etiquetas. |
sample_base64 | no | Clip de muestra que se guarda con la voz. No hace falta dentro de la ventana de 30 minutos: la previsualización elegida se conserva automáticamente. |
{ "id": "default-abc123__narrator", "name": "Documentary Narrator", "type": "designed",
"languages": ["EN_US"], "created_at": "...",
"preview_url": "https://api.vocallab.ai/api/v1/audio/...", "used": 3, "limit": 20 }
GET /api/v1/voices/designs
Tus voces diseñadas, de más reciente a más antigua, con el uso de plazas: { "voices": [...], "used": 3, "limit": 20 }.
DELETE /api/v1/voices/designs/:voiceId
Elimina la voz del proveedor y de tu biblioteca. En un plan de pago libera una plaza. Devuelve { "ok": true, "id": "...", "deleted": true }.
Clonación de voz
Recrea una voz concreta a partir de una grabación breve. Clonar no cuesta points: solo está limitado por el número de plazas de clonación de tu plan. Clona únicamente voces que te pertenezcan o para las que tengas permiso por escrito.
POST /api/v1/voices/clones
| Campo | Obligatorio | Notas |
|---|---|---|
name | sí | Nombre visible, hasta 80 caracteres. |
language | sí | Un nombre o código de GET /api/v1/voices/languages. Usa auto para que se detecte. |
samples | sí | [{ "audio_base64": "...", "transcript": "..." }]: una grabación de unos 30 segundos. transcript es opcional, pero mejora notablemente el clon. |
remove_background_noise | no | Limpia la grabación primero. Por defecto true. |
Vale casi cualquier archivo de audio. audio_base64 es el base64 puro de tu grabación, sin prefijo data:: MP3, WAV, M4A, AAC, OGG, FLAC, WebM, la pista de audio de un MP4 y más. Todo lo que el proveedor de voz no aceptaría directamente se convierte en el servidor a WAV mono de 16 bits, exactamente como hacen las apps web en el navegador antes de subirlo, así que la API no es más exigente que el Studio.
- recorta a los primeros 30 segundos: puedes enviar un archivo más largo, pero solo se usa el principio;
- mezcla el estéreo a mono y remuestrea a 32 kHz;
- reduce los archivos grandes, así que un WAV de estudio de 24 bits ya no hay que prepararlo a mano.
El límite se aplica a la cadena base64, no a los bytes decodificados: hasta 8 000 000 de caracteres, aproximadamente un archivo de 6 MB. Por encima devuelve 413 sample_too_large; un archivo sin audio legible devuelve 400 unreadable_audio.
Cuando se ha cambiado algo, la respuesta incluye un array audio_notes que lo explica. Conviene registrarlo, para que un clon hecho con los primeros 30 segundos de una grabación larga nunca sea una sorpresa silenciosa:
{ "id": "...", "name": "My Narrator", "type": "clone", "used": 2, "limit": 100,
"audio_notes": ["Re-encoded to mono 16-bit WAV at 32 kHz — aac isn't a format the provider accepts.",
"Trimmed to the first 30s (the sample was 90s)."] }
curl -X POST https://api.vocallab.ai/api/v1/voices/clones \
-H "Authorization: Bearer vl_live_..." \
-H "Content-Type: application/json" \
-d "{\"name\":\"My Narrator\",\"language\":\"English\",\"samples\":[{\"audio_base64\":\"$(base64 -w0 sample.mp3)\"}]}"
{ "id": "default-abc123__my-narrator", "name": "My Narrator", "type": "clone",
"languages": ["EN_US"], "created_at": "...", "used": 2, "limit": 100 }
GET /api/v1/voices/clones
Tus voces clonadas, de más reciente a más antigua, con el uso de plazas: { "voices": [...], "used": 2, "limit": 100 }.
DELETE /api/v1/voices/clones/:voiceId
Elimina la voz del proveedor y de tu biblioteca. En un plan de pago libera una plaza. Devuelve { "ok": true, "id": "...", "deleted": true }.
Las plazas son independientes. Las voces clonadas y las diseñadas nunca comparten presupuesto; consulta Planes y límites para las cifras de cada plan. En el plan Free el tope es vitalicio: eliminar una voz no libera la plaza. En un espacio de trabajo, los miembros trabajan dentro de los límites del plan del propietario, y los points de diseño salen del saldo del propietario.
Qué cuesta points
| Points | |
|---|---|
| Clonar una voz | ninguno: solo limitado por las plazas de clonación |
| Listar o eliminar una voz | ninguno |
| Diseñar una voz (previsualizaciones) | cantidad × ⌈preview_text ÷ 15⌉: cada previsualización es una síntesis real |
| Guardar una voz diseñada | ninguno: las previsualizaciones ya se cobraron |
GET /api/v1/me
Tu saldo de puntos y tu plan.
Errores
| Estado | Significado |
|---|---|
400 | Falta un campo obligatorio en el cuerpo (missing_text, missing_voice, missing_name, missing_prompt, …) |
401 | Clave de API ausente o no válida |
402 | Puntos insuficientes |
403 | El plan no incluye acceso a la API (requiere Pro o superior) |
404 | Generación o voz no encontrada (o no es tuya) |
409 | El audio aún no está listo: consulta hasta ready; no hay tiempos de palabra guardados (subtítulos); o todas las plazas de clonación/diseño están ocupadas (clone_limit, design_limit) |
413 | Texto, texto de previsualización o muestra de audio demasiado grande |
422 | Modelo desconocido, idioma no admitido o un parámetro fuera de rango |
429 | Límite de frecuencia alcanzado: 60 solicitudes/minuto por clave y, por separado, 60 llamadas de clonación o diseño de voz por hora |
502 | El proveedor de voz falló o rechazó la petición: el mensaje explica por qué y retryable indica si conviene reintentar |
Los errores tienen la forma { "error": { "code": "...", "message": "..." } }.
Precios
Las generaciones se cobran de tu saldo de puntos, calculado a partir de la longitud del texto (no de la duración final del audio):
points = ⌈ characters ÷ 15 ⌉ (tarifa de la API — unos 15 caracteres por punto)
⌈ ⌉ redondea hacia arriba al siguiente punto entero. La aplicación web usa 17 caracteres por punto, por lo que la API conlleva un pequeño recargo (~13 %). Los puntos se contabilizan antes de la llamada al proveedor: una solicitud que superaría tu saldo devuelve 402 y nunca se genera. Cada respuesta incluye el points_used exacto. Como la voz promedia ~15–17 caracteres/segundo, 1 punto ≈ 1 segundo de audio, pero el cargo exacto siempre sigue la fórmula anterior. Consulta Créditos y minutos para más información.


