Rate Limits
HyperSearchX enforces two types of rate limits: a monthly request quota per plan, and a per-minute limit to prevent burst abuse. Both limits are tracked per API key.
Plan quotas
| Plan | Requests / month | Requests / minute | Price |
|---|---|---|---|
| Free | 1,000 | 60 | $0 |
| Starter | 10,000 | 200 | $19 / mo |
| Pro | 100,000 | 500 | $79 / mo |
| Enterprise | Unlimited | 2,000 | Custom |
Rate limit headers
Every API response includes headers showing your current rate limit status:
HTTP/2 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 2025-07-01T00:00:00Z
X-Request-Id: req_01j8xk3m7p4qr5st6uv7wx8yz| Header | Description |
|---|---|
X-RateLimit-Limit | Monthly quota for your plan |
X-RateLimit-Remaining | Requests remaining this month |
X-RateLimit-Reset | ISO 8601 timestamp when quota resets |
X-Request-Id | Unique request ID for support/debugging |
Rate limit exceeded response
When you exceed the per-minute limit, you receive a 429 Too Many Requests response:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. You have exceeded the 60 requests/minute limit.",
"retry_after": 60,
"request_id": "req_01j8xk3..."
}
}HTTP/2 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 1000
X-RateLimit-Reset: 2025-07-01T00:00:00ZWhen the monthly quota is exhausted, you receive a 429 with code quota_exceeded:
{
"error": {
"code": "quota_exceeded",
"message": "Monthly quota exhausted. Resets 2025-07-01T00:00:00Z or upgrade your plan.",
"request_id": "req_01j8xk3..."
}
}Handling rate limits in code
async function searchWithRetry(query: string, maxRetries = 3): Promise<any> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch("https://api.hypersearchx.zuhabul.com/v1/search", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.HSX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, tier: "summary" }),
});
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60", 10);
if (attempt < maxRetries) {
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
}
if (!res.ok) throw new Error(`API error: ${res.status}`);
return res.json();
}
throw new Error("Max retries exceeded");
}import time, requests, os
HSX_BASE = "https://api.hypersearchx.zuhabul.com"
HEADERS = {"Authorization": f"Bearer {os.environ['HSX_API_KEY']}"}
def search_with_retry(query: str, max_retries: int = 3) -> dict:
for attempt in range(max_retries + 1):
r = requests.post(f"{HSX_BASE}/v1/search",
headers=HEADERS,
json={"query": query, "tier": "summary"})
if r.status_code == 429:
retry_after = int(r.headers.get("Retry-After", 60))
if attempt < max_retries:
time.sleep(retry_after)
continue
r.raise_for_status()
return r.json()
raise RuntimeError("Max retries exceeded")IP-level rate limiting
In addition to per-key limits, the API gateway enforces IP-level rate limiting of 100 requests/second average with a burst of 200. This protects against DDoS and is independent of your API key quota.
Monitoring usage
Check your current usage via the /v1/usage endpoint:
curl https://api.hypersearchx.zuhabul.com/v1/usage \
-H "Authorization: Bearer hsx_your_key"{
"plan": "free",
"quota": 1000,
"used": 153,
"remaining": 847,
"reset_at": "2025-07-01T00:00:00Z",
"per_minute_limit": 60,
"endpoints": {
"search": 120,
"research": 28,
"scrape": 5
}
}You can also view real-time usage in the dashboard.
Upgrade your plan
Upgrade anytime from the dashboard → Billing. Quota increases take effect immediately.