Demo da API TTS: Exemplos de requisições e respostas ao vivo
Este demo mostra requisições reais que você pode executar em um minuto e o formato de resposta retornado. A API é um modelo de texto, então a saída é texto de roteiro, JSON e chamadas de função que um motor de fala separado pode então ler em voz alta.
Atualizado

Antes de executar qualquer coisa
Um aviso justo para quem espera pressionar play e ouvir uma voz: este demo da api tts não produz som. O serviço retorna texto de um modelo, uncensored, via POST /v1/chat/completions. Há um segundo endpoint, GET /v1/models, para listar o que está disponível. Nada retorna áudio, imagens ou embeddings.
Por que um demo então? Porque muitos projetos de fala precisam exatamente desta parte: um escritor de roteiro, um limpador de texto, um splitter que decide quem diz o quê. Os exemplos abaixo mostram esses trabalhos, e o formato de saída é o que seu código de fala irá analisar.
Você precisa de uma chave. Cadastre-se na página da chave de API com Google ou com email e senha, depois reclame o crédito de teste de $0,50 com um clique. Ele é válido por 7 dias e não precisa de cartão. Exporte a chave para que os comandos abaixo possam lê-la:
export XTTS_API_KEY="paste-your-key-here"
curl -s https://api.xtts.cc/v1/models -H "Authorization: Bearer $XTTS_API_KEY" | grep uncensored
Se essa chamada retornar uma lista JSON que inclua uncensored, a chave funciona e você pode continuar.
Demo 1: uma solicitação simples
A chamada útil mais simples pede um parágrafo curto no estilo falado:
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
}'
A resposta se parece com a amostra abaixo. O texto dentro de content será diferente a cada execução, então trate-o como uma ilustração da estrutura e não como saída gravada.
{
"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}
}
Seu código de fala lê choices[0].message.content. O finish_reason diz por que a geração terminou: stop para um fim natural, length se max_tokens o cortar antes. Se você omitir max_tokens, a conclusão pode usar o que restar da janela de 100.000 tokens, que cobre prompt e conclusão juntos.
O que os cabeçalhos dizem
Adicione -i ao comando curl e você verá X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests e X-RateLimit-Limit-Concurrency. O cabeçalho de saldo é útil em um demo porque você pode vê-lo cair por uma pequena quantidade após cada chamada. Para esta solicitação, o uso acima resulta em 38 x $0,15 / 1.000.000 mais 21 x $0,50 / 1.000.000, que é $0,0000057 mais $0,0000105, cerca de $0,0000162.
Demo 2: streaming do script
Para áudio, você raramente quer esperar pelo texto completo. Adicione "stream": true e a API envia server-sent events, um pequeno pedaço de texto de cada vez. O exemplo Node abaixo imprime texto conforme ele chega, onde você alimentaria uma fila 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");
Execute-o como um módulo ES (salve como demo.mjs e execute node demo.mjs após npm install openai). Na rede, cada evento é uma linha começando com data: seguida por JSON, e o stream fecha com um marcador final. O uso de tokens é relatado no final do stream. Um ponto importante para o planejamento: uma solicitação em stream mantém seu slot de concorrência até o fim do stream, então um consumidor lento pode bloquear sua próxima solicitação.
Demo 3: chamada de funções como roteador de fala
Chamada de função permite que o modelo devolva uma instrução estruturada em vez de prosa. Em um projeto de voz, isso é uma maneira limpa de escolher um estilo de entrega por linha. Você define uma função chamada say, e o modelo preenche seus argumentos. Seu código então decide o que fazer com eles. O modelo não executa nada por conta própria.
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"])
Os argumentos chegam como uma string JSON, então analise-os e valide antes de usar. Modelos podem produzir um estilo fora do seu enum ou omitir um campo, e um valor não verificado nunca deve chegar ao seu motor. Se quiser que a conversa continue, anexe a mensagem do assistant e uma resposta com role: "tool" e o tool_call_id correspondente, depois chame a API novamente.
Ao fazer streaming, as chamadas de funções chegam em pedaços. O nome da função vem primeiro e a string de argumentos se constrói ao longo dos blocos, então colete fragmentos por índice e faça o parse apenas quando o streaming terminar.
Demo 4: modo JSON para uma lista de elenco
Se preferir pular definições de função, o modo JSON fornece JSON válido no conteúdo da mensagem. É um bom ajuste para transformar uma cena aproximada em linhas por falante.
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."}
]
}'
O modo JSON garante que a saída seja analisada, não que corresponda ao seu formato. Descreva o formato no prompt, como acima, e verifique as chaves no código. Temperatura baixa mantém a estrutura estável.
Demo 5: um documento longo em uma solicitação
A janela de contexto tem 100.000 tokens, compartilhada por prompt e conclusão. Isso é suficiente para enviar uma transcrição longa ou uma história curta inteira e pedir uma versão escrita para o ouvido. O corpo da solicitação pode ter até 8 MB, então o tamanho raramente é o limite; a contagem de tokens é.
Aqui está o custo de uma chamada pesada. Digamos que você envie 80.000 tokens e receba 2.000 de volta. Entrada: 80.000 x $0,15 / 1.000.000 = $0,012. Saída: 2.000 x $0,50 / 1.000.000 = $0,001. O total é $0,013, então o crédito de teste de $0,50 cobriria cerca de 38 chamadas como essa. Entrada longa é barata comparada com saída longa, por isso resumos e reescritas de textos grandes são acessíveis, enquanto gerar um romance inteiro de uma vez não é.
Uma dica prática para entradas longas: coloque suas instruções primeiro e repita a regra principal no final. Modelos tendem a seguir a instrução mais recente melhor, e um lembrete de uma linha após 80.000 tokens de texto de fonte custa quase nada.
Lendo erros no demo
Quebre algo de propósito uma vez para reconhecê-lo depois. Envie a solicitação com uma chave errada e você receberá um erro de autenticação em vez de uma conclusão. Envie dez solicitações ao mesmo instante a partir de uma chave de teste e algumas retornarão como HTTP 429.
O 429 tem três causas, e o código de erro as distingue:
rate_limitedsignifica muitas requisições em um minuto: 60 em uma chave de teste, 300 em uma chave completa.concurrencysignifica muitas requisições pendentes ao mesmo tempo: 2 em uma chave de teste, 8 em uma chave completa.- Um 429 com um cabeçalho
Retry-After: 5significa que o serviço estava brevemente sobrecarregado. Aguarde cinco segundos e envie novamente.
Solicitações falhas ou recusadas não são cobradas, então erros não custam nada. Para ver os limites da sua chave, leia X-RateLimit-Limit-Requests e X-RateLimit-Limit-Concurrency em qualquer resposta normal. Um pequeno loop de reenvio que dorme pelo valor de Retry-After, ou cinco segundos quando ausente, é tudo que um script de demo precisa.
O que tentar a seguir
Depois que essas quatro chamadas funcionarem, você tem as peças de um pipeline de script. Envolva a solicitação simples em uma função, execute o loop de streaming em uma fila e conecte a fila ao motor de fala da sua escolha. Os motores diferem em preço, licença e qualidade, então leia seus termos atuais. Este serviço não fornece um e não afirma nada sobre eles.
Os custos permanecem baixos enquanto você experimenta. A $0,15 por milhão de tokens de entrada e $0,50 por milhão de tokens de saída, uma chamada de demo típica custa uma fração de centavo, e o crédito de teste de $0,50 cobre centenas deles. Veja a página de preços para recarregamentos de $20 a $500 com bônus de 5% a 15%, pagáveis por cripto. A documentação cobre a lista completa de parâmetros, limites de requisições (8 simultâneos e 300 por minuto com uma chave completa) e códigos de erro. Os prompts não são usados para treinamento.
Uma ordem razoável para uma primeira tarde: execute a solicitação simples até o tom estar certo, mude para streaming e imprima frases conforme completam, depois adicione ou tool calls ou modo JSON, o que corresponder à maneira como seu código de fala quer sua entrada. Mantenha cada prompt em um arquivo sob controle de versão. Quando uma linha soa errada no áudio final, você pode rastrear de volta à instrução exata que a produziu e alterar uma coisa de cada vez.
Mais guias
Perguntas e respostas
Posso ouvir uma amostra de voz neste demo?
Não. A API retorna apenas texto, JSON e tool calls. Você fornece um motor de fala separado para converter o texto em áudio.
Qual ID de modelo eu envio?
Envie uncensored como valor do modelo, com a URL base https://api.xtts.cc/v1 e sua chave no cabeçalho Authorization: Bearer.
Os demos funcionam com uma chave de teste?
Sim. Uma chave de teste permite 2 requisições simultâneas e 60 por minuto, o que é suficiente para estes exemplos. Execute-os um de cada vez.
Por que recebo uma resposta 429?
Você ultrapassou o limite de solicitações por minuto (rate_limited), tinha muitas solicitações abertas ao mesmo tempo (concurrency) ou o serviço estava brevemente sobrecarregado. Aguarde o Retry-After se fornecido, então faça o reenvio.
Sua chave está a um formulário de distância
Crie uma conta, copie a chave e altere a URL base. Essa é toda a configuração.