Erros e rate limits
Esta página descreve o formato padrão de erro da API do vario, os códigos de aplicação possíveis, os limites de taxa por plano e as recomendações para lidar com falhas de forma resiliente.
Formato padrão de erro
Todos os erros retornam um objeto JSON com a seguinte estrutura:
{
"error": {
"code": "ERROR_CODE",
"message": "Descrição legível do erro."
}
}
O campo code é um identificador estável em inglês que você pode usar na sua lógica de tratamento de erros. O campo message é informativo e pode mudar entre versões; não dependa dele para lógica de negócio.
Tabela de códigos de erro
| HTTP | Código | Descrição | O que fazer |
|---|---|---|---|
400 | TEXT_TOO_LONG | O campo text excede 8.000 caracteres. | Dividir o texto em chunks e enviar múltiplas requisições. |
400 | INVALID_LANGUAGE | O idioma enviado não é suportado para o playbook selecionado. | Usar "es" ou "pt". Consultar GET /v1/playbooks. |
400 | INVALID_PLAYBOOK | O valor de playbook não existe no catálogo. | Consultar GET /v1/playbooks para obter a lista de valores válidos. |
400 | INVALID_MODE | O valor de mode não é válido. | Usar "screening", "fast" ou "full". |
400 | CONTEXT_TOO_LONG | thread_context excede 10 elementos, ou algum elemento excede 500 caracteres. | Reduzir a quantidade de mensagens de contexto ou truncar os elementos mais longos. |
400 | VALIDATION_ERROR | O schema da requisição é inválido. | Revisar a estrutura do corpo contra a referência de POST /v1/analyze. |
401 | INVALID_API_KEY | A API key não existe, está expirada ou foi revogada. | Verificar a key no portal. |
401 | MISSING_AUTH | O header Authorization está ausente. | Incluir Authorization: Bearer vario_SUA_API_KEY. |
402 | SUBSCRIPTION_REQUIRED | O tenant não possui assinatura ativa. | Verificar o status da conta no portal. |
402 | INSUFFICIENT_CREDITS | O saldo de créditos do tenant é zero. | Adquirir créditos adicionais. Ver Compra de créditos. |
403 | INSUFFICIENT_SCOPE | A API key não tem o escopo necessário. | Gerar uma nova key com os escopos necessários. |
409 | email_already_registered | O e-mail já possui uma conta API-only cadastrada. | Recuperar a key existente ou revogá-la e criar uma nova pelo portal. |
429 | RATE_LIMIT_EXCEEDED | O limite de chamadas permitido foi excedido. | Implementar backoff exponencial. Respeitar o header Retry-After. |
503 | DEEP_ANALYSIS_UNAVAILABLE | Retornado apenas quando a requisição inclui Prefer: deep-analysis-required e a análise profunda não está disponível. | Omitir o header para receber uma resposta parcial, ou retentar com backoff. |
503 | PRICING_NOT_CONFIGURED | O pacote de créditos solicitado ainda não tem preço configurado. | Consultar GET /api/public/checkout/credits/preview ou entrar em contato com [email protected]. |
500 | PIPELINE_ERROR | Erro interno do pipeline. O texto não foi analisado. | Retentar. Se o erro persistir, reportar para [email protected] com o timestamp da requisição. |
Rate limits por plano
Os limites de taxa são aplicados por API key e medidos em duas janelas: por minuto e por dia.
| Plano | Chamadas por minuto | Chamadas por dia |
|---|---|---|
| API-only (trial / sem seats) | 60 | 10.000 |
| Essentials | 60 | 10.000 |
| Professional | 300 | 100.000 |
| Enterprise | 1.000 | 500.000 |
Quando o limite é atingido, o servidor responde com 429 RATE_LIMIT_EXCEEDED e inclui o header Retry-After com os segundos que você deve aguardar antes de retentar.
Recomendações de resiliência
Backoff exponencial com jitter
Ao receber um 429 ou um 503, não retente imediatamente. Implemente um backoff exponencial com componente aleatório (jitter) para evitar que múltiplos clientes atinjam o servidor ao mesmo tempo:
import time
import random
def call_with_backoff(fn, max_retries=5):
for attempt in range(max_retries):
response = fn()
if response.status_code not in (429, 503):
return response
retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
sleep_time = retry_after + random.uniform(0, 1)
time.sleep(sleep_time)
raise Exception("Max retries exceeded")
Monitorar X-RateLimit-Remaining
Se o header X-RateLimit-Remaining estiver presente na resposta, use-o para antecipar o esgotamento do limite antes de receber um 429. Quando o valor estiver baixo, reduza a cadência de requisições.
Estratégia de modo por volume
Para corpora massivos, use mode=fast como primeira passagem. Reserve mode=full para os textos que exigirem análise mais profunda. Isso reduz o consumo de créditos e o risco de atingir o rate limit em janelas curtas.
Degradação da análise
Quando a requisição não inclui o header Prefer: deep-analysis-required, uma falha na análise profunda retorna 200 com bedrock_available: false e uma análise parcial. Verifique esse campo se precisar garantir a profundidade completa da análise antes de tomar uma decisão.
Exemplo: tratamento do erro INSUFFICIENT_CREDITS
import httpx
response = httpx.post(
"https://api.vario.lat/v1/analyze",
headers={"Authorization": "Bearer vario_SUA_API_KEY"},
json={"text": "...", "playbook": "price_fixing", "language": "pt"}
)
if response.status_code == 402:
error = response.json()["error"]
if error["code"] == "INSUFFICIENT_CREDITS":
# Notificar a equipe para recarregar créditos
raise InsufficientCreditsError("Recarga de créditos necessária.")