API Reference

Rate Limits

Tiered limits, response headers, and how to handle 429s.

Gummble uses a three-tier rate limiter. Each tier has its own threshold and penalty. Authenticated traffic is keyed per-user; unauthenticated traffic is keyed per-IP (resolved through one proxy hop via req.ip, not raw X-Forwarded-For).

Tiers

TierLimitPenalty when exceeded
Backoff60 req / minExponential backoff via Retry-After
CAPTCHA120 req / minSliding-window block; CAPTCHA challenge required for next request
Banned240 req / minHard block, 1 hour cooldown

Sensitive endpoints (OAuth register, token, revoke, session) have lower per-route caps documented inline in the Authentication section.

Response headers

Every response includes:

RateLimit-Limit: 60
RateLimit-Remaining: 42
RateLimit-Reset: 1779555000

Handling 429

async function withBackoff(fn, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    const res = await fn()
    if (res.status !== 429) return res
    const retryAfter = Number(res.headers.get('retry-after') ?? 2 ** i)
    await new Promise(r => setTimeout(r, retryAfter * 1000))
  }
  throw new Error('Rate limit retries exhausted')
}

MCP-specific limits

MCP traffic from authenticated users gets per-user rate limiting on the Cloudflare Worker side, keyed by the JWT sub claim. Tool calls are counted per JSON-RPC batch item, not per HTTP request.