Rate limits

Daily budgets, per-minute burst caps, and how team workspaces share a single pool.

Rate limits protect the platform from runaway workloads and prevent one noisy neighbor from degrading everyone else. They come in two shapes: a daily budget (total requests per day) and a burst cap (requests per minute).

Plan limits

PlanDailyBurstBatch size
Free500 / day20 / min10 indicators
Starter5,000 / day60 / min10 indicators
Pro25,000 / day120 / min50 indicators
Team100,000 / day300 / min100 indicators
EnterpriseUnlimited1,000 / min100 indicators

A request is one call to /lookup, regardless of how many indicators you pack into the batch. Sending 100 indicators in one request counts as 1, not 100.

Response headers

Every /lookup response includes rate-limit headers so your client can shape traffic without extra round trips:

X-RateLimit-Limit-Daily: 25000
X-RateLimit-Remaining-Daily: 24,987
X-RateLimit-Limit-Burst: 120
X-RateLimit-Remaining-Burst: 118
  • Limit-Daily / Remaining-Daily: your plan's daily budget and how much is left. Resets at midnight UTC.
  • Limit-Burst / Remaining-Burst: per-minute burst cap and the remaining slots in the current minute window.

On Enterprise (unlimited daily), X-RateLimit-Limit-Daily and X-RateLimit-Remaining-Daily are omitted.

When you hit a limit

The API returns 429 Too Many Requests with a body like:

{
  "error": "Rate limit exceeded",
  "message": "Daily team limit exceeded (25001/25000 requests). Resets at midnight UTC.",
  "limit_type": "daily",
  "limit": 25000,
  "reset_time": "2026-05-01T23:59:59Z"
}

The response also sets:

Retry-After: 60
X-RateLimit-Reset: 2026-05-01T23:59:59Z

Handling 429

Respect Retry-After. If you're doing bulk enrichment from a SIEM, chunk your workload so you stay under the burst cap — a simple semaphore with plan-appropriate concurrency is usually enough.

Team workspaces share one pool

If you're on Team (or Enterprise) and have invited analysts to your workspace:

  • The daily limit is a shared pool — usage from the owner + all members sums against the same 100k/day budget
  • The burst cap is also shared — all members combined can't exceed 300 requests/minute on Team
  • Usage is still tracked per member on the dashboard — you see who did what, but the budget is collective

Rationale: a team of 5 analysts investigating a live incident shouldn't be artificially limited to 20% of the plan each — they should all burn rubber when needed. Fair-share / per-seat caps are not in the current model.

See Teams for the full team model.

Subscription downgrades

When Paddle reports a subscription as past_due, paused, or canceled, we temporarily downgrade the customer to Free-tier rate limits (500/day, 20/min, 10 per batch) until the status resolves. This protects us from abuse of expired plans without locking out the customer completely — a legitimate customer whose card just failed can still run low-volume lookups while they update their payment method.

The downgrade applies to viewer keys inheriting the owner's plan as well: if your Team workspace goes past-due, viewers drop to Free quotas too.

Fail-closed policy

If our rate-limiter backing store (Redis) is unreachable, the API returns 503 Service Unavailable rather than allowing unchecked traffic. This is a deliberate safety measure — an attacker could otherwise exploit a Redis outage to bypass limits entirely. Your retry logic should treat 503 the same as 429: back off and try again.