Rate limits
The API is rate-limited with token buckets, per key
and per team. Every response carries the headers you need to pace yourself, and a
429 tells you exactly how long to wait. This page lists the bucket classes and the
introspection endpoint; the concrete numbers are deployment configuration and are
marked as examples below.
the buckets
Section titled “the buckets”There are two layers, and a request must satisfy both. Per-key buckets give each credential predictable headroom; the team ceiling keeps one noisy team — or a team that mints many keys — from starving everyone else. Minting more keys never buys more total throughput.
| Bucket | Limit (example) | Applies to |
|---|---|---|
Per-key — read (GET) |
1000 / min | each API key |
Per-key — write (PATCH/PUT/DELETE) |
100 / min | each API key |
Per-key — create (POST) |
5 / min | each API key |
| Team ceiling | 5000 / min aggregate | all keys on a team |
response headers
Section titled “response headers”Every authenticated response includes the state of the bucket the request drew from,
so a well-behaved client never needs to hit a 429 to discover the limit:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
The bucket’s ceiling for this request class. |
X-RateLimit-Remaining |
Requests left in the current window. |
X-RateLimit-Reset |
Unix seconds when the bucket refills to full. |
Retry-After |
Seconds to wait — present only on a 429. |
HTTP/1.1 200 OKX-RateLimit-Limit: 1000X-RateLimit-Remaining: 994X-RateLimit-Reset: 1782192000the 429 body
Section titled “the 429 body”When a bucket empties you get a 429 with Retry-After and the standard
error envelope. Back off for the stated seconds — don’t
retry tighter.
HTTP/1.1 429 Too Many RequestsRetry-After: 12X-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: 1782192012{ "error": { "type": "rate_limit", "code": "rate_limit.exceeded", "message": "rate limit exceeded; retry after 12s", "doc_url": "https://docs.managed.dev/errors/rate_limit/rate_limit.exceeded" }, "request_id": "req_01J9F2KQ"}The Go SDK honors Retry-After automatically with exponential
backoff, so you rarely handle a 429 by hand unless you’ve written a raw client.
introspecting your limits
Section titled “introspecting your limits”Don’t hard-code the numbers — read them. GET /v1/rate-limits returns the live
buckets and their current state for the calling key without consuming a token, so
a client can self-throttle or poll it freely:
curl https://api.managed.dev/v1/rate-limits \ -H "Authorization: Bearer mfk_live_…"{ "data": { "buckets": [ { "class": "read", "limit": 1000, "remaining": 994, "reset": 1782192000 }, { "class": "write", "limit": 100, "remaining": 100, "reset": 1782192000 }, { "class": "create", "limit": 5, "remaining": 4, "reset": 1782192000 } ], "team_ceiling": { "limit": 5000, "remaining": 4980, "reset": 1782192000 } }, "request_id": "req_01J9F2KQ"}Each bucket reports its class (omitted on the team ceiling), limit, remaining,
and reset. The same data is one call away in every client: mf ratelimits in the
CLI, client.RateLimits.Get(ctx) in the Go SDK, and the
get_rate_limits tool on the MCP server.
limits scale with your plan
Section titled “limits scale with your plan”Rate limits track your plan tier: higher tiers get larger per-key buckets and a higher team ceiling, matching the larger fleets they run. The exact per-tier numbers are part of the same catalog reconciliation as the plan limits, so they’re held as examples here until finalized.