Skip to main content
Rate limits protect the API from abuse and keep it fair for everyone. This page explains how they work and what a refused request looks like.

How Rate Limits Work

Requests are counted over a 15-minute window. When a window’s allowance is used up, further requests are refused with 429 Too Many Requests until the window ends. A refused request is not run.
  • A recognized API key is counted on its own, so one customer’s traffic never uses up another’s.
  • Anything else is counted by IP address: calls with no key, and calls with a key the API cannot vouch for.
  • A partner key is held to a ceiling of 1,000,000 requests per 15 minutes (about 1,100 a second). It is there to stop a runaway loop, not to meter a platform that serves hundreds of thousands of its own users.
The allowance that applies to a call is in the RateLimit-Limit header of its response, so read it there instead of hard-coding a number.

Reading Rate Limit Headers

Responses that were counted include rate limit headers:
  • RateLimit-Policy: the allowance and the length of the window in seconds (3000;w=900 is 3,000 requests per 900 seconds)
  • RateLimit-Limit: the requests allowed in the window
  • RateLimit-Remaining: the requests left in the window
  • RateLimit-Reset: the seconds until the window ends (a number of seconds to wait, not a timestamp)
The older X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers are sent as well. The first two carry the same numbers. X-RateLimit-Reset does not: it is the time the window ends, in Unix seconds, not a number of seconds to wait. Read the RateLimit-* headers. Use these to track your usage and slow down before you are refused.

Handling 429 Responses

Whichever limit you ran into, a refusal looks the same: a Retry-After header and the standard error envelope. Retry-After and error.retryAfter are the same number, in whole seconds (at least 1).
error.code tells you which limit it was:
  • RATE_LIMIT_EXCEEDED: the general limit for calls counted by IP address, the sign-in limit, or the limit on public embed endpoints
  • RATE_LIMIT_API_KEY_EXCEEDED: the limit on a recognized API key
  • RATE_LIMIT_USER_EXCEEDED: the brake on one person’s use of one kind of operation, such as billing changes (20 a minute), creating widgets (120 a minute), buying extra credits (10 an hour) or replaying a notification delivery (5 a minute). It is separate from the allowance on your key, and it is counted across all of that person’s keys and sessions. error.details.operation names the operation. Usage Limits lists them all
  • COST_LIMIT_EXCEEDED: a usage budget per hour or per day, not a count of requests. Retry-After is the end of the hour or day whose budget was used up
  • CONCURRENCY_LIMIT_EXCEEDED: too many operations of yours are running at once. It has no Retry-After: retry once one of them has finished
error.details carries what is particular to the limit (the limit, and for some codes the operation or the budgets). Do not depend on a key that is not documented for its code.
A refusal never reaches the operation, so it is safe to retry. When you retry a POST, send the same Idempotency-Key as the first attempt (see Idempotency).

Implementation Example

Best Practices

  1. Honor Retry-After - It is the time left until your counter starts over; retrying sooner is refused again
  2. Monitor headers proactively - Slow down before hitting limits
  3. Implement exponential backoff - When a refusal has no Retry-After, don’t retry immediately
  4. Use batch endpoints - Reduce total request count
  5. Cache responses - Avoid redundant requests
  6. Spread requests - Don’t burst all at once

Need Higher Limits?

Contact support@widgetic.com to discuss limits above what your key has today.