Rate limits

How many requests the capability API accepts, what a 429 looks like, and how to back off.
View as Markdown

The /v1 API allows at least 67 requests per minute per organization. This is a guaranteed floor, not a hard global ceiling: enforcement happens per edge location and is eventually consistent, so a geographically distributed caller may sustain more before being limited.

The limit is shared across every /v1 endpoint — extract, parse, redact, fill, sign, pipelines, files, runs, templates, actions, and webhook management all draw from the same per-organization budget.

Scoped to your organization, not your key. Every organization API key in the same organization draws from one budget, and one organization exhausting it never affects another. Minting a second key does not buy more throughput.

What counts as one request

One HTTP request, one token — regardless of how much work it starts. A batch that fans out to 100 documents costs the same single token as a one-file call, which makes batching the cheapest way to stay under the limit at volume. Long-polling with ?wait= also costs one token no matter how long the call is held open, so waiting for a run is cheaper than polling it.

GET /v1/webhooks/jwks.json is the one exception: it is public, unauthenticated, and never rate limited, so key rotation can’t be locked out.

When you exceed it

You get 429 with the standard error envelope and a Retry-After header in seconds:

1HTTP/2 429
2content-type: application/json
3retry-after: 60
4x-request-id: req_01KYDQJBG32QDWHM5ERG63XGNE
1{
2 "code": "rate_limited",
3 "message": "Rate limit exceeded: 67 requests per minute per organization. Retry after 60 seconds.",
4 "retryable": true,
5 "requestId": "req_01KYDQJBG32QDWHM5ERG63XGNE",
6 "docUrl": "https://docs.cloudraker.com/developers/rate-limits"
7}

Nothing was started: a 429 never creates a run and is never billed, so replaying the identical request is safe.

How to retry

  1. Respect Retry-After first. It is the authoritative wait in seconds — sleep at least that long before the next attempt. Don’t compute your own delay when the header is present.
  2. Then back off exponentially on repeated 429s: 60 s, 120 s, 240 s, with jitter, so a fleet of workers doesn’t resynchronize into the next window together.
  3. Cap your concurrency rather than retrying harder. A steady ~1 request per second per organization never hits the floor.
  4. Send an Idempotency-Key on writes so a retry that crosses with a slow success returns the original run instead of starting a second one. The one exception is POST /v1/extract/batch, which ignores the header — one key cannot address N runs, so a retried batch fans out again. Track batches by metadata instead.

Retrying immediately on 429 — or in a tight loop without jitter — keeps you limited for longer. retryable: true means the same request can succeed later, not that it can succeed now.

Staying under the limit

  • Batch instead of looping. POST /v1/extract/batch turns 100 calls into one.
  • Use webhooks instead of polling. A terminal event costs you zero requests; polling a slow run costs one per check.
  • Long-poll when you must poll. GET /v1/runs/:id?wait=30 holds one request open instead of spending 30.
  • Reuse file ids. Registering a document once and re-running against {"id": …} avoids both re-parsing and extra calls.

Need a higher ceiling for a launch or a backfill? Talk to your CloudRaker contact with your expected peak — the floor above is what every organization gets without asking.

Where to go next