Error Codes
All responses include a top-level <code>code</code> field. HTTP status codes indicate transport-level errors; API-level codes in the JSON body indicate application errors.
Response Envelope
Success — code: 0 HTTP 200
{
"code": 0,
"data": {},
"msg": "success"
} API Error — code: -1001 HTTP 200
{
"code": -1001,
"data": null,
"msg": "timeout: request exceeded the maximum allowed duration"
} Auth Error HTTP 401
{
"code": 401,
"data": null,
"msg": "Unauthorized: missing or invalid Authorization header"
} Note: API-level errors (e.g. timeout, fetch failure) return HTTP 200 with a non-zero code in the body. Always check response.data.code === 0 before processing data.
Recommended Error Handling
import requests, time
def search(query, retries=3, backoff=2):
for attempt in range(retries):
try:
r = requests.post(
"https://www.searchcans.com/api/v1/search",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"t": "google", "s": query, "d": 20000},
timeout=30,
)
r.raise_for_status()
body = r.json()
code = body.get("code")
if code == 0:
return body["data"]
elif code == 9999:
return [] # no results
elif code == 1001:
print(f"Timeout (1001) on attempt {attempt+1}, retrying…")
elif code == 1010:
print(f"Lane limit (1010) on attempt {attempt+1}, backing off…")
time.sleep(0.3 * (attempt + 1))
elif code in (1002, 1003, 1004, 1005, 1006, 1009):
print(f"Frequency/load limit ({code}), backing off…")
else:
raise RuntimeError(f"API error {code}: {body.get('msg')}")
except requests.HTTPError as e:
if e.response.status_code == 429:
time.sleep(backoff ** attempt)
elif e.response.status_code in (401, 402, 403):
raise # non-retryable
time.sleep(backoff ** attempt)
raise RuntimeError("Max retries exceeded") 1010 vs 429: Code 1010 is returned inside a HTTP 200 body (lane busy). HTTP 429 is a transport-level rejection. Both are retryable — add a short back-off of 100–500 ms.
HTTP Status Codes
Transport-level errors returned when a request cannot be processed at all.
| Code | Name | Cause | Recommended Fix |
|---|---|---|---|
| 400 | Bad Request | One or more required parameters are missing or have an invalid value. | Check that t, s / q, and all required fields are present and correctly typed. |
| 401 | Unauthorized | The Authorization header is missing, malformed, or the API key is invalid. | Ensure your request includes Authorization: Bearer YOUR_API_KEY with a valid key from your dashboard. |
| 402 | Payment Required | Your account has insufficient credits to complete this request. | Purchase additional credits at /pricing/. Credits are only deducted for successful (HTTP 200) responses. |
| 403 | Forbidden | The API key exists but does not have permission to access this resource. | Verify the API key belongs to an active account. Contact support if you believe this is an error. |
| 429 | Too Many Requests | All your Parallel Lanes are currently occupied. New requests cannot start until a lane frees up. | Implement a retry with exponential backoff, or upgrade your plan for more Parallel Lanes. |
| 500 | Internal Server Error | An unexpected error occurred on the SearchCans backend. | Retry the request. If the issue persists, check our status page or contact support. |
| 503 | Service Unavailable | The service is temporarily down for maintenance or experiencing high load. | Wait a few seconds and retry with backoff. |
API-Level Codes (code field)
Application errors returned inside the JSON body with HTTP 200. Always check code === 0 before reading data.
| Code | Name | Meaning | Recommended Fix |
|---|---|---|---|
| 0 | Success | Request completed successfully. data contains the response payload. | — |
| 1010 | Lane Limit Exceeded | All your Parallel Lanes are occupied. This is the most common rate-limit code — it is not fatal. | Pause 100–500 ms and retry. Use a Semaphore equal to your lane count to prevent 1010 entirely. See Rate Limits. |
| 1001 | Response Timeout | The search or fetch did not complete within the allowed window set by parameter d. | Increase d (e.g. 20000–30000 ms). Implement retry with exponential back-off. |
| 1002 | System Busy | The SearchCans backend is under high load. | Wait 1–2 s and retry. Use exponential back-off on repeated failures. |
| 1003 | IP Frequency Limit | Requests from your IP address are arriving too fast. | Slow down your request rate or distribute across multiple IPs. |
| 1004 | API Frequency Limit | Global API-level rate protection triggered by burst traffic. | Reduce concurrency or add delays between bursts. Retry after a short back-off. |
| 1005 | IP Endpoint Limit | Your IP has hit the per-endpoint rate cap for this specific API path. | Reduce request rate to this endpoint, or distribute requests across IPs. |
| 1006 | User Frequency Limit | Your API key is sending requests faster than the per-user burst allowance. | Add a small delay (50–200 ms) between requests, or cap concurrency to your lane count. |
| 1009 | Endpoint Lane Limit | Too many concurrent requests to this specific endpoint from your account. | Reduce parallelism for this endpoint. Route calls across multiple endpoints if applicable. |
| 9999 | No Results Found | The search engine returned no results for this query. Treated as a soft success — data is empty rather than null. | Try different keywords, remove overly restrictive site: or intitle: operators, or broaden the query. |
| 443 | Connection Error | SSL / TLS handshake failed between the backend and the target server. | Verify the target URL uses a valid certificate. Retry once; if persistent, the target site may be unreachable. |
| 10054 | Connection Reset | The remote host forcibly closed the connection (TCP RST). | Retry the request. If the issue recurs on the same URL, the target site may be blocking automated access. |
Need help debugging?
Check our docs or reach out to our support team.