Tratamento de Erros
Como a API NFe/CTe Inbound sinaliza erros e como seu cliente deve reagir.
Sumário
Formato do Erro
Quando ocorre um erro, a API retorna um JSON no seguinte formato:
{
"errors": [
{
"code": 404,
"message": "Document not found for the given access key."
}
]
}
Códigos HTTP
| HTTP | Significa | O que fazer |
|---|---|---|
200 | Sucesso | Processe a resposta normalmente |
204 | Sucesso sem conteúdo | Operação realizada, sem corpo de resposta |
400 | Requisição inválida | Verifique os parâmetros enviados |
401 | Não autorizado | Verifique sua API Key ou token |
403 | Proibido | Sua conta não tem permissão para este recurso |
404 | Não encontrado | O documento/empresa não existe |
409 | Conflito (duplicado) | Recurso já existe |
422 | Entidade não processável | Dados válidos mas não processáveis (ex: NF-e cancelada) |
503 | Serviço indisponível | SEFAZ temporariamente fora. Tente novamente em alguns minutos |
504 | Timeout | A operação demorou muito. Tente novamente |
500 | Erro interno | Entre em contato com o suporte |
Headers de Rate Limiting
Todas as respostas incluem headers indicando o status do rate limit:
| Header | Descrição |
|---|---|
X-RateLimit-Limit | Total de requisições permitidas por janela |
X-RateLimit-Remaining | Requisições restantes na janela atual |
X-RateLimit-Reset | Timestamp Unix quando a janela reinicia |
Quando o limite é excedido, a API retorna 429 Too Many Requests. Aguarde até X-RateLimit-Reset antes de tentar novamente.
Estratégia de Retry
Para erros 429, 503 e 504, recomendamos retry com backoff exponencial:
import time
import requests
def get_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
reset_time = int(response.headers.get('X-RateLimit-Reset', time.time() + 60))
wait_time = max(reset_time - time.time(), 1)
time.sleep(wait_time)
continue
if response.status_code in (503, 504):
wait_time = (2 ** attempt) * 1 # 1s, 2s, 4s
time.sleep(wait_time)
continue
return response
raise Exception("Max retries exceeded")