Errors & billing
Every JustSERP API status code and failure reason, which responses to retry, how to cancel a request, and which responses are charged.
Responses at a glance
| Status | Meaning | Retry? | Charged? |
|---|---|---|---|
200 | The answer, as the document. | No. | Yes. |
200, parsed: false | The page was fetched and not understood. An envelope: data is {"html": "..."} and parse_error says why. | Yes. | Yes. |
400 | The request cannot be run: a parameter is missing or refused. error says what. | No. Fix the request. | No. |
401 | No API key was sent: {"error": "API key required"}. | No. | No. |
403 | The key is not valid, or its call quota is used up (API call quota exceeded). | No, until you top up. | No. |
404 | reason: profile_not_found: the profile or place does not exist, confirmed twice. | No. It is the answer. | Yes. |
422 | /v1/web/page only: the page redirected more than five times (reason: too_many_redirects). | No. | No. |
429 | Too many requests in progress on this key at once (Concurrent request limit exceeded). | Yes, when one of yours finishes. | No. |
499 | Cancelled with GET /v1/cancel (reason: cancelled). | Only if you want the job again. | No. |
500 | Every attempt failed (reason says how), no answer within about 95 seconds (reason: job_timeout), or an error in the service itself (message, no reason). | Yes. | No. |
503 | No capacity was free (reason: no_capacity), the service could not take the job (message), or your key could not be checked right now (error, with Retry-After). | Yes, after a pause. | No. |
The API never answers 502 or 504. A request that runs out of time is a 500 with reason: job_timeout.
Failure bodies
Failures share one shape:
{
"success": false,
"engine": "google_maps",
"reason": "captcha",
"total_attempts": 5
}An error in the service itself has a message such as Search failed due to server error and no reason. A 400 adds error with the reason in words.
reason values
reason | Meaning | Status |
|---|---|---|
captcha | The site challenged the request (Google's /sorry, Cloudflare, DataDome). | 500 |
timeout | The page did not become ready in time, or a reply stalled. | 500 |
blocked | The site would not show the page. | 500 |
interstitial | A page stood in for the answer (a consent wall, an error page). | 500 |
unavailable | Not the surface asked for (a sign-up card, a prompt the site would not send). | 500 |
rate_limited | The site says this visitor has asked enough. | 500 |
profile_not_found | With 404, confirmed: the answer. With 500, seen once and not confirmed. | 404 or 500 |
job_timeout | No answer within about 95 seconds. | 500 |
no_capacity | No capacity was free. | 503 |
cancelled | Stopped by GET /v1/cancel. | 499 |
bad_request | The request cannot be run; error says why. | 400 |
too_many_redirects | /v1/web/page only: more than five redirects. | 422 |
error, unknown | Anything else. | 500 |
place_page is no longer sent: a Google Maps search that matches exactly one place now answers that place.
Place details errors
Maps place failures also carry error: {code, message} beside reason. code is one of place_not_found, error, captcha, consent_wall, blocked, timeout or no_capacity. A 404 with error.code: place_not_found is the only answer that means the place is gone.
{
"success": false,
"engine": "google_maps_place",
"reason": "profile_not_found",
"error": { "code": "place_not_found", "message": "Google has no place with this id" },
"total_attempts": 2
}Retry guidance
- Retry
500,503and200withparsed: false. Back off between tries; each retry is a full job. - On
503, retry after a pause, or afterRetry-Afterseconds when it is sent. - On
429, retry when one of your requests finishes, or after a second or two. See Rate limits. - Do not retry
400,401,403,404or422. - A
500profile_not_foundwas seen once and not confirmed, so one retry is reasonable. - Google AI Overview: an empty Overview is an answer, not a failure.
- Set your client timeout to about 100 seconds so a late answer is not cut off.
Cancelling
Send a cancel_token of your own with a request. Later, GET /v1/cancel?cancel_token=<token> with the same token stops the job before its next attempt (never mid-page) and the original request answers 499. Tokens are private to your API key. Use a new token for every request, retries included: a cancelled token stays cancelled for a few minutes.
curl -G "https://api.justserp.com/v1/cancel" \
-H "X-API-Key: YOUR_API_KEY" \
--data-urlencode "cancel_token=7f3c2a9e-4b1d-4e8a-9c6f-2d5b8a1e0f43"| Status | Body | Meaning |
|---|---|---|
202 | {"cancelled": true} | Recorded. Answered whether the job had started, finished or never existed. |
400 | {"error": "cancel_token is required"} | No cancel_token, or one longer than 128 characters. |
401 | {"error": "API key required"} | No key was sent. |
503 | {"cancelled": false, "error": "cancel store unavailable"} | The cancel could not be recorded. Try again. |
Billing
A 200 costs a call, and so does a 404: the profile or place you asked for does not exist, which takes the same work to find out. Every other answer is free, including 400, 422, 499, 500 and 503, and refusals (401, 403 and 429) are never counted. Retrying a failed request never pays twice for the same failure.
Calls are counted from your key's balance as they are served. Every 200 carries X-RateLimit-Remaining, the calls left after that request; it can trail your dashboard by a few minutes. /v1/google/locations is free.
If your client hangs up before the answer, the job is stopped and the call is still charged, because the work was done. Set a client timeout of about 100 seconds rather than a shorter one, and use cancelling when you no longer want an answer.
Parameters
The query parameters for every JustSERP endpoint, and how to encode them: shared fields, Google search inputs, AI question and location, reviews profiles and place ids.
Rate limits & concurrency
How many requests a JustSERP API key can run at once, plan quotas, what a 503 no_capacity answer means and how to retry it.