Rate limits
A API sinaliza excesso de requisições com 429 Too Many Requests e
o header
Retry-After. As cotas numéricas não são publicadas — não presuma um valor fixo; programe para reagir ao 429 e reduza
chamadas com cache.
Como o limite é sinalizado
- Status
429com o envelope de erro:error.code: RATE_LIMIT_EXCEEDED,error.retryable: trueeerror.retryDelayem milissegundos. - Header
Retry-After(em segundos): quanto esperar antes da próxima tentativa. Respeite-o — repetir antes só prolonga o bloqueio.
{
"success": false,
"error": {
"message": "Você atingiu o limite de requisições.",
"code": "RATE_LIMIT_EXCEEDED",
"type": "rate_limit",
"statusCode": 429,
"retryable": true,
"retryDelay": 60000,
"requestId": "req_5c26469a-1234-4c8b-9e21-370450bbda3a",
"docs": "https://docs.draftin.io/errors/RATE_LIMIT_EXCEEDED"
}
} Proteções específicas de anúncios
Embora não seja um limite de taxa clássico, o endpoint de clique em anúncios
aplica
deduplicação por IP: cliques repetidos do mesmo IP no mesmo
anúncio dentro de
30 minutos são aceitos com 200, mas não incrementam
a métrica. Além disso, cada clickToken é de uso único (reuso retorna
409) e expira em 10 minutos. Veja
Anúncios · Delivery.
Boas práticas
- Cacheie conteúdo publicado. Posts, categorias e tags mudam pouco. Em sites estáticos/SSR, busque no build ou com revalidação por intervalo em vez de a cada visita.
- Prefira chamadas no servidor. Evite que cada visitante dispare uma requisição direta à API — isso concentra carga e expõe a chave.
- Respeite o
Retry-Afterao receber429, e implemente backoff exponencial para5xx, com um teto de tentativas. - Respeite os limites de paginação (
limitaté 100 em posts, 50 na busca) e pagine em vez de pedir grandes volumes de uma vez.
Retentativa com backoff
Um wrapper de fetch que repete em erros transitórios e respeita o
Retry-After do 429:
async function fetchComRetry(
url: string,
init: RequestInit,
tentativas = 3,
): Promise<Response> {
let ultimoErro: unknown;
for (let i = 0; i < tentativas; i++) {
try {
const res = await fetch(url, init);
if (res.status === 429) {
// respeita o Retry-After do servidor (em segundos)
const after = Number(res.headers.get("Retry-After") ?? 1);
await esperar(after * 1000);
continue;
}
if (res.status >= 500) {
await esperar(2 ** i * 300); // 300ms, 600ms, 1200ms…
continue;
}
return res; // inclui 200, 401, 404…
} catch (err) {
ultimoErro = err;
await esperar(2 ** i * 300);
}
}
throw ultimoErro ?? new Error("Falha após retentativas");
}
const esperar = (ms: number) => new Promise((r) => setTimeout(r, ms));