Pular para o conteúdo principal

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:

PlanoLimiteRequisicoes/segundo (media)
Gratuito60 req/min~1 req/s
Profissional300 req/min~5 req/s
Equipe600 req/min~10 req/s
Enterprise1.200 req/min~20 req/s
Limite por organizacao

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:

HeaderDescricaoExemplo
X-RateLimit-LimitNumero maximo de requisicoes permitidas por minuto300
X-RateLimit-RemainingNumero de requisicoes restantes na janela atual298
X-RateLimit-ResetTimestamp Unix (em segundos) de quando a janela sera resetada1711700460

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
}
}
}
Atencao

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.

Dica

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:

DeParaGanho
GratuitoProfissional5x mais requisicoes
ProfissionalEquipe2x mais requisicoes
EquipeEnterprise2x 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.