Pular para o conteúdo principal

Rate Limits

Para garantir estabilidade e disponibilidade da plataforma, a API Externa aplica limites de taxa por empresa.

Limites

EscopoLimiteJanela
Por empresa (companyId)100 requisicoes1 minuto (janela deslizante)

O limite e compartilhado entre todas as API Keys da mesma empresa. Ou seja, se a empresa possui 3 chaves ativas, as 3 dividem a mesma cota de 100 req/min.

Headers de Resposta

Todas as respostas da API incluem headers informativos sobre o consumo:

HeaderDescricaoExemplo
X-RateLimit-LimitLimite total na janela100
X-RateLimit-RemainingRequisicoes restantes73
X-RateLimit-ResetTimestamp Unix de quando o limite sera renovado1711324800

Exemplo de headers em uma resposta:

HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1711324800

Resposta ao Exceder o Limite (HTTP 429)

Quando o limite e ultrapassado, a API retorna:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 23
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711324800
{
"statusCode": 429,
"message": "RATE_LIMIT_EXCEEDED",
"friendlyMessage": "Limite de requisicoes excedido. Tente novamente em alguns segundos."
}

O header Retry-After indica quantos segundos aguardar antes de tentar novamente.

Estrategia de Retry — Exponential Backoff

Recomendamos implementar exponential backoff com jitter para lidar com erros 429:

tentativa 1: aguardar 1s  + jitter aleatorio (0-500ms)
tentativa 2: aguardar 2s + jitter aleatorio (0-500ms)
tentativa 3: aguardar 4s + jitter aleatorio (0-500ms)
tentativa 4: aguardar 8s + jitter aleatorio (0-500ms)
tentativa 5: aguardar 16s + jitter aleatorio (0-500ms)

Maximo de tentativas recomendado: 5

Exemplo em JavaScript:

async function requestWithRetry(fn, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.response?.status !== 429 || attempt === maxRetries - 1) {
throw error;
}

const retryAfter = error.response.headers['retry-after'];
const baseDelay = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.pow(2, attempt) * 1000;
const jitter = Math.random() * 500;

await new Promise(resolve => setTimeout(resolve, baseDelay + jitter));
}
}
}

Exemplo em Python:

import time
import random
import requests

def request_with_retry(method, url, max_retries=5, **kwargs):
for attempt in range(max_retries):
response = requests.request(method, url, **kwargs)

if response.status_code != 429:
return response

if attempt == max_retries - 1:
response.raise_for_status()

retry_after = response.headers.get("Retry-After")
if retry_after:
delay = int(retry_after)
else:
delay = (2 ** attempt)

jitter = random.uniform(0, 0.5)
time.sleep(delay + jitter)

return response

Dicas para Otimizar o Consumo

  • Cache respostas de leitura (GET) quando os dados nao mudam com frequencia
  • Agrupe operacoes em lotes ao inves de chamadas individuais
  • Utilize filtros e paginacao para reduzir o volume de dados por requisicao
  • Monitore os headers X-RateLimit-Remaining para ajustar a cadencia das chamadas proativamente
  • Distribua chamadas ao longo do tempo ao inves de enviar rajadas (burst)