Rate limiting
Check’s API uses rate limits to protect platform stability. These limits also surface integration mistakes early — patterns like infinite loops, hot polling, or overly aggressive concurrency — so you can fix them before they cause trouble.
The API enforces two limits per partner across all keys: a request rate limit that scales with the size of your business, and 100 concurrent in‑flight requests. When you exceed either, you’ll receive HTTP 429 with a Retry-After header that tells you when it’s safe to try again. Note, the concurrency limit is not configurable.
Rate limit tiers
Your request rate limit is based on the number of payees you paid in the prior calendar month. It is an entitlement keyed to the size of your business, not to your observed request volume.
| Monthly payees (prior calendar month) | Request rate limit |
|---|---|
| Fewer than 1,000 | 10 requests per second |
| 1,000 – 10,000 | 20 requests per second |
| 10,000 – 50,000 | 40 requests per second |
| 50,000+ | 80 requests per second |
A few things to know about how tiers work:
- Limits recompute monthly. A monthly job recalculates your tier from the prior calendar month’s payees. Increases apply automatically—you don’t need to request them.
- Limits are never automatically lowered. If your payee count dips (for example, seasonally), your limit stays where it is.
- Higher throughput for one-time workloads. If you need temporarily higher throughput for a legitimate workload such as a backfill or migration, contact developer support.
In Sandbox, the default rate limit is 10 requests per second. This is intentional: Sandbox is the right place to exercise your 429 handling and retry logic before it matters in production.
Why you might be rate limited
Most throttling comes from a few predictable patterns.
- Bursts. Fan‑outs, scheduled jobs that all run at the same time, or a “bulk” button in a UI can spike your request rate above your limit even when the average is low.
- High concurrency. Many long‑running requests such as synchronous calculations or large syncs consume in‑flight slots and reduce headroom for other work.
- Hot polling and contention. Tight polling loops for status plus concurrent writes to the same resource add latency and multiply retries.
429s are backpressure, not a bug—they’re the API telling your client to slow down. Occasional 429s during bursts are expected at every tier; a well‑built integration absorbs them with retries and keeps going. Handle them gracefully and you won’t need to page on every 429. Instrument your API integration using standard observability tooling to identify hot spots to optimize.
Handling rate limits
Handling throttled requests follows the same pattern. Once you receive HTTP 429 and a Retry-After header, respect that header upon retry. For writes, include an idempotency key (see Idempotent Requests) so retries don’t duplicate work. Bound the overall retry window to avoid unbounded work buildup. Rate limits change over time, so programmatically preparing for 429s will save maintenance in the future.
Rate limit response headers
Every authenticated API response includes two headers that report your current rate limit status:
| Header | Description |
|---|---|
RateLimit-Limit | Your total request quota for the current window. |
RateLimit-Remaining | The number of requests remaining before you hit the limit. |
These headers follow the IETF RateLimit Headers draft specification. When multiple rate limit scopes apply to a request, the headers reflect the most restrictive scope.
HTTP/1.1 200 OK
Content-Type: application/json
RateLimit-Limit: 40
RateLimit-Remaining: 33
{ ... }Use these headers to monitor your consumption in real time and back off proactively before hitting 429. Because limits can increase over time, read your current limit from RateLimit-Limit rather than hardcoding it.
Response shape when throttled
A limited request returns HTTP 429 and JSON like:
{
"error": {
"type": "throttled",
"message": "Request was throttled. Expected available in 1 second."
}
}You’ll also receive Retry-After: <seconds>. Wait at least that long before retrying. Responses use our standard Errors envelope; the type will be throttled. 429s can come from either the requests per second or concurrency limit.
Working with many resources
Check endpoints operate on a single resource at a time. That keeps behavior clear, makes idempotency straightforward, and protects platform health. When you need to move quickly across many resources, these patterns work well:
- Process bulk work in batches. Chunk large volumes of updates into bounded batches and run a limited number of batches in parallel.
- Serialize writes per resource. Queue updates to the same resource so mutations happen in order.
- Stagger scheduled jobs. Randomize start times to avoid top‑of‑minute pileups.
- Prefer webhooks to polling. Subscribe to events and react to state changes.
See Batching requests for more details on how to work with many resources.
Updating many payments on a payroll. Where supported, use payroll‑scoped batch endpoints for payroll items and contractor payments. For larger payrolls, chunk updates and serialize writes per payroll to avoid contention on the payroll.
Updated 6 days ago

