All three apply at once. The first window you exceed returns
429 Too Many Requests with a Retry-After header telling you how long to wait for that window to reset.
Response headers
These headers are present on both successful and429 responses, so you can track your remaining budget without waiting to get throttled:
X-RateLimit-Limit— the per-minute ceiling.X-RateLimit-Remaining— requests left in the current minute window (0on a per-minute429).X-RateLimit-Reset— Unix timestamp (seconds) when the minute window resets.X-RateLimit-Monthly-Remaining— requests left in your monthly quota.
429 response additionally carries Retry-After — seconds to wait before retrying. Use this value, don’t hardcode delays.
Weighted cost
Most endpoints cost 1 request against every window. The exception is launching a sequence (POST /sequences/{id}/launch): it charges your monthly quota proportionally to the number of contacts enqueued. Enrolling 5,000 leads consumes roughly 5,000 monthly units — so bulk enrollment is not “free.” The per-second and per-minute windows still count a launch as a single request; only the monthly quota is charged the weighted cost. This weighting applies to all channels, including WhatsApp sequences — the cost is the number of enqueued contacts.
Sending a one-off WhatsApp message (POST /whatsapp/send) costs 1 monthly unit per message, like any ordinary request — it is not weighted.
Exemptions
Some organizations are not subject to these limits:- Organizations on the lifetime plan.
- Any organization an administrator has explicitly exempted.
Best practices
- Spread bulk operations. At 200 requests/minute you can sustainably push ~3 requests/second; aim to stay under the per-second burst of 3 to leave headroom.
- Watch the monthly quota. 50,000 requests/month is shared across the whole organization, and sequence launches draw down that quota by the number of contacts enrolled. Budget accordingly.
- Cache catalog lookups (
/lead-sources,/pipeline/stages,/webhooks/events) instead of hitting them on every request — they change rarely. - Batch reads with the
queryfilter instead of N individualGET /leads/{id}calls when you need to look up several leads.