ttsapi

API de texto-pra-voz (TTS) e transcrição de áudio. Precisa de uma chave de acesso pra usar.

Cadastrar Entrar (já tenho conta)

Fluxo de cadastro

  1. Cadastra nome/email em /cadastro.html
  2. Confirma o email pelo link mágico que chega na caixa de entrada
  3. Aguarda o admin aprovar o cadastro
  4. Entra em /painel.html (login por link, sem senha) e cria suas chaves de API por lá

Autenticação

Todo request precisa do header:

Authorization: Bearer SUA_CHAVE

(ou X-API-Key: SUA_CHAVE).

códigomotivo
401chave ausente ou inválida
403email não verificado, ou cadastro aguardando aprovação do admin
402créditos insuficientes

Créditos e uso

Cada chave de API (criada no /painel.html) tem seu próprio saldo de créditos, definido pelo admin. Consumo:

endpointcusto
/api/tts1 crédito por caractere do texto enviado (checado antes de gerar; estornado se falhar)
/api/transcricao1 crédito por token retornado pelo provedor (checado depois de transcrever, exige saldo > 0 antes de começar)

POST /api/tts

{
  "texto": "texto a narrar",
  "engine": "edge",
  "voz": "antonio",
  "rate": "+0%",
  "pitch": "+0Hz"
}

Resposta: audio/mpeg (mp3).

enginevozobs
edgeantoniomasculina, pt-BR
franciscafeminina, pt-BR
thalitafeminina, pt-BR
duartemasculina, pt-PT
pipercadumasculina, offline, empacotada (resposta rápida)
fabermasculina, offline, baixada sob demanda
jeffmasculina, offline, baixada sob demanda
edressonmasculina, offline, baixada sob demanda

rate e pitch só valem pra engine edge.

POST /api/transcricao

Body: bytes crus do áudio. Headers opcionais:

headerdefault
X-Audio-Filenameaudio.mp3
X-Idiomapt
curl -X POST https://ttsapi-delta.vercel.app/api/transcricao \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "X-Audio-Filename: fala.mp3" \
  --data-binary @fala.mp3

Provedor usado, em ordem de prioridade (o primeiro configurado no servidor):

provedormodelo
Groqwhisper-large-v3-turbo
OpenAIwhisper-1
OpenRouteropenai/whisper-large-v3 (padrão, configurável via OPENROUTER_STT_MODEL)

Outros modelos de transcrição disponíveis no OpenRouter (preço por minuto de áudio):

modelopreço/min
qwen/qwen3-asr-flash$0.000035
nvidia/parakeet-tdt-0.6b-v3$0.0015
openai/whisper-large-v3$0.0015
mistralai/voxtral-mini-transcribe$0.003
openai/whisper-1$0.016
google/chirp-3$0.016

Textos longos (evitar timeout)

/api/tts não quebra o texto sozinho. Se a síntese passar do timeout da function, ela é encerrada à força e o crédito já debitado não volta (o estorno automático só roda se o próprio código Python falhar, não quando a Vercel mata o processo por tempo).

Quebre o texto no seu lado, respeitando fim de frase, em pedaços de até ~3000 caracteres, chame /api/tts uma vez por pedaço, e concatene os .mp3 recebidos (colar os bytes um atrás do outro já funciona pra tocar em sequência).

import re, requests

def dividir_em_pedacos(texto, tamanho_max=3000):
    frases = re.split(r'(?<=[.!?])\s+', texto)
    pedacos, atual = [], ''
    for frase in frases:
        if len(atual) + len(frase) + 1 > tamanho_max:
            pedacos.append(atual.strip())
            atual = frase
        else:
            atual = f'{atual} {frase}'.strip()
    if atual:
        pedacos.append(atual)
    return pedacos

audio_completo = bytearray()
for pedaco in dividir_em_pedacos(texto_longo):
    resposta = requests.post(
        'https://SEU-DEPLOY.vercel.app/api/tts',
        headers={'Authorization': 'Bearer SUA_CHAVE'},
        json={'texto': pedaco, 'engine': 'edge', 'voz': 'antonio'},
    )
    resposta.raise_for_status()
    audio_completo.extend(resposta.content)

Custo em créditos é por caractere, cobrado em cada pedaço — quebrar não aumenta o custo total, só evita o timeout.

Limites a saber

Textos/áudios muito longos podem estourar o timeout da function (10-60s conforme plano Vercel) — ver seção acima. Corpo de request tem limite de tamanho (~4.5MB). Vozes Piper não empacotadas dependem de download da HuggingFace no cold start.