Rate limits
Direct API access is limited per organization. A program should read its limits from the response headers rather than hard-code them, because plans and their numbers can change.
What is counted
Section titled “What is counted”| Quota | Window |
|---|---|
| Burst | 60 seconds |
| Daily | The calendar day, in UTC |
| Monthly | The calendar month, in UTC |
- The quotas belong to the organization. All of its machine clients share them. There is no separate quota per client.
- The size of each quota depends on the organization’s plan, which is one of
free,small,medium, orlarge. A plan’s quotas are the ones this environment enforces. - A plan change reaches API clients within 10 minutes. A client picks it up when it next gets an
access token. This needs the
urn:zitadel:iam:user:metadatascope in the token request. See Authentication. - A request that the API refuses for its scope, role, subscription, or kind of client still counts,
so probing isn’t free. Once a quota is used up, such a request gets
429instead of its403. A request that fails authentication is not counted. - Some operations have their own limits as well. AI operations (
askOpportunities) also count against the organization’s AI spending budget and its premium units for the day. A search that ranks by meaning uses a premium unit too. The API counts premium units itself, so the gateway’s quotas don’t include them. See the API’s answer.
Two places refuse a request
Section titled “Two places refuse a request”A call can be refused in front of the API or by the API itself. The two answers look different, so read the response by what it carries.
| Refused by | Body | Headers |
|---|---|---|
| The gateway, for machine clients | Empty | X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset |
| The API | A Problem (rate-limited) |
Retry-After, RateLimit-Policy, RateLimit |
The gateway’s answer
Section titled “The gateway’s answer”For a machine client’s calls the gateway refuses first. Its 429 has no body. It has no
Retry-After, no RateLimit headers, and no Problem.
HTTP/1.1 429 Too Many RequestsX-RateLimit-Limit: 3000, 3000;w=2592000X-RateLimit-Remaining: 0X-RateLimit-Reset: 1203400| Header | Meaning |
|---|---|
X-RateLimit-Limit |
The exhausted rule’s limit and its window w in seconds, such as 3000, 3000;w=2592000. |
X-RateLimit-Remaining |
What is left in that window. It is 0 on a 429. |
X-RateLimit-Reset |
Seconds until that window resets. |
The same headers also appear on the gateway’s successful responses. The example is a free plan
organization that has used its 3,000 requests for the month.
The response doesn’t name the quota. Read it from the window w and the limit:
w (seconds) |
Quota |
|---|---|
| 60 | Burst. |
| 86400 | Daily. |
| 2592000 | Monthly. The calendar month is reported as 30 days. X-RateLimit-Reset is exact. |
Wait X-RateLimit-Reset seconds before you retry. Refused requests still count. A client that
keeps calling after a 429 keeps adding to the counter, so it doesn’t regain budget inside the
window.
The API’s answer
Section titled “The API’s answer”For everything the gateway doesn’t cover, the API refuses with a 429, a Problem of type
rate-limited, and Retry-After.
HTTP/1.1 429 Too Many RequestsContent-Type: application/problem+jsonRetry-After: 41000RateLimit-Policy: "org-burst";q=20;w=60, "org-day";q=100;w=86400RateLimit: "org-burst";r=7;t=40, "org-day";r=0;t=41000
{ "type": "https://fedwright.com/problems/rate-limited", "title": "Too Many Requests", "status": 429, "traceId": "4bf92f3577b34da6a3ce929d0e0e4736", "limit": "org-day", "resetsAt": "2026-11-08T00:00:00Z"}Retry-Afteris the number of seconds until the used-up limit’s window resets. If several limits are used up, it is the latest.limitnames the quota that is used up, andresetsAtsays when it starts again.- A request the API refuses with
rate-limiteduses no quota.
Two refusals carry their own problem types:
| Type | When |
|---|---|
ai-budget-exceeded |
An ask that the organization’s AI spending budget can’t cover. Retry-After is the end of the budget’s window. The budget counts what asks cost, not how many there are. |
premium-quota-exceeded |
An ask that the organization’s premium units for the day can’t cover. limit is org-premium-day, and resetsAt is the next midnight UTC. A refused ask uses no units. |
A search that ranks by meaning is not refused when the premium units run out. It runs as a search by
words instead, and its semantic.reason is premiumQuota.
The RateLimit-Policy and RateLimit headers
Section titled “The RateLimit-Policy and RateLimit headers”Where the API applies a limit it reports the caller’s own limits on the response, successful or not. They follow the IETF HTTPAPI rate-limit header fields, which are still a draft. Parse them leniently and ignore anything you don’t recognize.
| Header | Contents |
|---|---|
RateLimit-Policy |
Each limit’s name, its quota q, and its window w in seconds. |
RateLimit |
For each limit in the policy, the requests r still allowed and the seconds t until reset. |
RateLimit-Policy: "org-burst";q=20;w=60, "org-day";q=100;w=86400RateLimit: "org-burst";r=7;t=40, "org-day";r=62;t=41000Handling a 429
Section titled “Handling a 429”- Don’t retry at once. Wait the number of seconds the response gives:
X-RateLimit-Resetfor an empty-bodied429,Retry-Afterfor a Problem. - If the wait is longer than your program can hold, such as hours for a daily quota, stop and report it instead of sleeping inside the call.
- A
429is returned before the operation runs, so retrying any operation, including aPOST, can’t repeat its effect. - Spread calls out to stay under the burst quota. A client that checks
RateLimitorX-RateLimit-Remainingcan slow down before it is refused.
See Errors for the Problem format.