Account & Status
Endpoints that aren't tied to a specific captcha — task polling, balance, health, error catalog.
Task Status
Poll the status of a task. Same endpoint for every captcha type — call until status is completed or rejected.
Headers
| Name | Type | Required | Default | Example |
|---|---|---|---|---|
| x-solvium-authSolvium API key — get one from @solvium_crypto_bot. | Header | Yes | — | IE0B81Vn... |
Path parameters
| Name | Type | Required | Default | Example |
|---|---|---|---|---|
| task_id | URL | Yes | — | 01959e02-08fd-7000-8cbe-f682a959b3c1 |
Status values
pending— queued, no worker yet.running— worker is solving.completed—solutionis populated.rejected— terminal failure,erroris populated. See Error Codes.
Response
200 OK — same envelope regardless of state. Inapplicable fields come back as null.
Example
from solvium import Solvium
task = Solvium(api_key="YOUR_API_KEY").get_task_sync(
"01959e02-08fd-7000-8cbe-f682a959b3c1"
)
print(task["status"], task["solution"])Balance
Account balance in USD.
Headers
| Name | Type | Required | Default | Example |
|---|---|---|---|---|
| x-solvium-authSolvium API key — get one from @solvium_crypto_bot. | Header | Yes | — | IE0B81Vn... |
Response
Example
from solvium import Solvium
print(Solvium(api_key="YOUR_API_KEY").balance_sync())Health
Liveness probe — no auth required. Returns the server timestamp confirming the API is reachable. Per-captcha-type health is published through Prometheus, not here.
Response
Example
from solvium import Solvium
print(Solvium(api_key="YOUR_API_KEY").health_sync())Error Codes
Every v2 error response uses the same envelope. The code field is the stable machine-readable identifier — match against it, not against the prose in message.
Envelope
{
"error": {
"code": "validation_failed",
"message": "2 field(s) failed validation",
"retryable": false,
"doc_url": "https://docs.solvium.io/errors/validation-failed",
"request_id": "018f3c1a-7b81-7e0f-8a10-8a7ff43b2d8f",
"details": [
{ "field": "url", "code": "string_pattern_mismatch", "message": "String should match pattern '^https?:\\/\\/…'" },
{ "field": "site_key", "code": "missing", "message": "Field required" }
]
}
}code— one of the values in the table below. Stable contract — we only add new codes, never rename.message— human-readable summary. Safe to log, do not parse.retryable— iftrue, the same request may succeed on retry.doc_url— permalink derived fromcode.request_id— include in support tickets.details— only onvalidation_failed. Per-field array.
API errors
| Code | HTTP | Retryable | What it means |
|---|---|---|---|
missing_api_key | 401 | no | X-Solvium-Auth header missing. |
invalid_api_key | 401 | no | Header present but unknown. |
insufficient_scope | 401 | no | Reserved for per-scope keys. |
validation_failed | 422 | no | Request fields failed schema validation. See details. |
invalid_request | 400 | no | Generic client-side request error. |
not_found | 404 | no | task_id unknown or belongs to another account. |
offer_not_found | 400 | no | No pricing offer for this task type. |
insufficient_balance | 402 | no | Top up and retry. |
rate_limit_exceeded | 429 | yes | Back off and retry. |
internal_error | 500 | yes | Retry once; if persistent, include request_id. |
service_unavailable | 503 | yes | Retry with backoff. |
Task-rejection errors
When a task finishes but can't produce a solution, GET /v2/tasks/{id} returns HTTP 200 with status: "rejected" and the error object populated:
{
"task_id": "01959e02-…",
"status": "rejected",
"type": "cf-clearance",
"error": {
"code": "proxy_blocked",
"message": "Proxy blocked",
"retryable": true,
"doc_url": "https://docs.solvium.io/errors/captcha-failed"
},
"cost": "0.0009"
}Common values for error.code:
| Category | Code | How to fix |
|---|---|---|
| Input | invalid_params | Re-check required fields. |
| Input | missing_param | Make sure url and challenge_body_b64 were sent. |
| Input | invalid_base64 | Re-encode with standard base64 (no URL-safe alphabet). |
| Input | no_proxy | Pass a proxy — reCAPTCHA v3 and cf-clearance need one. |
| Challenge | error_render | Verify site_key matches what the page uses. |
| Challenge | challenge_error | Sitekey/URL pair is no longer authorised. |
| Challenge | invalid_challenge | Vercel challenge_token expired; fetch a fresh one. |
| Challenge | wrong_challenge_payload | Re-fetch the protected page; resend challenge_body_b64. |
| Proxy | proxy_blocked | Rotate to a cleaner (residential) IP. |
| Proxy | proxy_error | Bad creds / no HTTPS / dead proxy. |
| Proxy | ip_blocked_by_cloudflare | Switch IP and re-fetch the page. |
| Proxy | bot_detected_by_cloudflare | Use a static residential proxy for cf-clearance. |
| Solve | too_many_attempts_solving | Proxy flagged; rotate. |
| Solve | recaptcha_timeout | Retry; if persistent, switch proxy. |
| Solve | hcaptcha_timeout | Sitekey distrusts your IP — rotate. |
| Solve | solve_timeout | Faster proxy. |
| Solve | upstream_timeout | Transient. Retry once. |
| Solve | upstream_error | Target site changed challenge flow. Refresh the token. |
| Output | empty_token / no_token | Retry. |
| Lifecycle | cancelled | Resubmit. |
| Lifecycle | general_error | Open a ticket with task_id + request_id. |
OpenAPI
The full machine-readable spec is published at https://captcha.solvium.io/openapi.json — feed it into Postman, Insomnia, or any OpenAPI-aware client generator to scaffold a typed SDK.