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
| API | Limite | Janela | Observação |
|---|---|---|---|
| Public API | 100 req | 1 minuto | Por IP de origem |
| Developer API | 60 req | 1 minuto | Por API Key |
| TIDC v1 | Customizado | Sob contrato | Definido no onboarding do originador |
| CaaS | Customizado | Sob contrato | Definido 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:
| Header | Descrição | Exemplo |
|---|---|---|
X-RateLimit-Limit | Total de requisições permitidas na janela | 100 |
X-RateLimit-Remaining | Requisições restantes na janela atual | 87 |
X-RateLimit-Reset | Timestamp Unix (segundos) de quando a janela reseta | 1708531200 |
Retry-After | Segundos ate poder enviar novamente (apenas em 429) | 12 |
Exemplo de headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1708531200Resposta 429 — Too Many Requests
Quando você excede o limite, a API retorna status 429:
{
"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:
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:
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:
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:
# 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