Solve Endpoint
Submit a URL, poll for the result. Async by design.
How it works
VexSolver is an async API. Every solve is two steps:
- POST
/api/solve— get ataskIdimmediately. - Poll GET
/api/getTaskResult?taskId=...until done. Or pass acallbackURL to skip polling.
Submit a solve task. Returns taskId immediately. Deducts 1 credit upfront (more for domains with a configured credit cost). Credits are refunded automatically on failure.
Request body (JSON or form-encoded)
| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | Target page URL (must be https) |
vendor | string | no | Force vendor: datadome, perimeterx, kasada, akamai, incapsula, vercel_botid, imperva. Auto-detected if omitted. |
proxy | string | no | user:pass@host:port or http://... |
app_id | string | no | PerimeterX app ID (PXxxxxxxxxxx). Required only when PX is not auto-detected. |
user_agent | string | no | Pin the UA the cookie is minted with (PX TLS-replay alignment) |
fresh | bool | no | Skip cookie cache; force a live solve |
callback | string | no | Webhook URL we POST the result to when done (see Webhooks) |
Example request
curl -X POST https://api.vexsolver.com/api/solve \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.target-site.com/path",
"proxy": "http://user:pass@your-proxy:8080"
}'Response (HTTP 200)
{ "taskId": "abc123xyz" }Use the taskId to poll the result endpoint below.
Poll for the result of an async solve task. Retry every 1–2 seconds. Tasks expire after 5 minutes.
Query params
| Param | Required | Description |
|---|---|---|
taskId | yes | The task ID returned by /api/solve |
Response — pending
{ "status": "pending" }Response — success
{
"success": true,
"vendor": "datadome",
"cookies": "datadome=3y1u8z...; ...",
"cookie_map": { "datadome": "3y1u8z..." },
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
"elapsed_ms": 1840,
"cached": false,
"proxy_used": "user:pass@host:port"
}Response — failure
{
"success": false,
"error": "datadome solve failed: no trusted IP found",
"vendor": "datadome",
"elapsed_ms": 12000
}The credit is refunded automatically. You are not charged for failed solves.
Polling example (Python)
import time, requests
API = "https://api.vexsolver.com"
KEY = "sk_live_..."
HEADERS = {"X-API-Key": KEY}
# 1. Submit
r = requests.post(f"{API}/api/solve",
json={"url": "https://www.target-site.com/path"},
headers={**HEADERS, "Content-Type": "application/json"})
task_id = r.json()["taskId"]
# 2. Poll
for _ in range(60):
time.sleep(2)
r = requests.get(f"{API}/api/getTaskResult",
params={"taskId": task_id}, headers=HEADERS)
data = r.json()
if data.get("status") != "pending":
break
print(data)Kasada only. Returns the /tl request body and headers without posting them. Use this when you need to POST /tl from your own IP (high-volume drops where IP-binding matters).
Request body
| Field | Required | Description |
|---|---|---|
url | yes | The page URL (Kasada-protected) |
pjs_url | no | Direct p.js URL if known |
cjs_url | no | Direct c.js URL if known |
Response
{
"success": true,
"tl_url": "https://www.target-site.com/tl",
"tl_body_b64": "<base64-encoded POST body>",
"headers": { "x-kpsdk-v": "...", "x-kpsdk-dt": "...", "x-kpsdk-im": "..." },
"user_agent": "Mozilla/5.0 ...",
"pjs_url": "https://...p.js",
"elapsed_ms": 540
}Base64-decode tl_body_b64 and POST it to tl_url with the supplied headers + User-Agent from your own IP. The resulting x-kpsdk-ct token will be bound to your IP, not ours.
Supported vendors
| Vendor | Auto-detected? | Notes |
|---|---|---|
datadome | yes | DD v5+, cookie-based |
perimeterx | yes | PX3 cookie; set app_id for non-standard deployments |
kasada | yes | /tl token; use /api/payload for own-IP flow |
akamai | yes | Bot Manager sensor (_abck cookie) |
incapsula | yes | Imperva Incapsula (reese84) |
imperva | yes | Alias for incapsula |
vercel_botid | yes | Vercel BotID (Basic + Deep tier) |
callback in the solve body and we'll POST the result to your URL when done. See Webhooks for the payload shape.