Erros
Todo erro tem a mesma forma: o status HTTP, um code em inglês para o seu código decidir e uma message em português para pessoas.
A forma do erro
{
"error": {
"code": "insufficient_balance",
"message": "Saldo insuficiente. Recarregue em console › Faturamento.",
"request_id": "req_01JAA4M7Q2W8E5R3T6Y9U1I0PZ"
}
}O request_id é o mesmo do cabeçalho X-Request-Id. Guarde no seu log e mande no suporte: com ele a gente acha o pedido.
Todos os códigos
| HTTP | Código | Quando | O que fazer |
|---|---|---|---|
| 400 | invalid_request | Corpo, parâmetro ou mensagem fora do formato: text vazio, voice desconhecida, speed fora da faixa, keyterms com mais de 100 termos, URL que não normaliza. | Leia a message, que diz o campo, e corrija o pedido. Repetir igual dá o mesmo erro. |
| 401 | invalid_api_key | Sem o cabeçalho Authorization, chave que não existe, token temporário malformado ou com assinatura errada, ou chave int8_live_ na URL. | Mande Authorization: Bearer int8_live_… no servidor, ou ?token=int8_tmp_… no WebSocket do navegador. |
| 401 | api_key_expired | A chave passou da data de expiração, ou o token temporário passou do expires_at. | Crie uma chave nova no console, ou peça um token novo em POST /v1/tokens. |
| 401 | api_key_revoked | Alguém revogou a chave no console. Vale em até 15 s para pedidos novos. Nos WebSockets, a voz e o avatar recusam a próxima fala, e a transcrição ao vivo fecha em até 75 s (60 s entre conferências mais 15 s de cache). | Troque pela chave nova. Os tokens emitidos pela chave revogada param de valer junto. |
| 402 | insufficient_balance | O saldo da organização não é maior que zero, ou (no lote) não cobre o custo estimado somado ao dos jobs na fila. | Recarregue em console › Faturamento. O crédito do PIX entra em segundos. |
| 403 | ip_not_allowed | A chave tem whitelist e o IP de quem chamou não está nela. | Inclua o IP (ou a faixa CIDR) na chave, em console › Chaves de API › Editar. |
| 403 | scope_denied | A chave (ou o token) não tem o escopo da rota (stt, tts ou avatar), ou um token tentou emitir outro token. | Edite os escopos da chave no console, ou emita o token com o escopo certo. |
| 404 | not_found | A transcrição não existe, é de outra organização ou passou dos 30 dias de retenção. | Confira o id. Depois de 30 dias o resultado não volta: guarde o que precisar. |
| 405 | method_not_allowed | O caminho existe, mas não com esse método (por exemplo, PUT /v1/tts). | Veja o método certo na referência da API. |
| 409 | conflictrepita depois | Exportar (/export) uma transcrição que não está completed. | Espere o job concluir (ou o webhook transcription.completed) e exporte de novo. |
| 413 | payload_too_large | Corpo acima do teto da rota (500 MB no lote, 128 KB na voz, 64 KB no resto), text acima do limite, áudio acima de 4 h ou fala do avatar acima de 5 min. | Divida o pedido. Os limites estão na página Limites. |
| 415 | unsupported_media | O arquivo não é um áudio que o decodificador lê, ou o corpo não é multipart/form-data nem JSON. | Mande wav, mp3, m4a/aac, ogg/opus, flac, webm ou mp4. Confira se o arquivo abre num player. |
| 429 | rate_limitedrepita depois | Mais de 120 pedidos REST por minuto na mesma chave ou, na transcrição ao vivo, áudio mais rápido que o tempo real. | Espere os segundos do Retry-After e repita. Na transcrição ao vivo, mande o áudio no ritmo da fala. |
| 429 | concurrency_limitedrepita depois | A organização passou do limite de pedidos ao mesmo tempo: 8 vozes, 10 transcrições ao vivo ou 5 avatares. | Espere um pedido terminar, ou enfileire do seu lado. |
| 500 | internal_errorrepita depois | Falha do nosso lado. Um pedido que falha antes de começar não é cobrado. | Repita com espera crescente. Se continuar, mande o request_id para o suporte. |
| 503 | server_busyrepita depois | A fila de inferência está cheia. | Espere o Retry-After e repita. |
| 503 | model_unavailablerepita depois | O modelo do produto não está carregado (por exemplo, logo depois de uma reinicialização). | Confira GET /v1/health e repita em alguns segundos. |
Repetir ou não
Repita só o que pode dar certo da próxima vez: rate_limited, concurrency_limited, server_busy, model_unavailable, internal_error e conflict (repita depois que o job concluir). Respeite o Retry-After quando vier, e espere cada vez mais entre as tentativas. Os outros erros se repetem iguais até você mudar o pedido, a chave ou o saldo.
import osimport timeimport requestsREPETE = {429, 500, 503}def chamar(caminho: str, **kwargs) -> requests.Response:"""Repete 429, 500 e 503 respeitando o Retry-After; os outros erros sobem com a mensagem da API."""for tentativa in range(5):resposta = requests.post(f"https://api.int8labs.com{caminho}",headers={"Authorization": f"Bearer {os.environ['INT8_API_KEY']}"},timeout=60,**kwargs,)if resposta.status_code in REPETE and tentativa < 4:time.sleep(float(resposta.headers.get("Retry-After", 2**tentativa)))continueif resposta.status_code >= 400:erro = resposta.json()["error"]raise RuntimeError(f'{erro["code"]}: {erro["message"]} ({erro["request_id"]})')return respostaraise RuntimeError("sem resposta depois de 5 tentativas")audio = chamar("/v1/tts", json={"text": "Olá!", "voice": "eduardo"}).content
Nos WebSockets
No WebSocket, o erro chega como mensagem, {"type":"error","code","message","request_id"}, com os mesmos códigos. Os que encerram a sessão vêm seguidos do fechamento 4000 + o status HTTP:
| Fechamento | Quando |
|---|---|
1000 | Fim normal: depois do done da transcrição ao vivo, por ociosidade ou ao passar de 4 h de sessão. |
4400 | invalid_request na transcrição ao vivo ou no modo áudio do avatar. Na voz e no modo texto do avatar, o erro de uma fala chega sem fechar a conexão. |
4401 | invalid_api_key, api_key_expired ou api_key_revoked, no começo ou no meio da sessão. Na transcrição ao vivo, os final do áudio já recebido chegam antes do erro. |
4402 | insufficient_balance: o saldo acabou. O que já foi falado ou ouvido é cobrado; na transcrição ao vivo, os final desse áudio chegam antes do erro. |
4403 | ip_not_allowed ou scope_denied. |
4413 | payload_too_large no modo áudio do avatar (fala acima de 5 min). |
4429 | rate_limited (áudio mais rápido que o tempo real) ou concurrency_limited (WebSockets demais na organização). |
4500 | internal_error. |
4503 | server_busy ou model_unavailable. |
Na voz e no modo texto do avatar, os erros de uma fala (invalid_request, payload_too_large, server_busy e concurrency_limited) não fecham a conexão: mande a próxima fala. Na transcrição ao vivo e no modo áudio do avatar, todo erro fecha.