Demo API TTS: Ejemplos de peticiones y respuestas en vivo
Esta demo muestra peticiones reales que puedes ejecutar en un minuto y el formato de respuesta que se devuelve. La API es un modelo de texto, por lo que la salida es texto del guion, JSON y llamadas a funciones que un motor de voz separado puede leer en voz alta.
Actualizado

Antes de ejecutar cualquier cosa
Una advertencia importante para quien espere pulsar play y oír una voz: esta demo de la API TTS no produce sonido. El servicio devuelve texto de un modelo, uncensored, por POST /v1/chat/completions. Hay un segundo endpoint, GET /v1/models, para listar lo disponible. Nada devuelve audio, imágenes ni embeddings.
¿Por qué este demo? Porque muchos proyectos de voz necesitan exactamente esta parte: un escritor de guiones, un limpiador de texto, un divisor que decide quién dice qué. Los ejemplos de abajo muestran esos trabajos, y el formato de salida es lo que tu código de voz analizará.
Necesitas una clave. Regístrate en la página de clave de API con Google o con correo y contraseña, luego reclama el crédito de prueba de $0.50 con un clic. Es válido por 7 días y no requiere tarjeta. Exporta la clave para que los comandos de abajo puedan leerla:
export XTTS_API_KEY="paste-your-key-here"
curl -s https://api.xtts.cc/v1/models -H "Authorization: Bearer $XTTS_API_KEY" | grep uncensored
Si esa llamada devuelve una lista JSON que incluye uncensored, la clave funciona y puedes continuar.
Demo 1: una petición simple
La llamada útil más pequeña pide un párrafo corto de estilo hablado:
curl -s https://api.xtts.cc/v1/chat/completions \
-H "Authorization: Bearer $XTTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [
{"role": "system", "content": "You write short lines for a voice actor. No stage directions."},
{"role": "user", "content": "Welcome listeners to a show about lighthouses. Two sentences."}
],
"temperature": 0.7,
"max_tokens": 120
}'
La respuesta se parece a la muestra de abajo. El texto dentro de content variará en cada ejecución, así que trátalo como una ilustración de la estructura y no como una salida grabada.
{
"id": "chatcmpl-example",
"object": "chat.completion",
"model": "uncensored",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Welcome to the show. Tonight we climb the stairs of the world's loneliest lighthouses."
},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 38, "completion_tokens": 21, "total_tokens": 59}
}
Tu código de voz lee choices[0].message.content. El finish_reason te dice por qué terminó la generación: stop para un final natural, length si max_tokens lo cortó. Si omites max_tokens, la generación puede usar lo que quede de la ventana de 100.000 tokens, que cubre prompt y generación juntos.
Lo que te dicen los encabezados
Añade -i al comando curl y verás X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests y X-RateLimit-Limit-Concurrency. El encabezado de balance es útil en una demo porque puedes ver cómo baja una pequeña cantidad tras cada llamada. Para esta petición, el uso anterior equivale a 38 x $0.15 / 1.000.000 más 21 x $0.50 / 1.000.000, que es $0.0000057 más $0.0000105, unos $0.0000162.
Demo 2: streaming del script
Para audio rara vez quieres esperar al texto completo. Añade "stream": true y la API envía eventos SSE, una pequeña pieza de texto a la vez. El ejemplo de Node de abajo imprime texto a medida que llega, que es donde alimentarías una cola de frases.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.xtts.cc/v1",
apiKey: process.env.XTTS_API_KEY,
});
const stream = await client.chat.completions.create({
model: "uncensored",
stream: true,
messages: [
{ role: "user", content: "Read a four-line weather report for a coastal town." },
],
});
for await (const chunk of stream) {
const piece = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(piece);
}
process.stdout.write("\n");
Ejecútalo como un módulo ES (guárdalo como demo.mjs y ejecuta node demo.mjs tras npm install openai). En la red cada evento es una línea que comienza con data: seguida de JSON, y el streaming se cierra con un marcador final. El uso de tokens se informa al final del streaming. Un punto importante para la planificación: una petición en streaming mantiene su slot de concurrencia hasta que termina el streaming, así que un consumidor lento puede bloquear tu siguiente petición.
Demo 3: tool calling como router de voz
Tool calling permite al modelo devolver una instrucción estructurada en lugar de prosa. En un proyecto de voz es una forma limpia de elegir un estilo de entrega por línea. Defines una función llamada say, y el modelo rellena sus argumentos. Tu código decide luego qué hacer con ellos. El modelo no ejecuta nada por sí mismo.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.xtts.cc/v1", api_key=os.environ["XTTS_API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "say",
"description": "Queue one line for the voice engine.",
"parameters": {
"type": "object",
"properties": {
"text": {"type": "string"},
"style": {"type": "string", "enum": ["calm", "urgent", "whisper"]},
},
"required": ["text", "style"],
},
},
}]
messages = [
{"role": "system", "content": "Always answer by calling say, once per line."},
{"role": "user", "content": "The alarm sounds. The guard tells everyone to leave."},
]
r = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = r.choices[0].message
for call in msg.tool_calls or []:
args = json.loads(call.function.arguments)
print(args["style"], "->", args["text"])
Los argumentos llegan como una cadena JSON, así que analízalos y valídalos antes de usarlos. Los modelos pueden producir un estilo fuera de tu enumeración u omitir un campo, y un valor sin verificar nunca debe llegar a tu motor. Si quieres que la conversación continúe, añade el mensaje del asistente y una respuesta con role: "tool" y el tool_call_id correspondiente, luego llama a la API de nuevo.
Cuando se transmite, las llamadas a funciones llegan en piezas. El nombre de la función viene primero y la cadena de argumentos se construye a través de fragmentos, así que recopila fragmentos por índice y analízalos una vez que termine el stream.
Demo 4: modo JSON para una lista de reparto
Si prefieres omitir las definiciones de herramientas, el modo JSON proporciona JSON válido en el contenido del mensaje. Es una buena opción para convertir una escena aproximada en líneas por hablante.
curl -s https://api.xtts.cc/v1/chat/completions \
-H "Authorization: Bearer $XTTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"response_format": {"type": "json_object"},
"temperature": 0.2,
"messages": [
{"role": "system", "content": "Return JSON: {\"lines\": [{\"speaker\": string, \"text\": string}]}"},
{"role": "user", "content": "Ana asks Ben to hold the ladder. Ben agrees reluctantly."}
]
}'
El modo JSON garantiza que el análisis de la salida sea válido, no que coincida con tu forma. Describe la forma en el prompt, como arriba, y verifica las claves en el código. Una temperatura baja mantiene la estructura estable.
Demo 5: un documento largo en una petición
La ventana de contexto es de 100.000 tokens, compartida por prompt y completación. Eso es suficiente para enviar una transcripción larga o una historia corta completa y pedir una versión escrita para el oído. El cuerpo de la petición puede tener hasta 8 MB, así que el tamaño rara vez es el límite; el recuento de tokens lo es.
Aquí está el coste de una llamada pesada. Digamos que envías 80.000 tokens y recibes 2.000. Entrada: 80.000 x $0.15 / 1.000.000 = $0.012. Salida: 2.000 x $0.50 / 1.000.000 = $0.001. El total es $0.013, así que el crédito de prueba de $0.50 cubriría unas 38 llamadas como esta. La entrada larga es barata comparada con la salida larga, por eso los resúmenes y reescrituras de textos grandes son asequibles mientras generar una novela entera de una vez no lo es.
Un consejo práctico para entradas largas: pon tus instrucciones primero y repite la regla clave al final. Los modelos tienden a seguir mejor la instrucción más reciente, y un recordatorio de una línea después de 80,000 tokens de texto de origen cuesta casi nada.
Lectura de errores en el demo
Rompe algo a propósito una vez para reconocerlo después. Envía la petición con una clave incorrecta y obtendrás un error de autenticación en lugar de una generación. Envía diez peticiones al mismo instante desde una clave de prueba y algunas volverán como HTTP 429.
El 429 tiene tres causas, y el código de error las distingue:
rate_limitedsignifica demasiadas peticiones en un minuto: 60 en una clave de prueba, 300 en una clave completa.concurrencysignifica demasiadas peticiones en vuelo a la vez: 2 en una clave de prueba, 8 en una clave completa.- Un 429 con un encabezado
Retry-After: 5significa que el servicio estaba brevemente sobrecargado. Espera cinco segundos y envíalo de nuevo.
Las peticiones fallidas o rechazadas no se cobran, así que los errores no cuestan nada. Para ver los límites que tiene tu clave, lee X-RateLimit-Limit-Requests y X-RateLimit-Limit-Concurrency en cualquier respuesta normal. Un pequeño bucle de reintento que duerme el valor de Retry-After, o cinco segundos cuando falta, es todo lo que necesita un script de demo.
Qué intentar a continuación
Una vez que estas cuatro llamadas funcionen, tienes las piezas de una tubería de guiones. Envuelve la petición simple en una función, ejecuta el bucle de streaming en una cola, y conecta la cola al motor de voz de tu elección. Los motores difieren en precio, licencia y calidad, así que lee sus términos actuales. Este servicio no proporciona uno y no afirma nada sobre ellos.
Los costos se mantienen bajos mientras experimentas. A $0.15 por millón de tokens de entrada y $0.50 por millón de tokens de salida, una llamada de demostración típica cuesta una fracción de centavo, y la oferta de $0.50 cubre cientos de ellas. Consulta la página de precios para recargas desde $20 hasta $500 con bonos del 5% al 15%, pagaderas con cripto. La documentación cubre la lista completa de parámetros, límites de peticiones (8 simultáneas y 300 por minuto con una clave completa) y códigos de error. Los prompts no se usan para entrenamiento.
Un orden razonable para una primera tarde: ejecuta la petición simple hasta que el tono sea correcto, cambia al streaming e imprime oraciones a medida que se completan, luego añade ya sea llamadas a funciones o modo JSON, lo que coincida con la forma en que tu código de voz quiere su entrada. Mantén cada prompt en un archivo bajo control de versiones. Cuando una línea suene mal en el audio final, puedes rastrearla de vuelta a la instrucción exacta que la produjo y cambiar una cosa a la vez.
Más guías
Preguntas y respuestas
¿Puedo escuchar una voz de ejemplo en este demo?
No. La API devuelve solo texto, JSON y llamadas a funciones. Tú proporcionas un motor de voz separado para convertir el texto en audio.
¿Qué ID de modelo debo enviar?
Envía uncensored como valor del modelo, con la base URL https://api.xtts.cc/v1 y tu clave en el encabezado Authorization: Bearer.
¿Funcionan los demos con una clave de prueba?
Sí. Una clave de prueba permite 2 peticiones simultáneas y 60 por minuto, lo cual es suficiente para estos ejemplos. Ejecútalos uno a la vez.
¿Por qué obtengo una respuesta 429?
Superaste el límite de peticiones por minuto (rate_limited), tenías demasiadas peticiones simultáneas abiertas (concurrency) o el servicio estaba brevemente sobrecargado. Espera a que expire Retry-After si se proporciona, y luego reintenta.
Tu clave está a un formulario de distancia
Crea una cuenta, copia la clave, cambia la URL base. Esa es toda la configuración.