Errors
Error bodies, codes and HTTP statuses of the RankShark Track and Enhance APIs and MCP servers, what each one means and when to retry.
Every error has an HTTP status and a short, stable code. Check the code, not the message: messages are for people and can change. Each code below has its own link, for example /docs/errors#quota.
Error bodies
Track: { code, message }
{
"code": "quota",
"message": "This scan needs 49 points; 12 of your 50000 monthly points are left and 0 bought points. Buy a points pack, or wait for your monthly points to renew on 1 December.",
"needed": 49,
"monthlyLeft": 12,
"monthlyLimit": 50000,
"boughtLeft": 0,
"renewsAt": "2026-12-01T00:00:00.000Z"
}Some codes add details: quota the numbers above, workspace_starting and hourly limits a retryAfter in seconds, insufficient_scope the required scope. An unexpected failure answers 500 with a short message and no details.
Enhance: problem details
Errors from the workspace are application/problem+json (RFC 9457). type links to the code on this page, and correlationId is what to quote when you contact support:
{
"type": "https://docs.rankshark.io/docs/errors#validation_error",
"title": "The request was invalid.",
"status": 400,
"code": "validation_error",
"detail": "Provide ids[] or set all=true.",
"correlationId": "0HN7Q2K9M4ABC"
}When the workspace cannot answer at all, the body is { code }, for example {"code": "workspace_starting"}.
Sign-in and rate limits: { error, error_description }
On both products, a missing or wrong credential and the per-minute limit follow OAuth, with a WWW-Authenticate header on 401 and 403:
{
"error": "invalid_token",
"error_description": "This is a RankShark Enhance key; RankShark Track needs its own key or connection."
}A missing scope on Track:
{
"error": "insufficient_scope",
"code": "insufficient_scope",
"required": "track:run",
"message": "This key or connection lacks the 'track:run' scope."
}Codes on both products
| Status | Code | What happened | What to do |
|---|---|---|---|
| 401 | invalid_token | The key or token is missing, wrong, expired, revoked, for the other product, or API access is off. | Check the key and the product. See Authentication. |
| 401 | unauthorized | No credential at all. | Send Authorization: Bearer …. |
| 403 | insufficient_scope | The key or connection lacks the scope this call needs. required names it. | Reconnect the app with that scope, or upgrade a read-only plan. |
| 403, 409 | workspace_inactive | The workspace is not active (for example, the plan ended). | Check your plan in the panel. |
| 404 | not_found | No such campaign, scan, business or report in this workspace. A malformed id is not found too. | Check the id. |
| 429, 409 | rate_limited | Too many requests a minute (429), or an hourly Track lookup limit is used up (409). | Wait for Retry-After (or retryAfter) seconds. See Rate limits. |
| 503 | workspace_starting | The workspace is still being set up, or is restarting. | Retry after Retry-After (or retryAfter) seconds. |
| 500 | internal | Something went wrong on our side. | Try again. If it keeps happening, contact support with the correlationId. |
Track codes
| Status | Code | What happened |
|---|---|---|
| 400 | invalid | A field is missing or wrong. message says which. |
| 400 | plan_limit | Your plan does not include this: an engine, AI visibility, schedules, or a grid this big. |
| 404 | not_ai | You asked for AI visibility of a scan that is not an AI scan. |
| 409 | quota | Not enough points left for this run. The body has the numbers and when points renew. |
| 409 | already_running | Every keyword you asked to run is being scanned already. |
| 409 | limit | Your plan's campaigns are all used. Delete one or upgrade. |
| 409 | prospect | This is a quick scan made in the panel: it runs once and cannot be edited or run again. Save it as a campaign in the panel first. |
| 409 | busy | A business search is already running. Wait for it. |
| 409 | find_failed | The Google Maps search did not work. Try again, or paste a Google Maps link. |
| 502 | mail_rejected | The mail server refused a report recipient. Check the address. |
| 502 | mail_failed | The report email could not be sent. Try again later. |
| 503 | timeout | Google Maps did not answer in time. Try again. |
| 503 | geocode_failed | The place search is not answering. Try again in a minute. |
| 503 | pdf_unavailable | PDF export is not available right now. |
Enhance codes
| Status | Code | What happened |
|---|---|---|
| 400 | validation_error | The request is not valid. detail says why. |
| 403 | product_locked | This workspace has RankShark Track only, without Enhance. |
| 502 | relay_error | Something went wrong while reaching your workspace. Try again. |
| 504 | workspace_timeout | The workspace took too long to answer. Try again. |
Run, stop and delete calls have a lower limit per key, answered with 429 rate_limited.
OAuth codes
The /oauth/* endpoints answer with the standard OAuth codes: invalid_request, invalid_client, invalid_grant (code or refresh token expired, used or revoked), invalid_scope, invalid_target (unknown resource), unsupported_grant_type and rate_limited.
MCP errors
Over MCP, a refusal comes back as a tool result with isError: true and the same code as the REST API:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [{ "type": "text", "text": "{\"needed\":49,\"monthlyLeft\":12,\"error\":\"quota\",\"message\":\"This scan needs 49 points; …\",\"status\":409}" }],
"isError": true
}
}Protocol problems use JSON-RPC errors: -32700 (not JSON), -32600 (not a JSON-RPC request), -32601 (unknown method) and -32602 (unknown tool, or arguments that do not fit the tool's schema).
Retrying
- Retry
429,502,503and504after a pause. UseRetry-Afterwhen it is there, otherwise wait a few seconds and back off. - Do not retry
400,401,403,404or409unchanged: fix the request or the plan first. - Run and start calls are not idempotent: if a
runcall timed out on your side, list the campaign's scans before running again.