SurSolver
Docs menu

Docs / Guides

Errors

Every error code the SurSolver API can return, what each one means, which side caused it, and the exact step to take to recover from it.

The envelope

Solver calls (/createTask, /getTaskResult, /getBalance) answer HTTP 200 for success and for every error the API reports itself. Those failures are signalled in the body:

snippet.json
{
  "errorId": 1,
  "errorCode": "ERROR_INVALID_REQUEST",
  "errorDescription": "websiteKey is required."
}

Rules that follow from this:

  • Branch on errorId, not on the HTTP status.
  • errorDescription is written for a developer: it names the field or the reason. When the platform knows how long to wait, the description ends with (retry in Ns).
  • Error messages never echo client-supplied values and never reveal whether another account’s key or task exists.

Replies that are not in the envelope

HTTP 200 with errorId is not universal. An unexpected server error answers HTTP 500 with {"success": false, "error": {"code": "internal_error", …}} and no errorId. A wrong method or path answers 404 in the same shape, a CORS preflight from an unknown origin answers 405 with no body, and a request body larger than 1 MiB (the default limit) is refused before the API reads it, possibly by closing the connection. Treat any non-200 status, a connection error, or a body without errorId as a transport failure, not as an answer about your task.

Code catalogue

errorCodeMeaning
ERROR_KEY_DOES_NOT_EXISTThe clientKey does not match an active API key: wrong value, revoked, suspended or expired.
ERROR_WRONG_CLIENT_KEYclientKey is missing, empty or not a string.
ERROR_ZERO_BALANCEThe account’s balance cannot cover the price of this task — top up and retry.
ERROR_NO_SLOT_AVAILABLERate limit, concurrency limit or queue admission refused the task, no solver is available for it right now, or a short maintenance pause is in progress — retry shortly.
ERROR_TYPE_NOT_SUPPORTEDUnknown task.type, a type that is not available, or a missing task object.
ERROR_TASK_NOT_FOUNDUnknown taskId, or one that belongs to another account (the two look identical).
ERROR_TASK_EXPIREDThe task result is past the retention window and is gone.
ERROR_TASK_TIMEOUTThe task exceeded its execution time limit; its original payment or plan solve is returned once.
ERROR_FAILEDThe solve failed or was cancelled — errorDescription carries the reason.
ERROR_INVALID_REQUESTMalformed JSON body or task fields — errorDescription says which.
ERROR_INTERNAL_ERRORA server fault the API reported inside the envelope.

That is the complete list of errorCode values; no vendor-specific code such as ERROR_CAPTCHA_UNSOLVABLE is returned.

What to do

  • ERROR_WRONG_CLIENT_KEY, ERROR_KEY_DOES_NOT_EXIST — fix the credential and resend. Nothing was created or charged. See Authentication.
  • ERROR_INVALID_REQUEST, ERROR_TYPE_NOT_SUPPORTED — the request never became a task and was not charged. Correct the named field or the task type and resend.
  • ERROR_ZERO_BALANCE — no task was created. Top up in the dashboard, or check whether a package covers the service, then submit again.
  • ERROR_NO_SLOT_AVAILABLE — no task was created. Back off, honour the (retry in Ns) hint and retry with jitter; see Rate limits.
  • ERROR_FAILED — the task existed and was charged. The failure is final: submit a new task to try again. errorDescription says why the solve failed.
  • ERROR_TASK_TIMEOUT — the task is final and its original payment or plan solve is returned once. Submit a new task if you still need the result; see Task lifecycle.
  • ERROR_TASK_EXPIRED, ERROR_TASK_NOT_FOUND — there is no result to fetch. Store solutions as soon as status is ready.
  • ERROR_INTERNAL_ERROR, HTTP 500, or a connection failure — a server fault, not your request. createTask has no idempotency key, so a retried submission is a new, separately charged task: if you cannot tell whether the first one was accepted, wait briefly and check your balance with /getBalance before resubmitting. Contact support if it repeats.

Debugging checklist

  1. Is the key active and pasted without whitespace or quotes?
  2. Does task.type exist in the public catalog, GET /v1/task-types?
  3. Are all required parameters present, with the exact names the type uses?
  4. For proxy types: is the proxy well formed, and does it match the target’s IP expectations? See Proxies.
  5. Still stuck? Reproduce with the smallest request (one task, one poll) and include the taskId and the exact response when you contact support.