Skip to main content

Rate Limits

Rate limits protect the CronDB API from abuse and ensure fair usage across all customers. Limits are applied per API key and reset every minute.

Rate Limits by Plan

PlanRequests per MinuteMonthly Quota
Free10100
Starter6010,000
Pro300100,000
Enterprise1,000999,999

Rate limits apply to all endpoints equally. Each API call counts as one request regardless of the endpoint.

Rate Limit Headers

Every API response includes rate limit information:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1710764400
HeaderDescription
X-RateLimit-LimitMaximum requests per minute for your plan
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets

Handling Rate Limits (429 Responses)

When you exceed the rate limit, the API returns a 429 Too Many Requests response:

{
"detail": "Rate limit exceeded. Try again in 32 seconds."
}

The response includes a Retry-After header:

Retry-After: 32

Implementing Backoff (Python)

import time
import requests

def call_api_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)

if response.status_code == 200:
return response.json()

if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
continue

response.raise_for_status()

raise Exception("Max retries exceeded")

Implementing Backoff (JavaScript)

async function callApiWithRetry(url, headers, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, { headers });

if (response.ok) {
return await response.json();
}

if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
continue;
}

throw new Error(`API error: ${response.status}`);
}

throw new Error("Max retries exceeded");
}

Rate Limits vs. Monthly Quota

Rate limits and monthly quotas are separate mechanisms:

MechanismWhat It ControlsReset Period
Rate limitRequests per minuteEvery 60 seconds
Monthly quotaTotal requests per billing cycleMonthly on billing date

You can be within your rate limit but exceed your monthly quota, or vice versa.

Optimizing API Usage

Use Bulk Endpoints

Instead of making 100 individual enrichment calls:

# Inefficient: 100 requests
for domain in domains:
GET /v1/enrichment/domain?domain={domain}

Use the bulk endpoint for a single request:

# Efficient: 1 request
POST /v1/enrichment/bulk
{"domains": ["domain1.com", "domain2.com", ...]}

Cache Results

CronDB data updates periodically, not in real time. Cache enrichment results for at least 24 hours to avoid redundant API calls.

Request Only What You Need

If you only need tech stack data, use the /v1/tech-stack endpoint instead of the full enrichment endpoint. Specialized endpoints return faster and use the same quota.

Burst Allowance

CronDB allows short bursts above your rate limit:

  • Up to 2x your per-minute limit for bursts lasting under 5 seconds
  • After the burst, normal rate limiting resumes

This accommodates applications that send parallel requests in short bursts.

Monitor Your Usage

Check the X-RateLimit-Remaining header in every response to proactively throttle your request rate before hitting the limit.

Next Steps