Launch pricing: 78% of pool capacity allocated. Rates rise as it fills. Lock in today's rate →
Skip to content

Errors

You are never charged for an error. Only 200 responses use credits — every status below costs nothing, so retrying is safe.

Format

{
  "error": {
    "status": 402,
    "code": "insufficient_credits",
    "message": "Your query balance is empty. Top up or choose a plan at https://serpwiz.com/dashboard/billing",
    "request_id": "9f2c1a7b3e4d5f60",
    "docs": "https://serpwiz.com/docs/errors"
  }
}

Match on code, not on message — messages may be reworded.

Codes

Status code What happened What to do
400 invalid_request A parameter is missing or invalid. The message names it. Fix the request. Don't retry unchanged.
401 unauthorized API key missing, malformed, invalid or revoked. Check the X-API-Key header.
402 insufficient_credits Free allowance and balance are both used up. Top up or upgrade.
403 email_unverified The account's email isn't verified yet. Click the link in your verification email.
403 account_suspended The account is suspended. Contact [email protected].
404 not_found Unknown endpoint. Check the path against the API reference.
405 method_not_allowed Not a GET. Use GET.
429 rate_limited Over your requests-per-second limit, or the service is busy. Wait Retry-After seconds, then retry.
500 internal_error Something broke on our side. Retry with backoff.
502 upstream_error The search couldn't be completed. Retry with backoff.
503 capacity Temporarily over capacity. Wait Retry-After seconds, then retry.
504 upstream_timeout The search took too long. Retry.

Retrying

Retry 429, 5xx and network errors with exponential backoff and jitter, honouring Retry-After when present. Don't retry 400–404.

import random, time, requests

def search(params, key, attempts=5):
    for i in range(attempts):
        r = requests.get("https://api.serpwiz.com/v1/google/search", params=params,
                         headers={"X-API-Key": key}, timeout=60)
        if r.status_code == 200:
            return r.json()
        if r.status_code in (429, 500, 502, 503, 504):
            wait = float(r.headers.get("Retry-After", 0)) or min(30, 2 ** i)
            time.sleep(wait + random.random())
            continue
        r.raise_for_status()
    raise RuntimeError("gave up after retries")

Quote the request_id when you contact support.

This page as Markdown: /docs/errors.md