Skip to content

Rate limits

Two independent limits protect the platform and keep delivery latency predictable.

These limit how fast a single caller can send requests. They apply to the caller’s IP prefix (or API key prefix for /v1/*), reset on a rolling window, and protect the service from floods. They are not tied to your plan.

Operation Limit Window
Ingest events (/in/*) 1,000 requests 60 seconds
Read and write API (/v1/*) 600 requests 60 seconds
Manual retries (/v1/deliveries/*/retry) 60 requests 60 seconds

Every API response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When a per-IP limit is exceeded, the API returns 429 with a Retry-After header.

The quota is shared by every endpoint in a workspace and counts inbound POST /in/:publicId requests that are accepted and stored.

Plan Requests Resets
Free 1,000 Never (lifetime grant)
Pro 10,000 per prepaid block Never; buy more blocks to top up

What counts:

Outcome Billed
Accepted and stored 1 request
Filtered by a source filter or destination rule 0
Duplicate delivery (same source delivery ID) 0
Invalid signature 0
Rejected by a rate limit or the quota itself 0
Delivery retries after acceptance 0
Each destination after the first three +0.25
Each 64 KiB of payload after the first 64 KiB +1

/t/* (anonymous try playground) and /inspect/* use the per-IP limits only and never consume workspace quota.

Inbound requests return 429 and are not stored:

{
"error": "quota_exceeded",
"plan": "free",
"upgrade_url": "https://hooks.events/dashboard/billing",
"message": "Free plan request limit reached. Upgrade to Pro to keep receiving events."
}

The response carries X-Quota-Limit and X-Quota-Remaining. Neither the Free grant nor prepaid blocks reset, so the response has no Retry-After: buy more blocks to lift the limit immediately.

Current usage is available from GET /v1/billing/usage; the console reads the same values on the billing page.

Respect Retry-After instead of retrying immediately. Sources that retry on 429 keep events flowing once the window resets; events rejected with 429 are not stored.