Pular para conteúdo

Rate Limits

Visão Geral

A API Pontotel implementa rate limiting para garantir disponibilidade e performance para todos os clientes.

O que é Rate Limiting?

Rate limiting é uma técnica que limita o número de requisições que um cliente pode fazer em um período de tempo específico.

Limites Atuais

Ambiente Limite Janela Burst
Sandbox 1000 requisições 1 hora 100/min
Produção 500 requisições 1 hora 50/min

Headers de Rate Limit

Cada resposta da API inclui headers informativos:

HTTP
1
2
3
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1642089600
Header Descrição
X-RateLimit-Limit Limite total de requisições
X-RateLimit-Remaining Requisições restantes
X-RateLimit-Reset Timestamp (Unix) quando o limite reseta

Resposta 429 (Too Many Requests)

Quando o limite é excedido:

JSON
1
2
3
4
5
6
7
8
{
  "error": "rate_limit_exceeded",
  "message": "Você excedeu o limite de requisições",
  "limit": 500,
  "remaining": 0,
  "reset_at": "2025-02-09T15:00:00Z",
  "retry_after": 3600
}

Status Code: 429 Too Many Requests

Header adicional:

HTTP
Retry-After: 3600

Boas Práticas

1. Monitorar Headers

Python
def fazer_requisicao_com_monitoring(url, headers):
    response = requests.get(url, headers=headers)

    # Verificar rate limit
    limit = int(response.headers.get('X-RateLimit-Limit', 0))
    remaining = int(response.headers.get('X-RateLimit-Remaining', 0))

    print(f"Rate Limit: {remaining}/{limit} requisições restantes")

    # Alertar quando estiver perto do limite
    if remaining < limit * 0.1:  # Menos de 10%
        print("⚠️ ATENÇÃO: Perto do limite de rate!")

    return response
JavaScript
async function fazerRequisicaoComMonitoring(url, headers) {
  const response = await fetch(url, { headers });

  const limit = parseInt(response.headers.get('X-RateLimit-Limit') || '0');
  const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');

  console.log(`Rate Limit: ${remaining}/${limit} requisições restantes`);

  if (remaining < limit * 0.1) {
    console.warn('⚠️ ATENÇÃO: Perto do limite de rate!');
  }

  return response;
}

2. Implementar Retry com Backoff

Python
import time
from datetime import datetime

def requisicao_com_retry(url, headers, max_retries=3):
    for tentativa in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            reset_time = datetime.fromtimestamp(
                int(response.headers.get('X-RateLimit-Reset', 0))
            )

            print(f"⏳ Rate limit atingido. Aguardando {retry_after}s...")
            print(f"   Reset previsto: {reset_time}")

            time.sleep(retry_after)
            continue

        return response

    raise Exception("Máximo de tentativas excedido")
JavaScript
async function requisicaoComRetry(url, headers, maxRetries = 3) {
  for (let tentativa = 0; tentativa < maxRetries; tentativa++) {
    const response = await fetch(url, { headers });

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
      const resetTime = new Date(
        parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000
      );

      console.log(`⏳ Rate limit atingido. Aguardando ${retryAfter}s...`);
      console.log(`   Reset previsto: ${resetTime.toLocaleString()}`);

      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }

  throw new Error('Máximo de tentativas excedido');
}

3. Cache de Respostas

Reduza requisições armazenando respostas em cache:

Python
from functools import lru_cache
from datetime import datetime, timedelta

class PontotelClient:
    def __init__(self):
        self.cache = {}
        self.cache_duration = timedelta(minutes=5)

    def get_with_cache(self, url, headers):
        # Verificar cache
        if url in self.cache:
            cached_data, cached_time = self.cache[url]
            if datetime.now() - cached_time < self.cache_duration:
                print("✅ Retornando do cache")
                return cached_data

        # Fazer requisição
        response = requests.get(url, headers=headers)

        # Armazenar em cache
        self.cache[url] = (response.json(), datetime.now())

        return response.json()

4. Batch de Requisições

Agrupe múltiplas operações quando possível:

Python
1
2
3
4
5
6
# ❌ NÃO FAZER: Múltiplas requisições individuais
for user_id in user_ids:
    get_user(user_id)  # 100 requisições!

# ✅ FAZER: Uma requisição com filtros
get_users(ids=",".join(user_ids))  # 1 requisição

5. Paginação Eficiente

Use paginação para evitar requisições desnecessárias:

Python
def listar_todos_usuarios(base_url, headers):
    all_users = []
    url = f"{base_url}/usuarios/"

    while url:
        response = requests.get(url, headers=headers)
        data = response.json()

        all_users.extend(data['results'])
        url = data['next']  # Próxima página ou None

        print(f"Processados: {len(all_users)}/{data['count']}")

    return all_users

Aumentar Limites

Se você precisa de limites maiores:

  1. Entre em contato com o suporte comercial
  2. Apresente seu caso de uso
  3. Considere upgrade de plano

Planos Enterprise

Planos enterprise oferecem:

  • Rate limits personalizados
  • Burst maior
  • SLA garantido
  • Suporte prioritário

Monitoramento

Dashboard Recomendado

Monitore métricas importantes:

  • Requisições por hora
  • Taxa de erro 429
  • Tempo médio de resposta
  • Percentual de uso do rate limit

Alertas

Configure alertas para:

  • 80% do rate limit atingido
  • Erros 429 consecutivos
  • Tempo de resposta > 2s

Próximos Passos