Rate limits
Limites de requisição da API Simplafy Seguros, comportamento do código 429, headers expostos pelo throttler e estratégias para evitar bloqueios.
Rate limits
A API Simplafy Seguros aplica rate limiting com @nestjs/throttler para proteger endpoints contra abuso, evitar custos inesperados em operações destrutivas (INSERT/UPDATE/DELETE) e preservar latência das agregações de KPI. Os limites são contabilizados por IP do cliente, dentro de uma janela deslizante (TTL).
Esta página descreve os limites padrão, o que aparece nos headers da resposta, como reagir ao HTTP 429 e como otimizar o consumo da API.
Limites padrão
O limite global é configurado em src/app.module.ts e vale para todos os endpoints que não declaram override.
| Escopo | Limite | Janela (TTL) | Aplicação |
|---|---|---|---|
| Global (default) | 20 requisições | 60 segundos | Todos os endpoints |
KPI SDR (/kpi/sdr, /kpi/sdr/trending, /kpi/subscription-leads) | 10 requisições | 60 segundos | Agregações de KPI |
AI Agent (/ai/execute) | 20 requisições | 60 segundos | Execução de operações via agente IA |
Vendas manuais (POST /api/sales/manual) | 10 requisições | 5 minutos (300 s) | Inclusão manual de vendas |
O contador é por origem da requisição (IP) e por janela. Quando a janela expira, o contador é reiniciado — não é um balde token-bucket com refil contínuo.
Endpoints com limite mais restritivo declaram um override com o decorator @Throttle:
@Throttle({ default: { limit: 10, ttl: 60000 } })
@Get('sdr')
async getKpis(...) { ... }@Throttle({ default: { limit: 10, ttl: 300000 } }) // 10 requests per 5 minutes
@Post('manual')
async createManualSale(...) { ... }Headers de rate limit
O ThrottlerGuard do NestJS expõe headers padrão em toda resposta de endpoint protegido pelo guard. Use-os para monitorar o consumo da janela atual sem precisar contabilizar do lado do cliente.
| Header | Significado |
|---|---|
X-RateLimit-Limit | Número máximo de requisições permitidas na janela atual. |
X-RateLimit-Remaining | Quantas requisições ainda restam até atingir o limite. |
X-RateLimit-Reset | Segundos até a janela atual ser reiniciada. |
Retry-After | Presente apenas em respostas 429. Indica em segundos quando uma nova tentativa será aceita. |
Exemplo de resposta bem-sucedida próxima do limite:
curl -i https://api-seguros.simplafy.com.br/kpi/sdr \
-H "Authorization: Bearer $TOKEN"HTTP/1.1 200 OK
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 2
X-RateLimit-Reset: 37
Content-Type: application/json429 e backoff
Quando o limite é excedido, a API retorna 429 Too Many Requests. O corpo segue o formato padrão de erros do NestJS:
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests"
}O header Retry-After informa quantos segundos aguardar antes da próxima tentativa. Trate o erro com backoff respeitando esse valor.
Capture o 429. Verifique response.status === 429 antes de tratar a resposta como erro genérico.
Leia Retry-After. Use o valor exato em segundos retornado pelo servidor. Se ausente, aplique backoff exponencial começando em 1 segundo.
Aguarde e refaça. Reenvie a mesma requisição após a espera. Em pipelines críticos, limite o número de retries (recomendado: 3 tentativas).
Falhe explicitamente. Após o último retry, propague o erro para o chamador em vez de silenciar — o consumo provavelmente está acima do dimensionado.
Exemplo de retry com backoff em TypeScript:
async function fetchWithRetry(url: string, init: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, init);
if (response.status !== 429) {
return response;
}
if (attempt === maxRetries) {
throw new Error(`Rate limited after ${maxRetries} retries`);
}
const retryAfter = Number(response.headers.get("retry-after") ?? 1);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
}
}Não tente contornar o limite com múltiplos IPs ou tokens. Endpoints destrutivos (POST /api/sales/manual, /ai/execute) têm limites mais baixos justamente porque cada chamada tem efeito colateral (insert, update, side-effects no banco). Burlar o limite pode gerar inconsistência de dados.
Como otimizar
Antes de subir os limites de um cliente, revise o padrão de consumo. A maior parte dos 429 vem de loops síncronos ou polling agressivo, não de carga legítima.
Reduza polling
Em vez de fazer polling em /kpi/sdr a cada poucos segundos, prefira janelas mais largas (60 s+) e cache no cliente. Os KPIs são agregações pesadas — chamar com frequência alta não retorna dados mais frescos, apenas consome janela.
Use filtros do servidor
Liste com paginação e filtros (startDate, endDate, agentId) em vez de baixar tudo e filtrar no cliente. Cada requisição economizada conta na janela.
Faça batch quando possível
Para POST /api/sales/manual, agrupe inclusões manuais em batches espaçados em vez de uma chamada por linha. O limite é 10 requisições por 5 minutos, então 60 inclusões enfileiradas levam 30 minutos no fluxo atual.
Inspecione os headers em produção
Adicione observabilidade nos headers X-RateLimit-Remaining e X-RateLimit-Reset. Quando Remaining cai consistentemente para zero antes do Reset, é sinal de que o consumo está mal distribuído na janela.
console.log({
limit: response.headers.get("x-ratelimit-limit"),
remaining: response.headers.get("x-ratelimit-remaining"),
reset: response.headers.get("x-ratelimit-reset"),
});Para integrações que precisam de limites diferentes (cargas iniciais, sincronização periódica), abra um chamado descrevendo o caso de uso, endpoints envolvidos e volume esperado.
Próximos passos
Autenticação
Como autenticar requisições na Seguros API com API keys (x-api-key) ou JWT em cookie httpOnly / header Bearer, incluindo permissões e códigos de erro.
Erros
Formato canônico das respostas de erro da Simplafy Seguros API, lista de códigos HTTP e códigos internos, e como tratá-los no cliente.