Skip to main content
Every API key has per-minute request limits that vary by endpoint, and a daily limit on calls and on rows returned.

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 carries Retry-After and a reason instead:

429 response

When the limit is exceeded, the API returns 429 Too Many Requests:
The response also includes a Retry-After header with the number of seconds to wait.

MCP server

The MCP server at mcp.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

  1. Read Retry-After and wait at least that many seconds before retrying.
  2. Use exponential backoff if you receive multiple 429s in a row: wait 1s, 2s, 4s, etc.
  3. Check X-RateLimit-Remaining before 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.

Higher limits

Contact api@courtrules.app with your use case. We can increase limits for production integrations.