Error Medic

How to Fix HubSpot API '429 Too Many Requests' and Rate Limit Errors

Fix HubSpot API 429 Too Many Requests and timeout errors. Learn how to handle TEN_SECONDLY_ROLLING limits, implement exponential backoff, and optimize API calls

Last updated:
Last verified:
1,044 words
Key Takeaways
  • Identify if you are hitting the 10-second (burst) or daily rate limit by inspecting response headers.
  • Implement exponential backoff and retry logic in your API client to handle 429 status codes gracefully.
  • Optimize API calls by using batch endpoints and webhook subscriptions to drastically reduce overall request volume.
Fix Approaches Compared
MethodWhen to UseTimeRisk
Exponential BackoffStandard best practice for all API integrationsMediumLow
Batch ProcessingWhen updating or creating multiple records at onceMediumLow
Upgrading HubSpot TierWhen daily limits are consistently exceeded legitimatelyLowHigh (Cost)
Caching StrategiesRead-heavy applications fetching standard CRM dataHighMedium (Stale data)

Understanding HubSpot API Rate Limits

When integrating with HubSpot, developers frequently encounter the 429 Too Many Requests error. This status code indicates that your application has exceeded the number of API calls permitted within a specific timeframe. HubSpot enforces rate limits to ensure stability and fair usage across all accounts. Closely related are 504 Gateway Timeout or hubspot api timeout errors, which can occur if your connection drops while waiting for a bulk operation or if HubSpot's servers are overloaded by burst traffic.

HubSpot employs two primary types of rate limits:

  1. Secondly Limits (Burst): typically 100 or 150 requests per 10 seconds, depending on your authentication method (OAuth vs. Private App) and HubSpot subscription tier.
  2. Daily Limits: ranging from 250,000 to 1,000,000 requests per day, resetting at midnight Eastern Time (EST/EDT).

The error payload usually looks like this:

{
  "status": "error",
  "message": "You have reached your ten_secondly_rolling limit.",
  "errorType": "RATE_LIMIT",
  "correlationId": "1234abcd-5678-efgh-9012-ijklmnop3456",
  "policyName": "TEN_SECONDLY_ROLLING"
}

Step 1: Diagnose the Root Cause

Before writing a fix, determine which limit you are hitting.

Inspect the HTTP response headers returned by HubSpot. HubSpot provides rate limit headers with every response:

  • X-HubSpot-RateLimit-Daily: Your daily limit.
  • X-HubSpot-RateLimit-Daily-Remaining: The number of API calls remaining for the day.
  • X-HubSpot-RateLimit-Secondly: Your 10-second burst limit.
  • X-HubSpot-RateLimit-Secondly-Remaining: Remaining burst limit capacity.

If X-HubSpot-RateLimit-Secondly-Remaining drops to 0, your application is firing requests too rapidly. If X-HubSpot-RateLimit-Daily-Remaining hits 0, your overall integration volume is too high.

Additionally, check for hubspot api timeout (504/502 errors). These happen when you send massive payloads (like batch importing 10,000 contacts in a single heavily-associated request) that take too long for the server to process before the connection times out.

Step 2: Implement Exponential Backoff (The Standard Fix)

The most robust way to handle 429 Too Many Requests is by implementing an exponential backoff algorithm. When a 429 error occurs, your application should pause, wait for a short duration, and retry. If it fails again, the wait time increases exponentially.

Here is the logic flow:

  1. Make an API call.
  2. If response is 200 OK, continue.
  3. If response is 429 Too Many Requests, prepare to pause.
  4. Wait for $2^n$ seconds (plus some random jitter to avoid thundering herd problems) where $n$ is the retry attempt.
  5. Retry the request.

Step 3: Optimize with Batch Endpoints

If you are iterating through a list of contacts and making a separate API call for each (an N+1 problem), you will quickly burn through your 10-second limit.

Anti-Pattern (Causes 429s):

// DO NOT DO THIS
for (const contact of contactList) {
  await hubspotClient.crm.contacts.basicApi.create(contact);
}

Best Practice (Batching): Use HubSpot's batch endpoints to send up to 100 records per single API call.

// DO THIS INSTEAD
const batchInput = { inputs: contactList };
await hubspotClient.crm.contacts.batchApi.create(batchInput);

Step 4: Caching and Webhooks

To drastically reduce read requests and prevent daily limit exhaustion:

  • Caching: Cache frequently accessed, rarely changing data (like custom property definitions or owner IDs) in a local Redis instance or application memory.
  • Webhooks: Instead of polling HubSpot every 5 minutes to see if a contact changed, set up Webhooks. HubSpot will push a payload to your endpoint only when an event actually occurs. This shifts the architecture from pull to push, nearly eliminating unnecessary API polling calls.

Frequently Asked Questions

python
import time
import random
import requests
from requests.exceptions import HTTPError

def hubspot_api_request_with_backoff(url, headers, data=None, max_retries=5):
    retries = 0
    backoff_factor = 2
    
    while retries < max_retries:
        try:
            if data:
                response = requests.post(url, headers=headers, json=data)
            else:
                response = requests.get(url, headers=headers)
                
            response.raise_for_status()
            return response.json()
            
        except HTTPError as e:
            if response.status_code == 429:
                # Exponential backoff with jitter
                wait_time = (backoff_factor ** retries) + random.uniform(0, 1)
                print(f"Rate limit hit (429). Retrying in {wait_time:.2f} seconds...")
                time.sleep(wait_time)
                retries += 1
            elif response.status_code in [502, 504]:
                print("HubSpot API timeout. Reducing payload size or retrying...")
                time.sleep(5)
                retries += 1
            else:
                raise e
                
    raise Exception("Max retries exceeded for HubSpot API call")

# Example Usage:
# headers = {"Authorization": "Bearer YOUR_PAT"}
# result = hubspot_api_request_with_backoff('https://api.hubapi.com/crm/v3/objects/contacts', headers)
E

Error Medic Editorial

Error Medic Editorial is a team of veteran Site Reliability Engineers and DevOps practitioners dedicated to solving complex integration, infrastructure, and API challenges.

Sources

Related Articles in Hubspot Api

Explore More API Errors Guides