Skip to main content
You’ve sent more requests than the rate limit allows for this API key. Slow down and retry after the Retry-After header’s value.

What triggers it

  • Burst exceeded the per-key write limit on POST /v1/posts.
  • Burst exceeded the per-key media-upload limit on POST /v1/media.
  • Suspicious patterns flagged by the rate limiter.
The exact limits aren’t published as a contract — they’re tuned by environment and may move. Honor Retry-After and you’ll never need the number.

Response shape

rate_limited.json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded.",
    "remediation": "Wait the number of seconds in the Retry-After header before retrying.",
    "docUrl": "https://docs.letmepost.dev/errors/rate_limited",
    "requestId": "req_..."
  }
}
Retry-After is set on the response in seconds. Every response (not just 429s) also carries X-RateLimit-Limit — the static per-route ceiling — so a client can size concurrency without first probing a 429. We deliberately do not publish Remaining or Reset until per-key counting lands; those values would be misleading across tenants in v1.

How to handle

handle.ts
async function postWithBackoff(body: object) {
  for (let i = 0; i < 5; i++) {
    const res = await fetch("https://api.letmepost.dev/v1/posts", { /* ... */ });
    if (res.status !== 429) return res;
    const retry = Number(res.headers.get("retry-after") ?? 1);
    await sleep(retry * 1000);
  }
  throw new Error("rate limited five times in a row");
}

Distinct from upstream rate limits

This error is letmepost’s own per-key limit. When the upstream platform rate-limits us you’ll see platform_rejected or platform_unavailable with the upstream’s headers attached.