Rate limit headers

Understand and use rate limit response headers to manage API request throttling

Overview

When you exceed a rate limit, the Brevo API returns a 429 Too Many Requests status code along with response headers that provide information about the current rate limit status. These headers help you monitor your API usage and implement proper retry logic.

Use rate limit headers to:

  • Track remaining request capacity
  • Determine when rate limits reset
  • Implement exponential backoff strategies
  • Prevent unnecessary API calls

Rate limit headers

All rate-limited endpoints include the following headers in their responses:

HeaderDescription
x-sib-ratelimit-limitMaximum number of requests allowed in the current time window before receiving a 429 status code
x-sib-ratelimit-remainingNumber of requests remaining in the current time window
x-sib-ratelimit-resetTime remaining until the rate limit resets, expressed in the granularity unit (typically seconds)

Rate limit headers example

Reading rate limit headers

Limit header

The x-sib-ratelimit-limit header indicates the maximum number of requests you can make in the current time window. This value depends on your account plan and the specific endpoint.

Example:

x-sib-ratelimit-limit: 1000

This means you can make up to 1,000 requests in the current time window.

Remaining header

The x-sib-ratelimit-remaining header shows how many requests you have left before hitting the rate limit. Monitor this value to avoid 429 errors.

Example:

x-sib-ratelimit-remaining: 750

This indicates 750 requests remain in the current time window.

Reset header

The x-sib-ratelimit-reset header specifies when the rate limit counter resets. The value is expressed in the same granularity unit as the rate limit (typically seconds).

Example:

x-sib-ratelimit-reset: 45

This means the rate limit resets in 45 seconds.

Implementing retry logic

Use rate limit headers to implement intelligent retry mechanisms:

Check remaining capacity

Before making requests, check the x-sib-ratelimit-remaining header to ensure you have capacity:

1const response = await fetch('https://api.brevo.com/v3/account', {
2 headers: { 'api-key': 'YOUR_API_KEY' }
3});
4const remaining = parseInt(response.headers.get('x-sib-ratelimit-remaining') || '0', 10);
5
6if (remaining < 10) {
7 // Wait before making more requests
8 await new Promise(resolve => setTimeout(resolve, 60000));
9}

Handle 429 responses

When you receive a 429 response, read the reset header to determine how long to wait:

1if (response.status === 429) {
2 const resetTime = parseInt(response.headers.get('x-sib-ratelimit-reset') || '60', 10);
3 await new Promise(resolve => setTimeout(resolve, resetTime * 1000));
4 // Retry the request
5}

Exponential backoff

Combine rate limit headers with exponential backoff for robust error handling:

1async function makeRequestWithBackoff(url, headers, maxRetries = 3) {
2 for (let attempt = 0; attempt < maxRetries; attempt++) {
3 const response = await fetch(url, { headers });
4
5 if (response.status === 429) {
6 const resetTime = parseInt(response.headers.get('x-sib-ratelimit-reset') || '60', 10);
7 const waitTime = (resetTime + Math.pow(2, attempt) + Math.random()) * 1000;
8 await new Promise(resolve => setTimeout(resolve, waitTime));
9 continue;
10 }
11
12 return response;
13 }
14
15 throw new Error('Max retries exceeded');
16}

Best practices

Monitor headers proactively

Check x-sib-ratelimit-remaining before making bulk requests to avoid hitting limits:

1const remaining = parseInt(response.headers.get('x-sib-ratelimit-remaining') || '0', 10);
2if (remaining < batchSize) {
3 // Delay or split the batch
4}

Cache header values

Rate limit headers are consistent for the same endpoint and account. Cache these values to reduce unnecessary API calls when checking limits.

Use webhooks for high-volume operations

For high-volume operations like fetching statistics, use webhooks instead of polling endpoints. This reduces API calls and eliminates rate limit concerns.

Rate limit headers are included in all responses, not just 429 errors. Monitor them proactively to prevent rate limit issues.