Politicas de Rate Limit
A API do TapSign implementa limites de requisicoes (rate limiting) para garantir a estabilidade e disponibilidade do servico para todos os usuarios.
Limites por plano
Cada plano possui um limite de requisicoes por minuto:
| Plano | Limite | Requisicoes/segundo (media) |
|---|---|---|
| Gratuito | 60 req/min | ~1 req/s |
| Profissional | 300 req/min | ~5 req/s |
| Equipe | 600 req/min | ~10 req/s |
| Enterprise | 1.200 req/min | ~20 req/s |
O rate limit e aplicado por organizacao, nao por API Key. Se voce possui multiplas chaves de API, todas compartilham o mesmo limite.
Headers de Rate Limit
Todas as respostas da API incluem headers informativos sobre o estado atual do seu rate limit:
| Header | Descricao | Exemplo |
|---|---|---|
X-RateLimit-Limit | Numero maximo de requisicoes permitidas por minuto | 300 |
X-RateLimit-Remaining | Numero de requisicoes restantes na janela atual | 298 |
X-RateLimit-Reset | Timestamp Unix (em segundos) de quando a janela sera resetada | 1711700460 |
Exemplo de headers em uma resposta
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 298
X-RateLimit-Reset: 1711700460
Resposta 429 - Rate Limit Excedido
Quando o limite de requisicoes e excedido, a API retorna o status 429 Too Many Requests:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711700460
Retry-After: 32
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Limite de requisicoes excedido. Tente novamente em 32 segundos.",
"details": {
"limit": 300,
"remaining": 0,
"reset_at": "2026-03-29T14:01:00Z",
"retry_after": 32
}
}
}
Requisicoes que retornam 429 nao sao processadas. Voce precisa reenvia-las apos aguardar o tempo indicado no header Retry-After.
Boas praticas
1. Monitore os headers
Acompanhe os headers X-RateLimit-Remaining e X-RateLimit-Reset para saber quantas requisicoes voce ainda pode fazer e quando a janela sera resetada.
async function callTapSignAPI(url, options) {
const response = await fetch(url, options);
const remaining = response.headers.get('X-RateLimit-Remaining');
const resetAt = response.headers.get('X-RateLimit-Reset');
if (parseInt(remaining) < 10) {
console.warn(`Rate limit baixo: ${remaining} requisicoes restantes`);
}
return response;
}
2. Implemente retry com backoff exponencial
Quando receber um erro 429, implemente retry com backoff exponencial para reenviar a requisicao de forma segura:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
if (attempt === maxRetries) {
throw new Error('Rate limit excedido apos multiplas tentativas');
}
// Usar Retry-After se disponivel, senao backoff exponencial
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter) * 1000
: Math.pow(2, attempt) * 1000 + Math.random() * 1000;
console.log(`Rate limit atingido. Aguardando ${waitTime}ms antes do retry...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
import time
import random
import requests
def fetch_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries + 1):
response = requests.get(url, headers=headers)
if response.status_code != 429:
return response
if attempt == max_retries:
raise Exception("Rate limit excedido apos multiplas tentativas")
retry_after = response.headers.get("Retry-After")
if retry_after:
wait_time = int(retry_after)
else:
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limit atingido. Aguardando {wait_time}s...")
time.sleep(wait_time)
3. Distribua as requisicoes
Evite enviar rajadas de requisicoes. Distribua as chamadas ao longo do tempo:
// Ruim - rajada de 100 requisicoes simultaneas
const promises = ids.map(id => fetch(`/v1/envelopes/${id}`));
await Promise.all(promises);
// Bom - processar em lotes de 10 com intervalo
async function processInBatches(ids, batchSize = 10, delayMs = 1000) {
const results = [];
for (let i = 0; i < ids.length; i += batchSize) {
const batch = ids.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(id => fetch(`/v1/envelopes/${id}`))
);
results.push(...batchResults);
if (i + batchSize < ids.length) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
return results;
}
4. Use webhooks em vez de polling
Em vez de consultar repetidamente o status de um envelope, configure webhooks para receber notificacoes automaticas quando houver mudancas.
Usar webhooks reduz drasticamente o numero de requisicoes a API e garante que voce receba atualizacoes em tempo real, sem desperdicio de cota.
5. Cache de respostas
Para dados que nao mudam frequentemente (como templates e configuracoes), implemente cache local para evitar requisicoes desnecessarias.
Upgrade de plano
Se o rate limit do seu plano atual nao e suficiente para sua operacao, considere fazer upgrade:
| De | Para | Ganho |
|---|---|---|
| Gratuito | Profissional | 5x mais requisicoes |
| Profissional | Equipe | 2x mais requisicoes |
| Equipe | Enterprise | 2x mais requisicoes |
Para o plano Enterprise com limites personalizados, entre em contato pelo email suporte@tapsign.com.br.
Proxima secao: Status de Erros -- Entenda os codigos de erro retornados pela API.