Rate limiting
Cotas por API key nas rotas públicas, headers de resposta, padrão de retry e ajuste de limites.
A API pública da Allya Payments aplica rate limiting por API key, em janela deslizante de 60 segundos. Quando o limite estoura, a resposta é 429 rate_limit_exceeded com header Retry-After.
Por que existe
Rate limiting protege a Allya, os gateways e a operação do próprio cliente:
- Gateway: todos os providers cobram por chamada e podem retornar
429para a Allya se o burst for grande. Limitar na entrada amortece. - Banco:
POST /v1/paymentsfaz transação com lock para idempotência. Burst sem limite vira contenção em produção. - Conta comprometida: se uma
sk_live_…vazar, o atacante esbarra no limite antes de torrar verba.
Cotas atuais
| Rota | Default | Escopo |
|---|---|---|
POST /v1/payments | 30 req/min | Bucket próprio por API key |
POST /v1/subscriptions | 30 req/min | Bucket próprio por API key, mesmo limite de criação de pagamentos |
POST /v1/payments/:id/sync | 10 req/min | Bucket próprio por API key |
POST /v1/payments/:id/cancel | 10 req/min | Bucket próprio por API key |
POST /v1/subscriptions/:id/cancel, GET /v1/payments, GET /v1/subscriptions, GET /v1/health e GET /v1/auth/test não consomem rate limit de pagamentos. Eles têm fluxo barato e não chamam gateway externo na maioria dos casos.
A janela é deslizante: a Allya conta requests dos últimos 60 segundos a partir de "agora", não em janelas fixas de relógio. Isso evita bursts no boundary do minuto.
Headers em toda resposta
Toda resposta de rota com rate limit inclui:
| Header | Tipo | Significado |
|---|---|---|
X-RateLimit-Limit | integer | Limite atual da janela para esta rota. |
X-RateLimit-Remaining | integer | Quantas requisições ainda cabem antes de bater o limite. |
X-RateLimit-Reset | integer (unix seconds) | Quando o slot mais antigo da janela expira: após esse momento, Remaining aumenta. |
Retry-After | integer (seconds) | Apenas em 429: segundos até a próxima requisição ser aceita. |
Use Remaining para fazer self-throttle antes de tomar 429:
const res = await fetch("https://payments-api.allyasolutions.com/v1/payments", options);
const remaining = Number(res.headers.get("X-RateLimit-Remaining") ?? "0");
if (remaining < 5) {
// Estou perto do limite: espalhar próximas requisições no tempo.
await new Promise((r) => setTimeout(r, 1000));
}Padrão de retry recomendado
Quando vier 429, sempre honre Retry-After e não retentar mais rápido. A Allya conta cada tentativa.
async function callWithBackoff(input: RequestInit) {
for (let attempt = 1; attempt <= 3; attempt++) {
const res = await fetch("https://payments-api.allyasolutions.com/v1/payments", input);
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("Retry-After") ?? "1");
// Jitter (±20%) para não sincronizar retries em fleet de workers.
const jitter = retryAfter * (0.8 + Math.random() * 0.4);
await new Promise((r) => setTimeout(r, jitter * 1000));
}
throw new Error("rate_limit_exceeded after 3 attempts");
}Se a chamada original mexe com idempotência (POST /v1/payments com externalId), retries são seguros: a Allya retorna o pagamento existente.
Como aumentar o limite
O limite é global por instância da Allya, não por organização/projeto. Para subir:
- Confirme que o volume de produção excede 30 req/min de forma sustentada (não pico isolado). Pico curto é melhor resolvido com espalhamento no cliente.
- Solicite ou aplique um ajuste operacional do limite na plataforma.
- Valide pelos headers
X-RateLimit-*após a mudança. O contador é por instância do serviço; em arquitetura multi-réplica, o limite efetivo depende da configuração da plataforma.
Cotas por organização baseadas no plano ainda não estão disponíveis. Todos compartilham o limite global da instância.
Limite vs. capacidade do gateway
A cota da Allya não substitui a cota do gateway. Se o Pagar.me limita você em 60 req/min, subir a cota da Allya acima disso não ajuda: o gateway vai retornar 429 ou 503. Olhe ambos os limites.
Em geral, configure a cota da Allya um pouco abaixo da menor cota dos gateways que você usa. Isso garante que o 429 que volta para o seu sistema é o da Allya (com Retry-After previsível), e não um erro 502 confuso de gateway.
Veja também
- Erros: outros códigos que valem retry com backoff (502, timeout).
- Idempotência: por que retries com mesmo
externalIdsão seguros. - Troubleshooting: passo a passo quando o erro aparecer.