Errors
Error codes and retry guidance
Errors are never charged. Credits are deducted for searches that return results, and for searches whose query genuinely has no results (confirmed by multiple search engines). An empty response we could not confirm as genuinely empty is never charged — see When are empty results charged?. Your own repeats of the same request within about 5 minutes are free.
HTTP Status Codes
| Status | Meaning | Retryable |
|---|---|---|
| 400 | Bad request | No |
| 401 | Invalid or missing API key | No |
| 402 | Insufficient credits | No |
| 429 | Rate limit exceeded | Yes |
| 503 | Temporary capacity limit | Yes |
400 Bad Request
Returned when the request is malformed or missing required parameters.
Common causes:
- Missing
qparameter on the Search endpoint - Submitting more than 10 URLs to the Extract endpoint
- Query exceeds 500 characters
{
"error": "Query parameter (q or query) is required"
}401 Unauthorized
Returned when the API key is missing, invalid, or inactive.
{
"error": "Invalid or inactive API key"
}Check that you are sending Authorization: Bearer sk_... and that the key is active in your dashboard.
402 Insufficient Credits
Returned when your account does not have enough credits to cover the request cost.
{
"error": "Insufficient credits",
"remainingCredits": 0
}The remainingCredits field shows your current balance. Top up credits from the billing page.
429 Rate Limited
Returned when you exceed your plan's request-per-second limit.
{
"error": "Rate limit exceeded",
"limit": 50,
"retryAfterMs": 800
}Response headers include:
X-RateLimit-Limit— your plan's per-second ceilingX-RateLimit-Remaining— requests remaining in the current windowRetry-After— seconds to wait before retrying
Retry guidance: Wait for retryAfterMs milliseconds, then retry the request. Use exponential backoff if you are consistently hitting the limit.
| Plan tier | Rate limit |
|---|---|
| Starter (under $50 spent) | 10 req/sec |
| Standard ($50–$499) | 50 req/sec |
| Scale ($500–$1,999) | 100 req/sec |
| Enterprise ($2,000+) | 200 req/sec |
503 Service Unavailable
Returned when the request cannot be fulfilled due to a temporary capacity condition.
{
"error": "Service temporarily unavailable",
"retryable": true
}Retry guidance: Wait at least 1 second, then retry. Use exponential backoff with a maximum of 3 retries. If the issue persists beyond a few minutes, check the status page.
Error Handling Example
import { SerpexClient, SerpApiException } from "serpex";
const client = new SerpexClient("sk_your_api_key");
try {
const results = await client.search({ q: "test query" });
} catch (error) {
if (error instanceof SerpApiException) {
switch (error.statusCode) {
case 429:
console.log(`Rate limited. Retry after ${error.details?.retryAfterMs}ms`);
break;
case 402:
console.log(`Out of credits. Balance: ${error.details?.remainingCredits}`);
break;
default:
console.log(`API error ${error.statusCode}: ${error.message}`);
}
}
}from serpex import SerpexClient, SerpApiException
client = SerpexClient("sk_your_api_key")
try:
results = client.search({"q": "test query"})
except SerpApiException as e:
if e.status_code == 429:
print(f"Rate limited. Retry after {e.details.get('retryAfterMs')}ms")
elif e.status_code == 402:
print(f"Out of credits. Balance: {e.details.get('remainingCredits')}")
else:
print(f"API error {e.status_code}: {e}")