HubSpot’s API is generous until it isn’t. Hit the per-second cap during a marketing send and your downstream integrations queue up, time out, and silently drop work. Here’s the survival architecture.
Know the actual limits
Pro and Enterprise sit at 100 requests per 10 seconds and 250,000 requests per day, with separate limits on Search API (4 requests per second) and the v1 endpoints. The Search API is the most common bottleneck because it’s the easiest to over-call.
Use batch endpoints, always
GET /crm/v3/objects/contacts/{id} -> single
POST /crm/v3/objects/contacts/batch/read -> up to 100 per call
A batch read of 100 contacts costs 1 request, not 100. Refactor any loop that reads single records.
Cache picklist values and properties
Property metadata barely changes. Calling /crm/v3/properties/contacts on every record sync wastes 50% of your budget. Cache for 24 hours minimum.
Implement exponential backoff with jitter
async function fetchWithBackoff(url, opts, retries = 5) {
for (let i = 0; i < retries; i++) {
const res = await fetch(url, opts);
if (res.status !== 429) return res;
const wait = (2 ** i) * 1000 + Math.random() * 1000;
await new Promise(r => setTimeout(r, wait));
}
throw new Error("rate limit exceeded after retries");
}
The jitter prevents thundering herd when multiple workers retry simultaneously.
Watch the X-HubSpot-RateLimit headers
X-HubSpot-RateLimit-Daily-Remaining: 184231
X-HubSpot-RateLimit-Secondly-Remaining: 8
Pipe these into your monitoring. Alert at 80% daily consumption by 6pm so you have time to throttle before hitting zero.
Serialize, don’t parallelize, write operations
Five workers each calling POST /contacts in parallel will burn your secondly limit in milliseconds. Use a queue (SQS, Cloud Tasks, or even a simple Redis list) and have one worker drain it at a controlled rate.
Avoid Search API for high-frequency lookups
Search is rate-limited separately and aggressively. Replace POST /crm/v3/objects/contacts/search with a webhook subscription where possible. Push beats pull.
Know what counts against your limit
Workflow custom code actions calling external APIs don’t count. Workflow actions calling HubSpot’s own API do. Operations Hub data sync doesn’t count. Webhooks delivered to you don’t count, but your acknowledgment does if you call back into HubSpot.
What to do this week
Pull yesterday’s API consumption from Settings -> Integrations -> API Calls. Identify your top three caller integrations. If any single integration consumes more than 30% of daily budget, refactor to batch or webhook before the next campaign cycle.