Rate Limiting
A BSPAY aplica rate limiting por endpoint e bloqueio anti-abuso por credencial. Excedê-los retorna 429 Too Many Requests.
A BSPAY aplica rate limiting por endpoint e bloqueio anti-abuso por credencial. Excedê-los retorna 429 Too Many Requests.
Limites por endpoint
| Endpoint | Limite | Notas |
|---|---|---|
POST /v2/oauth/token | 30 reqs/min/IP | Após 5 falhas seguidas → IP bloqueado por 5min (IP_BLOCKED_TEMPORARILY) |
GET /v2/account/balance | 120 reqs/min | |
GET /v2/account/info/profile | 60 reqs/min | |
GET /v2/account/limits | 60 reqs/min | |
GET /v2/account/fees | 60 reqs/min | |
POST /v2/transactions/cashin | 12 000 reqs/min | Alta vazão pra checkout |
POST /v2/transactions/cashout | 6 000 reqs/min | Exige HMAC |
POST /v2/transactions/wallet | 30 reqs/min | |
POST /v2/internal_transfers/payment | 10 reqs/min | Anti-enumeração de usernames |
POST /v2/conversions/rate | 120 reqs/min | Cotação spot |
POST /v2/conversions/simulate | 60 reqs/min | |
POST /v2/conversions/new | 30 reqs/min | Exige HMAC |
POST /v2/account/transactions/list | 300 reqs/min | |
GET /v2/account/infractions | 60 reqs/min | |
POST /v2/account/infractions/reply | 10 reqs/min | Multipart upload |
Bloqueio anti-abuso
Independente do rate limit por endpoint, há um bloqueio global por erros consecutivos:
| Condição | Limite | Ação |
|---|---|---|
| Erros 4xx por credencial | 15 erros/min | Bloqueio temporário da credencial |
| Falhas de auth por IP | 5 erros/5min | IP_BLOCKED_TEMPORARILY (5min) |
A ideia é proteger contra:
- Brute-force de credenciais (
/oauth/token) - Enumeração de
usernameou chaves PIX
Resposta 429
Headers de resposta
Toda resposta (sucesso ou erro) inclui:
| Header | Descrição |
|---|---|
X-RateLimit-Limit | Limite total da janela (reqs/min) |
X-RateLimit-Remaining | Reqs restantes na janela atual |
X-RateLimit-Reset | Unix timestamp de quando o contador zera |
Retry-After | Segundos pra esperar (presente apenas em 429) |
Boas práticas
1. Cache do access token
Token tem validade de 1h — não regenere a cada request.
2. Retry com backoff exponencial
Em 429, respeite Retry-After antes de retentar. Para 502/503, use backoff exponencial (1s → 2s → 4s → 8s).
3. Webhook em vez de polling
Polling em transactions/list desperdiça quota. Configure postback_url e reaja ao webhook cashin.confirmed / cashout.confirmed. Reconcile via list só periodicamente (1×/hora).
4. Nonce + idempotência em rotas com HMAC
X-Nonce deve ser único nos últimos 5 min. Se quiser retry seguro:
- Mesmo
external_id+ mesmo body + nonce novo → idempotente (segunda chamada retorna a transação original) - Mesmo
external_id+ body diferente → erroDUPLICATE_EXTERNAL_ID
Erros relacionados
| Código | HTTP | Ação |
|---|---|---|
RATE_LIMIT_EXCEEDED | 429 | Espere Retry-After segundos |
IP_BLOCKED_TEMPORARILY | 403 | Espere 5 minutos — não retry imediato |
IP_BLACKLISTED | 403 | Contate suporte — bloqueio permanente |
SECURITY_BLOCKED | 423 | Conta sob revisão de segurança |
