Skip to main content

Per-organization buckets

Rate limits are enforced per organization, not per key. Every key issued to the same org shares one bucket, so adding keys doesn’t multiply your quota. The default limit is 100 requests per day per organization. A few endpoints carry an extra hourly ceiling on top of that allowance, and job polling draws from a bucket of its own: The hourly ceilings are additional, not separate: a Research call spends one of its 10 hourly slots and one of your 100 daily requests. Each endpoint’s page notes its limit. Batch requests count as one request per item: a 10-item batch consumes 10 from your quota, the same as 10 single calls.

Quota in response headers

Rate-limit state comes back as HTTP headers on every response (not in the body):

Retries and idempotency

Every Croma operation is a lookup: repeating a request with the same body returns the same result and never creates or changes a record, so retrying after a timeout or a dropped connection is always safe. Send an optional Idempotency-Key header (any string up to 255 characters, a UUID works) and the API echoes it back in the Idempotency-Key response header, so you can tie a retry to its first attempt in your logs. Each attempt that reaches the API counts against the quota above; a 429 tells you to wait for Retry-After seconds rather than retry immediately. | X-Request-Id | Unique id for the request (req_…); include it in support reports. | | X-Cache | HIT or MISS on cacheable endpoints. Cached hits still count against your quota. |

When you exceed the limit

Over-quota requests return 429 with a rate_limit_error envelope and a Retry-After header (seconds):
Back off until Retry-After elapses (or X-RateLimit-Reset), then retry.
The limiter fails open: if the rate-limit backend is briefly unavailable, requests are allowed through and no X-RateLimit-* headers are emitted. Don’t depend on the headers always being present.

Next: Errors

The error envelope and every error code.