HubSpot 429: rate limit exceeded" contacts batch update
Handles HubSpot 429 rate limits on batch contact updates: honor Retry-After, shrink batch sizes, and pace daily volume. Use when batch updates start returning 429. Not for Salesforce REQUEST_LIMIT_EXCEEDED.
TL;DR
HubSpot rate-limits by rolling windows, so a fast batch loop trips 429 even under the daily cap. Read the Retry-After header, sleep, and retry the same batch; then slow the loop with smaller batches and spacing. Never drop the batch on a 429; the data is not written.
Error
{
"status": "error",
"message": "You have reached your daily limit",
"errorType": "RATE_LIMIT"
}Steps
- On a 429, read the Retry-After response header and sleep that many seconds plus a small buffer. Expected: the retry succeeds instead of hammering the limit.
- Cut the batch size in half (for example from 100 to 50) and add a short sleep between batches. Expected: the loop stays under the rolling window.
- Track usage via the X-HubSpot-RateLimit headers returned on every response. Expected: you see remaining quota before you hit zero.
- For large backfills, spread the work across the day or across multiple days rather than one burst. Expected: no 429s and no daily-limit lockout.
- Make the retry loop idempotent: re-sending the same batch update must be safe. Expected: a retried batch never creates duplicates or double-writes.
When to use
- HubSpot API returns 429 during batch contact updates.
- An agent enrichment run dies halfway with rate limit errors.
- Daily backfills that used to finish now stall.
When not to use
- Salesforce REQUESTLIMITEXCEEDED (different limits, different headers).
- 403 insufficient permissions (scopes, not rate).
- A single request 429ing (check for a loop, not a limit).
Tool compatibility
- HubSpot CRM API v3 batch endpoints; private apps.
- Any HTTP client that can read response headers.
Variant phrasings
You have exceeded the rate limit
The rolling-window form; slow down and retry with backoff.
daily limit reached on private app
The daily cap form; the only fix is waiting or spreading load.
Why it happens
HubSpot enforces both per-second and daily limits. Batch endpoints let you send a lot quickly, which is exactly how agents trip the per-second window while barely denting the daily allowance.
Edge cases
- Retry-After is in seconds; some clients misread it as milliseconds and retry far too early.
- Different endpoints share one quota pool; a search-heavy agent can starve its own write loop.
- 429s during OAuth token refresh need the same backoff; do not spin on refresh.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_bDDXSlO38IbN1AZZ86Urdw
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.