429 with Retry-After, a Link to this page, and:
RateLimit-Limit is the sustained quota for the window. RateLimit-Remaining is burst tokens left, so a short spike can succeed before the sustained cap binds. RateLimit-Reset is 0 while you are under quota. After a 429, RateLimit-Reset and Retry-After are the seconds to wait.
Counters are per api process.
What is limited
Identity is either the API key or the client IP. A Bearer key has its own read and write budgets. Dashboard cookies, probers, and anything that is not a key share an IP budget.
MCP uses the public REST API with your API key, so it shares the key budgets.
list_* / get_* are reads. Create, pause, ack, resolve, and test-check are writes. An agent that calls get_monitor in a loop spends the same 300 reads / min as curl.
A Bearer request counts against the key bucket. Session-cookie dashboard traffic uses the IP bucket only. The two do not share a budget. Unmatched paths (including wrong-method scans) count against the IP bucket.
Abuse-only routes
Tighter limits on expensive or guessable endpoints. Test-check, password unlock, subscribe, contact, and auth are the usual brute-force or cost targets.Never rate-limited
These stay available even when another client is over quota.- Heartbeat ingest
GET|POST /api/v1/heartbeats/:token - Public status-page reads (page, RSS, badge, by-host, verify)
- Stripe webhooks, Slack acknowledge, Caddy TLS ask,
GET /health,GET /
Handling 429
Wait Retry-After seconds (same value as retry_after_sec), then retry. Do not tight-loop: retries that ignore the header spend the burst bucket again and stay at 429. docs_url is always this page. For MCP, prefer one list_monitors over many get_monitor calls in the same turn.