reference

rate limiting

global baseline, per-route limits, and 429 responses

rate limiting

two layers: a global baseline and optional per-route limits.

global baseline

200 requests per 60 seconds per ip. enforced by cloudflare's built-in rate limiter across all edge locations.

applies to all routes except /api/auth/*, /health, /reference, and /openapi.json.

per-route limits

some routes have stricter limits enforced via kv-based fixed window counters:

route limit window
POST /internal/render/mermaid 10 60s
POST /internal/layout/elk 50 60s

per-route limits are checked before the global limit. both must pass.

when you hit the limit

the api returns 429 with an rfc 9457 problem details body:

{
  "type": "https://api.gnu.foo/errors/rate-limit-exceeded",
  "title": "rate limit exceeded",
  "status": 429,
  "detail": "too many requests, please try again later",
  "_links": {
    "self": { "href": "/tools" },
    "root": { "href": "/" }
  }
}

reducing requests

use etag-based conditional requests — if the resource hasn't changed you get a 304 with no body:

curl -H "If-None-Match: W/\"abc\"" gnu.foo/tools

responses include Cache-Control headers. respect them.