Error Codes
This page documents all error responses returned by the SerpWatch API,
including HTTP status codes, error formats, and troubleshooting guidance.
Error Response Format
All error responses include a JSON body with details about the error.
The format varies slightly depending on the error type.
Standard Error
{
"detail": "Error message describing what went wrong"
}
Validation Error (422)
{
"detail": [
{
"loc": ["body", "keyword"],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": ["body", "depth"],
"msg": "ensure this value is less than or equal to 100",
"type": "value_error.number.not_le"
}
]
}
Rate Limit Error (429)
{
"code": "ThrottlingException",
"message": "Retry your request, preferably using backoff algorithm."
}
HTTP Status Codes
| Code | Name | Description |
|---|---|---|
200 |
OK | Request succeeded |
201 |
Created | Resource created successfully |
400 |
Bad Request | Invalid request format (e.g., malformed JSON) |
401 |
Unauthorized | Missing or invalid authentication |
403 |
Forbidden | Valid auth but insufficient permissions |
404 |
Not Found | Resource doesn’t exist |
422 |
Unprocessable Entity | Validation error in request body |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server error (contact support) |
503 |
Service Unavailable | Temporary outage (retry later) |
Common Errors
Authentication Errors
401 Unauthorized
Message: “Could not validate credentials”
Causes:
- Missing
Authorizationheader - Invalid API key
- Malformed Bearer token format
Solution:
# Correct format
curl -H "Authorization: Bearer YOUR_API_KEY" ...
# Common mistakes:
# - Missing "Bearer " prefix
# - Extra spaces in header
# - Using expired or revoked key
Validation Errors
422 Unprocessable Entity
Message: Field-specific validation errors
Common Validation Errors:
| Field | Error | Solution |
|---|---|---|
keyword |
field required | Include the keyword field in your request |
depth |
ensure this value is less than or equal to 100 | Use a depth value between 1 and 100 |
device |
value is not a valid enumeration member | Use “desktop” or “mobile” |
postback_url |
invalid or malformed url | Use a valid HTTPS URL |
Rate Limit Errors
429 Too Many Requests
Message: “Retry your request, preferably using backoff algorithm.”
Causes:
- Too many requests per second
- Exceeded daily/monthly quota
- DynamoDB throttling (internal)
Solution: Implement exponential backoff:
import time
import random
def request_with_backoff(func, max_retries=5):
"""Execute request with exponential backoff on 429 errors."""
for attempt in range(max_retries):
response = func()
if response.status_code != 429:
return response
# Exponential backoff with jitter
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limited. Retrying in {wait_time:.1f}s...")
time.sleep(wait_time)
raise Exception("Max retries exceeded")
Not Found Errors
404 Not Found
Message: “Task not found” or “Not Found”
Causes:
- Task ID doesn’t exist
- Task ID belongs to different user
- Task has been deleted or expired
Solution:
- Verify the task ID is correct
- Check that you’re using the right API key
- Ensure the task was created successfully
Task-Level Errors
Even when the API request succeeds (200), the task itself may fail during processing.
Check the task’s status field:
{
"id": "task_abc123",
"status": "error",
"keyword": "search query",
"error_message": "Failed to fetch search results after 6 attempts"
}
Common Task Errors
| Error Message | Cause | Solution |
|---|---|---|
| Failed to fetch search results | Crawling failed after max retries | Retry the task; may be temporary |
| Invalid search engine configuration | Invalid se_id parameter |
Use a valid search engine ID or omit |
| Location not supported | Invalid location_name |
Check location spelling |
| Insufficient credits | Account has no remaining credits | Add credits to your account |
Error Handling Best Practices
import requests
from requests.exceptions import RequestException
def make_api_request(endpoint, method="GET", **kwargs):
"""Make API request with comprehensive error handling."""
try:
response = requests.request(
method,
f"https://engine.v2.serpwatch.io{endpoint}",
headers={"Authorization": f"Bearer {API_KEY}"},
**kwargs
)
# Check for HTTP errors
if response.status_code == 401:
raise AuthenticationError("Invalid API key")
elif response.status_code == 422:
errors = response.json().get("detail", [])
raise ValidationError(f"Validation failed: {errors}")
elif response.status_code == 429:
raise RateLimitError("Rate limit exceeded")
elif response.status_code >= 500:
raise ServerError("Server error, please retry")
response.raise_for_status()
return response.json()
except RequestException as e:
raise NetworkError(f"Network error: {e}")
# Usage with specific error handling
try:
result = make_api_request("/api/v2/serp/crawl", method="POST", json=data)
except AuthenticationError:
print("Check your API key")
except ValidationError as e:
print(f"Fix request: {e}")
except RateLimitError:
print("Slow down requests")
except (ServerError, NetworkError):
print("Retry later")
async function makeApiRequest(endpoint, options = {}) {
try {
const response = await fetch(
`https://engine.v2.serpwatch.io${endpoint}`,
{
...options,
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
...options.headers
}
}
);
// Handle specific status codes
if (response.status === 401) {
throw new Error("Authentication failed: Invalid API key");
}
if (response.status === 422) {
const data = await response.json();
throw new Error(`Validation error: ${JSON.stringify(data.detail)}`);
}
if (response.status === 429) {
throw new Error("Rate limit exceeded");
}
if (response.status >= 500) {
throw new Error("Server error, please retry");
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
if (error.name === "TypeError") {
throw new Error("Network error: Unable to connect");
}
throw error;
}
}
// Usage
try {
const result = await makeApiRequest("/api/v2/serp/crawl", {
method: "POST",
body: JSON.stringify(data)
});
} catch (error) {
console.error("API Error:", error.message);
}
Getting Help
If you encounter errors not covered here:
- Check the Swagger UI for interactive testing
- Review the OpenAPI spec for exact schema requirements
- Contact support with your request details and error response