Daily limits
Keys without a plan of their own are on the free limits:
A list counts one row for each item it returns. A single rulebook or rule counts as one row, however long its text. For example, a full
GET /api/v1/courts counts one row for every court in the list, so a few full lists use a whole day’s rows. Keep the list, or read one court with GET /api/v1/courts/{district_id}.
Days run from 00:00 UTC. A key that is shared by several people (the console key) is counted per network address, and all of its callers also share one daily total. The MCP server counts the same way, per signed-in user or per key.
When a daily limit is reached the API answers 429 with "error": "Usage limit reached", a reason (minute, day, rows or shared) and a Retry-After header. Keys for production integrations have higher limits: write to api@courtrules.app.
Limits by endpoint
RPM = requests per minute, per API key. The endpoint limits use a sliding window. The daily limits above, and the 30 calls a minute on the free limits, count in fixed windows: the clock minute and the UTC day.
Response headers
Responses from the endpoint limits include rate limit headers. A response refused by the daily limits carriesRetry-After and a reason instead:
429 response
When the limit is exceeded, the API returns429 Too Many Requests:
Retry-After header with the number of seconds to wait.
MCP server
The MCP server atmcp.courtrules.app uses the same limits, counted for each signed-in user or for each API key. Accounts that sign in from one network address also share a larger total for that network, so a call can be refused because the network has reached it. When a call goes over a limit, the tool returns an error whose text names the limit and how long to wait, and it tells the assistant to stop instead of retrying in a loop.
One answer holds at most 500 rows on the free limits. A longer list is cut, and the answer says how many rows it held and how to narrow the query, for example with district_id, judge_slug or year.
Retry guidance
- Read
Retry-Afterand wait at least that many seconds before retrying. - Use exponential backoff if you receive multiple 429s in a row: wait 1s, 2s, 4s, etc.
- Check
X-RateLimit-Remainingbefore sending requests to avoid hitting the limit in the first place.
Common mistakes
Tight-loop classify calls./classify is limited to 5 RPM because each request takes 10 to 30 seconds to read a PDF. If you need to process a batch, space requests at least 12 seconds apart or queue them server-side.
Ignoring Retry-After. Retrying immediately after a 429 wastes your remaining budget and delays recovery. Always respect the header value.
Polling /check on every keystroke. While /check has a generous 60 RPM limit, calling it on every form change in a UI can still exhaust it. Debounce to at most once per second.