Rate limits
SerpKite limits requests per second per API key. Free keys get 5 per second; buying a pack raises every key to that pack's rate. Over the limit you get a 429 with Retry-After.
Limits per plan
Rate limits are requests per second, per API key. They protect the upstream and keep latency predictable; they are not a quota. Your total volume is bounded only by your credit balance and any spend controls you set.
| Plan | Requests per second, per key |
|---|---|
| Free | 5 |
| Starter | 20 |
| Growth | 50 |
| Pro | 100 |
| Enterprise | Custom |
Your rate is set by the largest pack you have ever bought, not by your current balance. Buy a Pro pack once and every key on the account stays at 100 requests per second, even after the credits are spent and you top up with Starter packs. GET /v1/account returns the current value as rate_limit_rps.
Because the limit is per key, two services with separate keys don’t compete for the same budget. Keys on a team account all get the owner’s rate.
What counts as a request
- Every call to a search endpoint counts as one request.
- A
POST /v1/batchescall counts once, however many requests it holds, so every plan can submit the full 100 per call. The jobs then run on the batch lane at their own pace, so batch is the way to push large volumes without managing concurrency yourself. What bounds a batch is the queue: a single account can have up to 10,000 jobs queued at once. GET /v1/accountandGET /v1/batches/{id}are free but still authenticated calls. Poll batch jobs every few seconds, not in a tight loop, or use a webhook instead.- MCP tool calls count like the equivalent REST call.
When you hit the limit
Over the limit, the API answers 429 Too Many Requests with the rate_limited code and a Retry-After header (seconds). Nothing is billed.
HTTP/2 429
content-type: application/json
retry-after: 1
x-request-id: req_01J8ZKA1B2C3D
{"error":{"code":"rate_limited","message":"rate limit exceeded","request_id":"req_01J8ZKA1B2C3D"}}
Retry-After is exposed through CORS, so browser code can read it too.
Two other 429 codes are not about request rate, and retrying soon won’t help:
daily_limit_reached: a free account hit its daily cap. Buying any pack removes it.rate_limitedwith a message about queued batch jobs: you have too many batch jobs waiting. Let some finish first.
Retrying well
The official SDKs already do this: they honour Retry-After and retry 429 and 5xx with exponential backoff (configurable with maxRetries, max_retries or serpkite.WithMaxRetries). With your own HTTP client, wait for Retry-After, then retry with exponential backoff and jitter. The same approach works for 503 (upstream errors, blocks and timeouts), which is also free and safe to retry.
import os
import random
import time
import requests
API = "https://api.serpkite.com"
HEADERS = {"Authorization": f"Bearer {os.environ['SERPKITE_API_KEY']}"}
RETRY = {429, 500, 502, 503, 504}
def search(body: dict, attempts: int = 5) -> dict:
for i in range(attempts):
res = requests.post(f"{API}/v1/search", json=body, headers=HEADERS, timeout=30)
if res.status_code not in RETRY:
res.raise_for_status()
return res.json()
code = res.json()["error"]["code"]
if code == "daily_limit_reached":
raise RuntimeError("free-tier daily limit reached")
wait = float(res.headers.get("Retry-After", 0)) or min(2**i, 30)
time.sleep(wait + random.random() / 2)
res.raise_for_status()
return res.json()Staying under the limit
- Cap concurrency in your client. At a typical latency of about a second, a limit of N requests per second means roughly N requests in flight at once.
- Use the batch lane for anything that doesn’t need an answer right now.
POST /v1/batchestakes up to 100 requests per call, costs half price, and you don’t have to pace it. - Use the cache for repeated queries. A
max_agehit is half price and returns faster. See Caching. - Split workloads across keys. Each key has its own per-second budget.
Need more than 100 requests per second? Talk to us about Enterprise.
Playground limits
The no-login demo on the playground doesn’t use a key, so it is limited per IP address instead: at most 5 searches per minute and 20 per day. Past either limit it answers 429 rate_limited. Playground searches are never billed and don’t count against your key’s limit. For anything beyond a quick look, create a free key.
Related
Last updated: 2026-09-29