LiqiDevelopers

Rate Limits

A Liqi aplica limites de requisição (rate limits) para garantir a estabilidade da plataforma e proteger todos os clientes contra uso abusivo. Os limites variam conforme a API e o tipo de autenticação.


Limites por API

APILimiteJanelaObservação
Public API100 req1 minutoPor IP de origem
Developer API60 req1 minutoPor API Key
TIDC v1CustomizadoSob contratoDefinido no onboarding do originador
CaaSCustomizadoSob contratoDefinido no onboarding da empresa

Para APIs com limites customizados (TIDC v1 e CaaS), entre em contato com seu gerente de conta para conhecer os limites específicos do seu plano.


Headers de resposta

Toda resposta da API inclui headers que informam o estado atual do seu rate limit:

HeaderDescriçãoExemplo
X-RateLimit-LimitTotal de requisições permitidas na janela100
X-RateLimit-RemainingRequisições restantes na janela atual87
X-RateLimit-ResetTimestamp Unix (segundos) de quando a janela reseta1708531200
Retry-AfterSegundos ate poder enviar novamente (apenas em 429)12

Exemplo de headers

Text
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1708531200

Resposta 429 — Too Many Requests

Quando você excede o limite, a API retorna status 429:

JSON
{
  "statusCode": 429,
  "message": "Too Many Requests",
  "error": "Rate limit exceeded. Try again in 12 seconds."
}

O header Retry-After indica quantos segundos você deve aguardar antes de tentar novamente.


Boas práticas

1. Implemente exponential backoff

Ao receber um 429, não tente imediatamente. Espere o tempo indicado em Retry-After e aumente progressivamente o intervalo entre tentativas:

TypeScript
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

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

    const retryAfter = parseInt(response.headers.get("Retry-After") || "1", 10);
    const delay = retryAfter * 1000 * Math.pow(2, attempt); // exponential backoff
    await new Promise((resolve) => setTimeout(resolve, delay));
  }

  throw new Error("Rate limit exceeded after max retries");
}

2. Monitore os headers

Antes de atingir o limite, monitore X-RateLimit-Remaining para ajustar o ritmo das requisições:

TypeScript
const response = await fetch("https://api.liqi.com.br/public/tranches");
const remaining = parseInt(response.headers.get("X-RateLimit-Remaining") || "0", 10);

if (remaining < 10) {
  console.warn(`Rate limit baixo: ${remaining} requisições restantes`);
  // Reduzir velocidade das chamadas
}

3. Use cache local

Para dados que não mudam frequentemente (como lista de séries ou patrimônios), implemente cache no seu lado para evitar chamadas desnecessárias:

TypeScript
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos
let cachedTranches: { data: unknown; fetchedAt: number } | null = null;

async function getTranches() {
  if (cachedTranches && Date.now() - cachedTranches.fetchedAt < CACHE_TTL) {
    return cachedTranches.data;
  }

  const response = await fetch("https://api.liqi.com.br/public/tranches?status=ACTIVE");
  const data = await response.json();

  cachedTranches = { data, fetchedAt: Date.now() };
  return data;
}

4. Agrupe requisições

Sempre que possível, use filtros e paginação para buscar mais dados em menos chamadas, em vez de fazer várias chamadas individuais:

Bash
# Ruim: 1 chamada por série
curl "https://api.liqi.com.br/public/tranches/ROB1SR01/details"
curl "https://api.liqi.com.br/public/tranches/ROB1SR02/details"
curl "https://api.liqi.com.br/public/tranches/ROB1SR03/details"

# Bom: 1 chamada com filtro
curl "https://api.liqi.com.br/public/tranches?patrimonyTicker=ROB1&limit=50"

Próximos passos

  • Idempotência — Evite operações duplicadas com chaves de idempotência
  • Paginação — Navegue por grandes conjuntos de dados eficientemente
  • Erros — Trate todos os códigos de erro corretamente