Resources
Mar 19, 20264 min read

Handling rate limits gracefully

Implement retry logic and exponential backoff to stay within the 60 req/min limit.

Overview

SynthLink enforces a 60 req/min rate limit and a 1,000 req/day daily limit. Limits are applied per approved email identity, so multiple API keys issued to the same email address share the same quota pool. Exceeding either returns a 429 Too Many Requests response. The API exposes rate-limit state through the RateLimit-Policy, RateLimit, and Retry-After headers, and may also include a retry_after field in the JSON body. This guide shows how to handle that gracefully.

Retry with backoff

fetch — retry with backoff
async function fetchWithRetry(url: string, options: RequestInit, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch(url, options);

    if (res.status !== 429) return res;

    const body = await res.json().catch(() => ({}));
    const retryAfterHeader = res.headers.get("Retry-After");
    const retryAfter = Number(retryAfterHeader ?? body.retry_after ?? Math.pow(2, i));
    const wait = retryAfter * 1000;

    await new Promise((r) => setTimeout(r, wait));
  }

  throw new Error("Max retries exceeded");
}

Preventing rate limit hits

  • Cache responses server-side and revalidate on a timer aligned to source update intervals.
  • Request only as many records as your UI needs — avoid fetching 100 when you display 10.
  • Schedule fetches to align with source cadence rather than polling continuously.