Skip to main content
Rate limits cap how many requests a client can send in a minute. They keep one client from saturating the API so other traffic still lands. Heartbeats and public status-page reads are not limited: ingest and public pages must keep working even if a script is over quota. You hit a cap when a script, MCP agent, or scanner loops too fast, not when Tallwatch is checking your monitors. Writes are tighter than reads because they change data. Over a cap: 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. Create and scope keys on API keys. Agent setup is on MCP.