Rate Limits
Limites de uso da engineAPI: headers, limites por plano, tratamento de 429 e retry com backoff.
Rate Limits
A engineAPI aplica limites de taxa para garantir estabilidade e performance para todos os parceiros. Os limites são aplicados por API Key.
Limites por plano
| Plano | Requests/segundo |
|---|---|
| Dev | 5 |
| Starter | 20 |
| Growth | 60 |
| Scale | 200 |
| Enterprise | Dedicado |
A janela do rate limit é sempre de 1 segundo. Não existe limite por minuto, hora ou
dia. O limite é aplicado por partnerId (não por IP) e vale para toda requisição
autenticada, emissão, consulta ou download.
Headers de rate limit
Toda resposta da API inclui headers que indicam seu consumo atual:
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1714200000
| Header | Descrição |
|---|---|
X-RateLimit-Limit | Total de requests permitidos no período |
X-RateLimit-Remaining | Requests restantes no período atual |
X-RateLimit-Reset | Timestamp Unix de quando o contador reseta |
Resposta 429 (Too Many Requests)
Quando o limite é atingido, a API retorna o mesmo envelope RFC 7807 usado em todos os erros (ver Erros e Rejeições):
{
"error": {
"type": "https://engineapi.com.br/errors/RATE_LIMIT_EXCEEDED",
"title": "Limite de Requisições Excedido",
"status": 429,
"detail": "Rate limit excedido. Seu plano permite 20 requests/segundo. Upgrade em https://engineapi.com.br/#pricing",
"instance": "/v1/nfe",
"requestId": "req_uofirusmuamw",
"timestamp": "2026-07-05T11:06:14.453Z"
}
}
Com o header adicional:
Retry-After: 1
Retry-After é sempre 1 (a janela do rate limit é de 1 segundo). Não é um valor
dinâmico calculado a partir do consumo.
Retry com backoff exponencial
Implemente retry automático para lidar com rate limits de forma elegante:
import { EngineApiClient, EngineApiError } from '@engineapi/sdk';
async function emitirComRetry(
client: EngineApiClient,
params: any,
maxRetries = 3
) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await client.nfe.emitir(params);
} catch (error) {
if (error instanceof EngineApiError && error.isRateLimited) {
if (attempt === maxRetries) throw error;
const waitMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
console.log(`Rate limited. Retry em ${waitMs}ms...`);
await new Promise(r => setTimeout(r, waitMs));
} else {
throw error; // Não é rate limit, propaga o erro
}
}
}
}
Boas práticas
Endpoints sem autenticação
Nenhum endpoint é isento de rate limit. O que muda é a régua aplicada:
| Requisição | Limite aplicado |
|---|---|
Autenticada (JWT ou x-api-key) | Limite do plano, por partner (tabela acima) |
Sem autenticação (GET /health, GET /health/live, GET /version) | Limite global por IP, separado do plano |
Os endpoints públicos de monitoramento vivem fora do prefixo /v1 (/health,
/health/live, /version) e não consomem o limite do seu plano: usam um limite
global por IP. Use GET /health à vontade para health check de infraestrutura.
Precisa de mais?
Se o seu volume ultrapassa os limites do plano Scale, entre em contato para um plano Enterprise personalizado:
- Email: suporte@engineapi.com.br
- Dashboard: app.engineapi.com.br