Rate Limits

Learn how ZoomInfo API rate limits work and how to build integrations that handle them gracefully.

ZoomInfo enforces rate limits on all authenticated API requests to ensure stability and fair resource allocation across all customers. If you send too many requests in a short period, you will receive 429 Too Many Requests responses.


How rate limits work

Every API request is evaluated against three independent windows simultaneously:

WindowDurationResets at
Per-second1 secondEvery second
Per-hour1 hourRolling sliding window
Per-day24 hoursRolling sliding window

All three windows must have remaining capacity for a request to succeed. If any window is exhausted, the request is rejected with a 429 response.

πŸ“˜

Rejected requests do not consume quota. Retrying while rate-limited will not burn your remaining budget.

ZoomInfo uses a sliding window counter algorithm for the per-hour and per-day limits. Unlike a fixed window that resets abruptly at set intervals β€” allowing a double burst at the boundary β€” the sliding window carries a decaying contribution from the previous window, ensuring smooth and consistent enforcement.


Rate limit tiers

Your rate limits are determined by your ZoomInfo subscription and are visible on every API response via the X-RateLimit-Limit-* headers.

PackagePer SecondPer HourPer Day
Builder5 req/s10,800129,600
Standard25 req/s54,000648,000
Scaling35 req/s75,600907,200

Hourly and daily limits are intentionally set below the theoretical per-second maximum to prevent sustained abuse while still accommodating legitimate traffic spikes.

To request a higher limit, see Requesting a limit increase.


Response headers

ZoomInfo returns quota headers on every API response so you can monitor usage proactively and throttle before hitting a limit.

On every response

Header

Description

X-RateLimit-Limit

Your configured per-second limit.
This is deprecated and will be removed on 2027-01-01.
Use X-RateLimit-Limit-Second instead

X-RateLimit-Remaining

Requests remaining in the current second.
This is deprecated and will be removed on 2027-01-01.
Use X-RateLimit-Limit-Second-Remaining instead

X-RateLimit-Limit-Second

Your configured per-second limit

X-RateLimit-Remaining-Second

Requests remaining in the current second

X-RateLimit-Limit-Hour

Your configured per-hour limit

X-RateLimit-Remaining-Hour

Requests remaining in the current hour window

X-RateLimit-Limit-Day

Your configured per-day limit

X-RateLimit-Remaining-Day

Requests remaining in the current day window

On 429 responses only

HeaderDescription
Retry-AfterNumber of seconds to wait before retrying
X-RateLimit-Rejected-BucketWhich window caused the rejection: second, hour, or day
X-RateLimit-ResetUnix epoch timestamp (seconds) of when the breached window resets
πŸ“˜

A value of -1 in any X-RateLimit-Remaining-* header means the quota service was temporarily unavailable. Your request was allowed through, but quota state is unknown. This is not an error condition for your integration.


Handling 429 responses

When you receive a 429 response:

  1. Check X-RateLimit-Rejected-Bucket to identify which window was breached: second, hour, or day.
  2. Read Retry-After for the exact number of seconds to wait before retrying.
  3. Read X-RateLimit-Reset for the Unix epoch timestamp of when the breached window resets β€” useful for scheduling work after a quota boundary.
  4. Do not retry immediately. The Retry-After value may be hundreds or thousands of seconds if an hourly or daily quota is exhausted.

Example 429 response

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 25
X-RateLimit-Remaining: 25
X-RateLimit-Limit-Second: 25
X-RateLimit-Remaining-Second: 25
X-RateLimit-Limit-Hour: 54000
X-RateLimit-Remaining-Hour: 0
X-RateLimit-Limit-Day: 648000
X-RateLimit-Remaining-Day: 94000
X-RateLimit-Rejected-Bucket: hour
X-RateLimit-Reset: 1744246800
Retry-After: 719

The hour window was exhausted. Wait 719 seconds (~12 minutes) before retrying, or schedule work after the Unix timestamp 1744246800.

Retry strategy by window

X-RateLimit-Rejected-BucketRecommended action
secondShort exponential backoff (1–5 seconds)
hourPause and resume after Retry-After seconds
dayPause and resume after Retry-After seconds

Exponential backoff example


Do not use a fixed 1-second retry loop. The Retry-After value may be 719 seconds or more when an hourly quota is exhausted. Ignoring it and retrying immediately will not succeed.


Proactive throttling

Rather than waiting for a 429, read the Remaining headers on every response and slow down before hitting a limit:

X-RateLimit-Remaining-Second: 2   β†’ slow down immediately
X-RateLimit-Remaining-Hour: 120   β†’ reduce throughput for the rest of this hour
X-RateLimit-Remaining-Day: 400    β†’ schedule lower-priority work for tomorrow

Distributing requests evenly across the hour and day β€” rather than front-loading them β€” is the most reliable way to avoid quota exhaustion.


Burst behavior

First use

On your first hour of API usage, the full hourly quota is available as an instant burst. There is no prior usage history to penalize.

Steady state

From the second hour onward, the sliding window carries a decaying contribution from the previous hour. If you exhaust your hourly quota, the next hour's slots open gradually β€” not all at once at the boundary β€” as the previous hour's contribution decays.

Per-second boundary protection

Sending requests across a second boundary does not give you a burst advantage. Requests from the previous second count fully against the current second's limit. Sending 25 requests in the last 500ms of one second and 25 more in the first 500ms of the next results in requests 26–50 being rejected.


Migrating from legacy headers

If your integration uses the old header names, update your code as follows:

Old header

New header

Action required

X-RateLimit-Limit

X-RateLimit-Limit-Second

X-RateLimit-Limit is deprecated and will be removed on 2027-01-01.
Use X-RateLimit-Limit-Second instead

X-RateLimit-Remaining

X-RateLimit-Remaining-Second

X-RateLimit-Limit-Remaining is deprecated and will be removed on 2027-01-01.
Use X-RateLimit-Limit-Second-Remaining instead

X-RateLimit-Reset

X-RateLimit-Reset (retained, new semantics)

Header value changed β€” update retry logic if you rely on this header

Semantics change: X-RateLimit-Reset now reflects when your current request volume drops below the limit under the sliding window algorithm, rather than when the fixed rate-limit window expires. The value is a Unix epoch timestamp; in most cases it will be earlier than before, since you no longer have to wait for the full window to roll over.


Requesting a limit increase

If your use case requires higher throughput than your current package provides:

  1. Contact your ZoomInfo account team or email us at [email protected].
  2. Provide your Tenant ID and the desired per-second value.
  3. New limits take effect within 24 hours of the change being applied.

FAQ

Q: My retry loop was designed around Retry-After: 1. I'm now seeing Retry-After: 3595. Is this correct?

Yes. If your hourly quota is exhausted, Retry-After accurately reflects how long until the window boundary β€” potentially close to one full hour. Update your retry logic to honor the precise value rather than assuming a 1-second wait.


Q: I exhausted my hourly quota in the first 10 minutes. When can I make my next request?

Check the Retry-After header on the 429 response for the exact wait time, or use X-RateLimit-Reset to determine the Unix timestamp when the window resets. The first slot opens one second after the window boundary as the previous hour's contribution begins to decay.


Q: How do daily quotas reset β€” rolling 24 hours or calendar days?

Fixed calendar days aligned to UTC midnight. Monitor X-RateLimit-Remaining-Day to track your daily budget. If you receive X-RateLimit-Rejected-Bucket: day, schedule remaining work after the next UTC midnight.


Q: What happens if ZoomInfo's quota service is unavailable?

The gateway fails open β€” all requests are allowed through during a short cooldown period, after which normal enforcement resumes. During this window, X-RateLimit-Remaining-* headers return -1 to indicate that quota state is unknown.


Q: Does the per-second limit protect against bursts at second boundaries?

Yes. Requests from the previous second count fully against the current second's limit. There is no burst advantage at second boundaries.


Q: My integration reads X-RateLimit-Limit and X-RateLimit-Remaining. Will it break?

Those headers are still emitted but are deprecated and will be removed on 2027-01-01. Update your client to read X-RateLimit-Limit-Second and X-RateLimit-Remaining-Second, and add handling for the -Hour and -Day variants.


For additional help, contact your ZoomInfo account representative or reach out to ZoomInfo Support.