Limites e Boas Práticas

Informações sobre limites de taxa, paginação, cache e boas práticas da API

Rate Limiting (Limite de Taxa)

Limites Atuais

  • 100 requisições por minuto por credencial de API
  • O contador é resetado a cada 60 segundos (janela deslizante)
  • Rate limiting aplicado globalmente para todos os endpoints

Resposta ao Exceder o Limite

Quando você excede os limites, receberá:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "statusCode": 429,
  "error": "Too Many Requests",
  "message": "Limite de requisições excedido. Tente novamente em alguns minutos.",
  "retryAfter": 60
}

Boas Práticas para Rate Limiting

  1. Implemente retry com backoff exponencial

    • Aguarde o tempo indicado no header Retry-After
    • Use delay crescente entre tentativas
  2. Distribua requisições ao longo do tempo

    • Evite bursts (rajadas) de requisições
    • Use filas para operações em lote
  3. Use cache para dados que não mudam frequentemente

    • A API implementa cache de 30 minutos para consultas
    • Evite requisições redundantes
  4. Agrupe múltiplas operações quando possível

    • Use endpoints que suportam operações em lote
    • Combine filtros para reduzir número de chamadas

Paginação

Parâmetros

ParâmetroDescriçãoValor MínimoValor MáximoValor Padrão
limitQuantidade de registros por página na requisição15000500
pageNúmero da página de resultados1—1

Como Usar

GET /v1/google/ads/campaigns?organizationId=organization_123&limit=1000&page=2

Ajuste Automático

Valores inválidos ou fora dos limites serão automaticamente ajustados

  • Valores abaixo do mínimo → ajustados para o mínimo
  • Valores acima do máximo → ajustados para o máximo
  • Valores não numéricos → usam valor padrão
  • Valores decimais → arredondados para baixo (floor)

Exemplos de ajuste:

  • limit=0 → ajustado para 1
  • limit=6000 → ajustado para 5000
  • limit=abc → usa padrão 500
  • page=0 → ajustado para 1
  • page=2.7 → ajustado para 2

Exemplo de Resposta Paginada

{
  "data": [...],
  "meta": {
    "page": 1,
    "limit": 500,
    "hasNextPage": false,
    "hasPreviousPage": false
  }
}

Cache

Configuração de Cache

A API utiliza cache automático para otimizar performance:

  • Duração do cache: 30 minutos (1800 segundos)

Estratégias de Cache

  1. Cache de consultas

    • Queries complexas são cacheadas automaticamente
    • Cache invalida após 30 minutos ou quando dados são atualizados
  2. Cache no cliente

    • Implemente cache local para dados estáticos
    • Respeite TTL (Time To Live) apropriado
    • Invalide cache quando necessário

Boas Práticas Gerais

1. Tratamento de Erros

Sempre trate possíveis erros da API:

async function makeRequest(url, clientId, clientSecret) {
  try {
    const response = await fetch(url, {
      headers: {
        'x-client-id': clientId,
        'x-client-secret': clientSecret,
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        throw new Error(`Rate limit excedido. Aguarde ${retryAfter} segundos.`);
      }
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Erro ao acessar API:', error);
    // Implementar lógica de retry ou fallback
    throw error;
  }
}

2. Implementação de Retry com Backoff Exponencial

async function makeRequestWithRetry(url, clientId, clientSecret, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, {
        headers: {
          'x-client-id': clientId,
          'x-client-secret': clientSecret,
          'Content-Type': 'application/json',
        },
      });

      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        console.log(`Rate limit atingido. Aguardando ${retryAfter} segundos...`);
        await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      if (attempt === maxRetries - 1) {
        throw error;
      }
      // Backoff exponencial: 2^attempt segundos
      const delay = Math.pow(2, attempt) * 1000;
      console.log(`Tentativa ${attempt + 1} falhou. Aguardando ${delay}ms...`);
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}

3. Use Paginação Eficientemente

  • Não busque todos os dados de uma vez

    • Use limit adequado ao seu caso de uso (recomendado: 500-1000)
    • Evite limit muito alto que pode causar timeout
  • Implemente paginação progressiva (lazy loading)

    // endpoint: URL com organizationId, ex.:
    // https://data.v4mos.ai/v1/google/ads/campaigns?organizationId=organization_123
    async function* fetchAllPages(endpoint, clientId, clientSecret) {
      let page = 1;
      let hasMore = true;
    
      while (hasMore) {
        const url = new URL(endpoint);
        url.searchParams.set('page', String(page));
        url.searchParams.set('limit', '500');
    
        const response = await fetch(url, {
          headers: {
            'x-client-id': clientId,
            'x-client-secret': clientSecret,
          },
        });
        const data = await response.json();
    
        yield data.data;
    
        hasMore = data.meta?.hasNextPage || false;
        page++;
      }
    }

4. Monitoramento

  • Registre (log) erros e respostas inesperadas

    const logger = {
      error: (message, context) => console.error(`[ERROR] ${message}`, context),
      warn: (message, context) => console.warn(`[WARN] ${message}`, context),
      info: (message, context) => console.log(`[INFO] ${message}`, context),
    };
  • Monitore tempo de resposta

    • Configure alertas para respostas lentas (> 5s)
    • Identifique endpoints com performance degradada
  • Acompanhe uso de quota de requisições

    • Monitore X-RateLimit-Remaining em cada resposta
    • Configure alertas quando próximo do limite (ex: < 20 requisições)

5. Otimização de Requisições

  • Filtros eficientes: Use date ranges e outros filtros para reduzir dados

    # Em vez de buscar todos e filtrar localmente
    GET /v1/facebook/ads/campaigns?organizationId=organization_123&dateStart=2024-01-01&dateEnd=2024-12-31
  • Requisições paralelas: Limite concorrência para não exceder rate limit

    async function fetchInParallel(urls, clientId, clientSecret, maxConcurrent = 10) {
      const semaphore = { count: maxConcurrent };
      const queue = urls.map((url) => ({
        url,
        promise: null,
      }));
    
      return Promise.all(
        queue.map(async (item) => {
          while (semaphore.count === 0) {
            await new Promise((resolve) => setTimeout(resolve, 100));
          }
          semaphore.count--;
          try {
            item.promise = fetch(item.url, {
              headers: {
                'x-client-id': clientId,
                'x-client-secret': clientSecret,
              },
            });
            return await item.promise;
          } finally {
            semaphore.count++;
          }
        }),
      );
    }

6. Versionamento

  • Sempre especifique a versão da API
    • Todos os endpoints começam com /v1/
    • Monitore comunicados sobre descontinuação de versões
    • Planeje migração com antecedência

7. Timeouts

Configure timeouts adequados em suas requisições:

// Exemplo com timeout de 30 segundos
async function fetchWithTimeout(url, clientId, clientSecret, timeout = 30000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, {
      signal: controller.signal,
      headers: {
        'x-client-id': clientId,
        'x-client-secret': clientSecret,
        'Content-Type': 'application/json',
      },
    });
    clearTimeout(timeoutId);
    return response;
  } catch (error) {
    clearTimeout(timeoutId);
    if (error.name === 'AbortError') {
      throw new Error('Requisição cancelada por timeout');
    }
    throw error;
  }
}

Recomendações de timeout:

  • Requisições GET simples: 10-15 segundos
  • Requisições com paginação grande: 30-60 segundos
  • Operações em lote: 60-120 segundos

Checklist de Integração

Antes de colocar em produção, certifique-se de:

  • Credenciais de API (client_id e client_secret) geradas e armazenadas com segurança
  • organizationId configurado corretamente
  • Tratamento de erros implementado (incluindo 429)
  • Rate limiting considerado na arquitetura
  • Paginação implementada para grandes volumes
  • Retry com backoff exponencial configurado
  • Logs e monitoramento configurados
  • Timeouts configurados adequadamente
  • Cache implementado quando apropriado
  • Testes realizados em ambiente de desenvolvimento
  • Monitoramento de X-RateLimit-Remaining implementado

Troubleshooting

Problemas Comuns

Erros 429 frequentes:

  • Reduza frequência de requisições
  • Implemente cache mais agressivo
  • Use endpoints batch quando disponível
  • Contate suporte para limites customizados (plano enterprise)

Timeout em requisições grandes:

  • Reduza o limit da paginação
  • Use filtros mais específicos (date ranges menores)
  • Implemente requisições incrementais

Dados inconsistentes:

  • Verifique se está respeitando cache (aguarde 30 minutos após atualizações)
  • Use timestamps para sincronização
  • Considere webhooks se disponível para atualizações em tempo real

Suporte

Para questões sobre limites e boas práticas:

  • Revise padrões de uso na V4MOS.AI
  • Contate suporte para ajustes de rate limit
  • Solicite monitoramento customizado para necessidades específicas

Nesta página