Pular para o conteúdo principal
Zenovay
Pro Plano5 minutesIntermediário

Limites de Taxa e Melhores Práticas

Entenda os limites de taxa da API — cotas, headers e estratégias para uso eficiente da API.

apirate-limitsperformancebest-practices
Última atualização:
Pro Plano

Entenda os limites de taxa da API do Zenovay e otimize sua integração para confiabilidade e desempenho.

Visão Geral dos Limites de Taxa

A API REST é uma função paga. As chaves de API funcionam apenas nos planos Pro, Scale e Enterprise — as chaves do plano Free são rejeitadas com uma resposta 403 API_PAID_PLAN_REQUIRED.

Limites da API por Plano

Estes limites se aplicam à API REST (endpoints sob /api/external/v1/):

PlanoRequisições/MinutoRequisições/Mês
Pro3010 000
Scale60100 000
Enterprise1201 000 000

Os limites são resolvidos a partir da assinatura da sua equipe. Se você pertence a vários times, a API usa o plano mais alto do qual você é membro.

O Que Conta como Requisição

Cada chamada de API autenticada conta como uma requisição contra sua cota mensal — os endpoints de leitura (GET) e o endpoint de consulta (POST /query/:websiteId). A API REST é somente leitura; não há endpoints PUT, PATCH ou DELETE.

O Que Não Conta

As requisições que falham na autenticação (401, por exemplo, uma chave ausente ou inválida) não contam contra sua cota, pois a chave nunca é validada.

Headers de Rate Limit

Headers de Resposta

Cada resposta da API inclui headers de uso:

X-RateLimit-Limit: 30
X-Usage-Monthly: 4521
X-Usage-Limit: 10000
X-Usage-Reset: 2026-07-01T00:00:00.000Z
X-Usage-Total: 89234
HeaderDescrição
X-RateLimit-LimitSeu limite de requisições por minuto
X-RateLimit-RemainingRequisições restantes neste minuto (nem sempre presentes — ver abaixo)
X-Usage-MonthlyRequisições usadas neste mês
X-Usage-LimitLimite mensal de requisições
X-Usage-ResetQuando o uso mensal é redefinido (ISO 8601)
X-Usage-TotalTotal de requisições jamais realizadas com esta chave

X-RateLimit-Remaining é incluído apenas quando uma contagem exata de requisições restantes está disponível; trate sua ausência como normal e confie em X-RateLimit-Limit mais sua própria contagem de requisições para orçamento.

Lendo os Headers

const response = await fetch(url, { headers });

const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining'); // pode ser null — veja a nota acima
const monthlyReset = response.headers.get('X-Usage-Reset'); // timestamp ISO 8601

console.log(`${remaining ?? '?'}/${limit} requisições restantes este minuto`);
console.log(`O uso mensal é redefinido em ${monthlyReset}`);

Limite de Taxa Excedido

Resposta

Quando o limite por minuto é excedido:

HTTP/1.1 429 Too Many Requests
Retry-After: 42

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded (30 requests/minute). Try again in 42 seconds",
    "timestamp": "2026-06-13T12:00:00.000Z"
  }
}

O 429 por minuto inclui um header Retry-After (em segundos) informando quanto tempo esperar antes de tentar novamente.

Quando a quota monthly é excedida, o corpo do erro usa a mesma forma com "code": "MONTHLY_LIMIT_EXCEEDED". Esta resposta não carrega um header Retry-After — em vez disso, verifique o header X-Usage-Reset, que informa quando sua alocação mensal é redefinida (o primeiro do mês seguinte).

Tratando Erros 429

async function apiRequest(url, options, retries = 3) {
  const response = await fetch(url, options);

  if (response.status === 429 && retries > 0) {
    const retryAfter = response.headers.get('Retry-After') || 60;
    console.log(`Rate limited. Waiting ${retryAfter}s...`);
    await sleep(retryAfter * 1000);
    return apiRequest(url, options, retries - 1);
  }

  return response;
}

Melhores Práticas

Cache

Armazene em cache as respostas quando possível:

const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos

async function getWithCache(endpoint) {
  const cached = cache.get(endpoint);
  if (cached && Date.now() - cached.time < CACHE_TTL) {
    return cached.data;
  }

  const response = await api.get(endpoint);
  cache.set(endpoint, { data: response, time: Date.now() });
  return response;
}

Solicite Apenas o Que Precisa

Use o filtro range para limitar os dados retornados:

# Filtrar por um intervalo de tempo específico:
GET /api/external/v1/analytics/WEBSITE_ID?range=7d

Use Filtros de Data

Limite os dados retornados a períodos específicos (valores suportados: 24h, 7d, 30d, 90d, 1y):

# Buscar apenas os últimos 30 dias:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d

Paginação

O endpoint de visitantes pagina com limit e offset (não números de página). limit tem um padrão de 100 e é limitado a 1000.

Requisição

GET /api/external/v1/analytics/WEBSITE_ID/visitors?range=30d&limit=100&offset=0

Resposta

{
  "success": true,
  "data": {
    "visitors": [...],
    "pagination": {
      "limit": 100,
      "offset": 0,
      "has_more": true
    }
  },
  "timestamp": "2026-06-13T12:00:00.000Z"
}

Paginação Eficiente

Continue solicitando páginas até que has_more seja false, incrementando offset por limit a cada vez:

async function getAllVisitors(websiteId) {
  let allVisitors = [];
  let offset = 0;
  const limit = 100;
  let hasMore = true;

  while (hasMore) {
    const response = await api.get(
      `/analytics/${websiteId}/visitors?limit=${limit}&offset=${offset}`
    );
    const { visitors, pagination } = response.data;
    allVisitors = allVisitors.concat(visitors);

    hasMore = pagination.has_more;
    offset += limit;

    // Respeite os limites de taxa
    await sleep(100);
  }

  return allVisitors;
}

Backoff Exponencial

Implementação

async function requestWithBackoff(fn, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429 && attempt < maxRetries - 1) {
        const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
        console.log(`Retry ${attempt + 1} after ${delay}ms`);
        await sleep(delay);
      } else {
        throw error;
      }
    }
  }
}

Cronograma de Backoff

TentativaTempo de Espera
11-2 segundos
22-4 segundos
34-8 segundos
48-16 segundos
516-32 segundos

Monitorando o Uso

Verificar Uso Atual

curl https://api.zenovay.com/api/external/v1/usage \
  -H "X-API-Key: zv_YOUR_API_KEY"

Isso retorna sua contagem de requisições mensuais atual, cota restante, limite de taxa por minuto e nível de assinatura.

Cada resposta da API também carrega seu uso ao vivo nos headers (X-Usage-Monthly, X-Usage-Limit, X-Usage-Reset), permitindo rastrear o consumo sem uma chamada separada.

No Painel

Abra Chaves de API (app.zenovay.com/api-keys) para ver suas chaves e os totais de requisições de cada chave, bem como a atividade recente. Use o endpoint GET /usage acima para a contagem mensal precisa e a cota restante.

Otimizando para Alto Volume

Use Endpoints Agregados

Use o endpoint de visão geral de analytics para obter totais de resumo em uma única chamada em vez de paginar por registros de visitantes brutos:

# Requisição única para visão geral de analytics:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d

Isso retorna um bloco summary (total de visitantes, visualizações de página, visitantes únicos) mais daily_stats em uma única resposta. Para desagregações geográficas, por página ou por dispositivo, use os endpoints dedicados /countries, /pages e /technology.

Limites de Taxa Enterprise

Enterprise Plano

Os planos Enterprise começam nos limites publicados mais altos (120 requisições/minuto, 1 000 000 requisições/mês). Se precisar de limites mais altos, envie um email para [email protected] com:

  • Seus padrões de uso atuais
  • Crescimento esperado
  • Detalhes do seu caso de uso

Solução de Problemas

Frequentemente com Rate Limit

Se estiver atingindo o limite por minuto frequentemente:

  1. Adicione atrasos entre requisições (ou uma fila de requisições)
  2. Use backoff exponencial em 429s
  3. Armazene em cache as respostas que reutiliza
  4. Use endpoints agregados em vez de muitas chamadas pequenas
  5. Atualize seu plano para um limite mais alto

Cota Mensal Esgotada

Um MONTHLY_LIMIT_EXCEEDED (429) significa que você esgotou sua alocação mensal de requisições. Ele é redefinido no primeiro dia do mês seguinte (veja o header X-Usage-Reset). Atualize seu plano para uma cota mensal mais alta.

Limites Inesperadamente Baixos

Se seus limites parecerem incorretos:

  1. Verifique seu nível de plano — os limites são baseados na assinatura da sua equipe
  2. Confirme que está usando uma chave do time correto
  3. Entre em contato com o suporte

Próximos Passos

Este artigo foi útil?