Rate limits
Limites de requisição por endpoint na Hub API, headers de controle, comportamento do status 429 e estratégias para evitar throttling.
Rate limits
A Hub API aplica rate limiting em duas camadas independentes para proteger o gateway de tráfego abusivo e isolar tenants em endpoints multi-tenant. A primeira camada é um limite global por IP em rotas sensíveis, executado no middleware antes do roteamento. A segunda é um limite por organização em endpoints de webhook, distribuído via Redis quando disponível e com fallback em memória local por pod.
Esta página descreve os limites em vigor, os headers retornados, o comportamento ao exceder a cota e como mitigar 429 Too Many Requests em integrações.
Limites padrão
O middleware global aplica um teto de 10 requisições por IP a cada 5 minutos sobre rotas autenticação e webhooks. O limite é compartilhado entre todos os pods do mesmo processo Node (in-memory), funcionando como primeira linha de defesa contra brute force e flood.
| Escopo | Limite | Janela | Estado |
|---|---|---|---|
| IP em rotas sensíveis | 10 req | 5 minutos | In-memory por pod |
| Organização em webhooks | 30 req | 1 minuto | Redis distribuído (com fallback in-memory) |
O bucket por IP é identificado pela chave <ip>:<path>, ou seja, cada rota tem contador independente. O IP é extraído da cadeia X-Forwarded-For (primeiro valor) ou X-Real-IP, com fallback para unknown.
O limite por IP é mantido em memória local de cada pod. Em ambientes com múltiplas réplicas, o limite efetivo é proporcional ao número de pods. Já o limite por organização nos webhooks é estritamente compartilhado entre pods via Redis.
Limites por endpoint
Endpoints com rate limit global por IP
As rotas abaixo estão sob o limite de 10 req/5min por IP, aplicado no middleware.ts:
POST /api/v1/auth/login
POST /api/v1/auth/register
POST /api/v1/auth/forgot-password
POST /api/v1/auth/reset-password
POST /api/v1/auth/refresh
ANY /api/v1/webhooks/*Esses caminhos são definidos em RATE_LIMITED_PATHS no middleware. Qualquer rota que comece com um desses prefixos é contabilizada.
Endpoints com rate limit por organização
As rotas de webhook aplicam um segundo limite por orgId, em cima do limite por IP:
POST /api/v1/webhooks/{orgId}/followize
POST /api/v1/webhooks/{orgId}/crm/pipefyO bucket é identificado por webhook:<provider>:<orgId> e usa Redis como backend principal. Se o Redis estiver indisponível, o limiter cai automaticamente para um Map em memória com janela fixa, capa de 10.000 entradas e limpeza periódica das chaves expiradas.
Demais endpoints
Endpoints fora das listas acima não têm rate limit aplicado pela API — proteção fica a cargo das camadas superiores (Ingress, WAF Cloudflare). Recomendamos ainda assim aplicar throttling do lado do cliente para integrações de alto volume.
Headers X-RateLimit-*
Quando uma requisição passa pelo middleware de rate limit global, a resposta inclui um header informando quantas requisições ainda estão disponíveis na janela atual:
HTTP/1.1 200 OK
X-RateLimit-Remaining: 7
Vary: Origin| Header | Significado |
|---|---|
X-RateLimit-Remaining | Requisições restantes na janela atual para o bucket <ip>:<path>. |
Retry-After | Em respostas 429, tempo em segundos até que a janela seja reiniciada. Atualmente fixo em 300 (5 minutos) para rotas globais. |
O limite por organização em webhooks não emite headers X-RateLimit-*. Para monitorar consumo desses endpoints, instrumente o cliente e observe ocorrências de 429 retornadas pela API.
429 Too Many Requests
Há duas formas de resposta 429, dependendo de qual camada disparou o bloqueio.
Bloqueio pelo limite global por IP
Quando o IP excede 10 requisições em 5 minutos em uma rota sensível, o middleware retorna:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 300
{
"error": "Too many requests"
}O header Retry-After: 300 indica que a janela só será reiniciada após 300 segundos. Não há reset progressivo — o contador é fixo dentro da janela.
Bloqueio pelo limite por organização em webhooks
Quando uma organização excede 30 requisições por minuto em um endpoint de webhook, a rota retorna:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": "Rate limit exceeded"
}Não há Retry-After nesse caso. A janela é fixa de 60 segundos a partir da primeira requisição que abriu o bucket. Se o Redis estiver disponível, o TTL é gerenciado por PEXPIRE NX (TTL definido apenas na criação da chave, sem reset em incrementos subsequentes).
Provedores externos (Followize, Pipefy) podem reentregar webhooks bloqueados por 429. Garanta que sua integração de processamento downstream seja idempotente — a dedupe é feita por externalId no ingest canônico.
Como otimizar
Backoff exponencial em integrações server-to-server
Implemente backoff com jitter ao receber 429. Para rotas globais, aguarde pelo menos o valor de Retry-After antes de retentar. Para webhooks, comece com 1 segundo e dobre a cada falha até um teto razoável (ex.: 32 segundos).
async function callWithBackoff(url: string, init: RequestInit) {
let delay = 1000;
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch(url, init);
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("Retry-After")) * 1000;
await new Promise((r) => setTimeout(r, retryAfter || delay));
delay = Math.min(delay * 2, 32000);
}
throw new Error("Rate limit persistente");
}Batching e deduplicação no cliente
Se sua integração dispara várias chamadas em sequência para a mesma organização (ex.: replay de webhooks históricos), agrupe-as em batches espaçados. Como o limite por org é de 30 req/min, distribua acima de 2 segundos entre requisições para se manter abaixo do teto.
Monitoramento de X-RateLimit-Remaining
Em integrações que tocam rotas de autenticação repetidamente (ex.: rotação programada de tokens), leia o header X-RateLimit-Remaining a cada resposta e pause proativamente quando o valor cair abaixo de um limiar (ex.: 2). Isso evita atingir o bloqueio duro de 5 minutos.
Uso correto de refresh em vez de login
O endpoint POST /api/v1/auth/login está sob o limite global e não deve ser chamado em cada requisição. Use POST /api/v1/auth/refresh para renovar o access token (15 min de TTL) com o refresh token (7 dias), e só caia em login quando o refresh falhar com reuse detection.
Veja Autenticação para o fluxo completo de rotação.
Webhooks idempotentes
Como provedores externos podem reentregar webhooks bloqueados, garanta que o handler downstream tolere reentrega da mesma mensagem. A Hub API já faz dedupe canônica por (provider, externalId) no ingest, mas integrações customizadas devem aplicar a mesma política.
Autenticação
Como autenticar requisições no Hub API: JWT HS256 de 15 minutos, refresh token de 7 dias com rotation e reuse detection, e Bearer interno para tráfego server-to-server.
Erros
Formato canônico de error response da Hub API, códigos HTTP utilizados, semântica de cada status e boas práticas para implementar handlers de erro resilientes em clientes.