Skip to main content
A API da AWSales aplica limites de requisição para garantir uso justo e estabilidade da plataforma. Quando você excede o limite, a API retorna uma response 429 Too Many Requests. Sua integração deve tratar isso de forma adequada.

Visão geral dos limites

Os limites de requisição são aplicados por access token (ou seja, por sessão de usuário autenticado). Endpoints não autenticados (login, cadastro, OTP) têm limites mais rígidos para prevenir abuso.
Categoria de endpointLimiteJanela
Autenticação (login, cadastro, OTP)10 requestspor minuto
Operações de leitura (GET)120 requestspor minuto
Operações de escrita (POST, PUT, PATCH, DELETE)60 requestspor minuto
Operações de pagamento (pagar fatura, criar assinatura)10 requestspor minuto
Limites de burst: Enviar muitas requests em um intervalo muito curto (ex: 30 requests em 1 segundo) pode acionar throttling mesmo que você esteja dentro do limite por minuto. Espalhe suas requests para evitar bursts.

Headers de rate limit

Toda response da API inclui headers que informam o status atual do seu rate limit:
HeaderDescriçãoExemplo
X-RateLimit-LimitMáximo de requests permitidas na janela atual120
X-RateLimit-RemainingRequests restantes na janela atual87
X-RateLimit-ResetTimestamp Unix (segundos) de quando a janela reseta1711382460
Retry-AfterSegundos para aguardar antes de retentar (apenas em responses 429)12
async function makeRequest(url, options) {
  const response = await fetch(url, options);

  // Read rate limit headers
  const limit = response.headers.get("X-RateLimit-Limit");
  const remaining = response.headers.get("X-RateLimit-Remaining");
  const resetTimestamp = response.headers.get("X-RateLimit-Reset");

  console.log(`Rate limit: ${remaining}/${limit} remaining`);
  console.log(`Resets at: ${new Date(resetTimestamp * 1000).toISOString()}`);

  if (response.status === 429) {
    const retryAfter = parseInt(response.headers.get("Retry-After") || "1");
    console.log(`Rate limited. Retrying in ${retryAfter}s...`);
    await new Promise((r) => setTimeout(r, retryAfter * 1000));
    return makeRequest(url, options); // Retry
  }

  return response;
}

Tratando responses 429

Quando o rate limit é atingido, a API retorna:
{
  "statusCode": 429,
  "message": "Too Many Requests"
}
Junto com um header Retry-After indicando quantos segundos aguardar.

Backoff exponencial com jitter

Para uma lógica de retry robusta, combine o header Retry-After com backoff exponencial e jitter aleatório para evitar problemas de thundering herd.
1

Capturar a response 429

Detecte o código de status 429 no seu cliente HTTP.
2

Ler o header Retry-After

Use o valor do Retry-After como tempo mínimo de espera. Se o header estiver ausente, use 1 segundo como padrão.
3

Aplicar backoff exponencial

A cada retry consecutivo, dobre o tempo de espera: 1s, 2s, 4s, 8s, etc. Limite o máximo (ex: 30 segundos).
4

Adicionar jitter aleatório

Adicione um atraso aleatório (ex: 0-500ms) para evitar que múltiplos clientes retentem no exato mesmo momento.
5

Definir um limite de retentativas

Pare após um número razoável de tentativas (ex: 5) e apresente o erro ao usuário.
class RateLimitedClient {
  constructor(baseUrl, token) {
    this.baseUrl = baseUrl;
    this.token = token;
    this.maxRetries = 5;
  }

  async request(path, options = {}) {
    const url = `${this.baseUrl}${path}`;

    for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
      const response = await fetch(url, {
        ...options,
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${this.token}`,
          ...options.headers,
        },
      });

      if (response.status !== 429) {
        return response;
      }

      if (attempt === this.maxRetries) {
        throw new Error("Rate limit exceeded. Max retries reached.");
      }

      // Calculate wait time
      const retryAfter = parseInt(
        response.headers.get("Retry-After") || "1"
      );
      const backoff = Math.min(retryAfter * Math.pow(2, attempt), 30);
      const jitter = Math.random() * 0.5;
      const waitTime = (backoff + jitter) * 1000;

      console.log(
        `Rate limited (attempt ${attempt + 1}/${this.maxRetries}). ` +
        `Waiting ${(waitTime / 1000).toFixed(1)}s...`
      );

      await new Promise((r) => setTimeout(r, waitTime));
    }
  }
}

// Usage
const client = new RateLimitedClient(
  "https://api.awsales.io/studio",
  "eyJhbGciOiJSUzI1NiIs..."
);

const response = await client.request("/plans");
const plans = await response.json();

Gerenciamento proativo de rate limit

Em vez de esperar por erros 429, monitore os headers e faça throttling antes de atingir o limite.
class SmartClient {
  constructor(baseUrl, token) {
    this.baseUrl = baseUrl;
    this.token = token;
    this.remaining = Infinity;
    this.resetAt = 0;
  }

  async request(path, options = {}) {
    // If we're almost out of budget, wait for the reset
    if (this.remaining <= 2 && Date.now() < this.resetAt) {
      const waitMs = this.resetAt - Date.now() + 100;
      console.log(`Preemptive throttle: waiting ${waitMs}ms`);
      await new Promise((r) => setTimeout(r, waitMs));
    }

    const response = await fetch(`${this.baseUrl}${path}`, {
      ...options,
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${this.token}`,
        ...options.headers,
      },
    });

    // Update rate limit state from headers
    this.remaining = parseInt(
      response.headers.get("X-RateLimit-Remaining") || "Infinity"
    );
    this.resetAt =
      parseInt(response.headers.get("X-RateLimit-Reset") || "0") * 1000;

    return response;
  }
}

Reduzindo chamadas à API

A melhor forma de evitar rate limits é fazer menos requests. Aqui estão estratégias práticas:
Cache de responses localmente. Planos, permissões e roles mudam com pouca frequência. Faça cache por minutos ou horas em vez de buscar a cada carregamento de página. Use tamanhos de página maiores. Ao paginar, solicite o limit máximo para reduzir o número de round trips. Uma request com limit=50 é melhor que cinco requests com limit=10. Agrupe atualizações na UI. Se seu frontend dispara chamadas à API baseadas em input do usuário (ex: busca enquanto digita), faça debounce das chamadas para evitar enviar uma request a cada tecla pressionada. Use webhooks para atualizações em tempo real. Em vez de fazer polling para mudanças de status de fatura, configure webhooks para receber notificações push quando eventos ocorrerem.

Limites por plano

Os limites de requisição podem variar por plano de assinatura. Entre em contato com seu gerente de conta para detalhes sobre limites maiores para casos de uso enterprise.
PlanoLimite de leituraLimite de escrita
Starter120/min60/min
Professional300/min120/min
EnterprisePersonalizadoPersonalizado
Se você precisa consistentemente de limites maiores, entre em contato com seu gerente de conta da AWSales. Planos Enterprise suportam limites personalizados e throughput dedicado.

Próximos passos

Tratamento de Erros

Construa tratamento de erros robusto com estratégias de retry.

Paginação

Navegue por grandes conjuntos de dados de forma eficiente para minimizar chamadas à API.