What is PerimeterX (HUMAN Security)?
PerimeterX (now HUMAN Security) is a bot protection platform that scores requests on IP trust, browser fingerprint, TLS/JA3, and on-page behavior. The visible CAPTCHA is a press-and-hold button; the cookie hierarchy is _px3 (newer/strict, 60s expiry) > _px2 (older sites) > _pxhd (fallback).
How it works
Send Task
POST your AntiPerimeterXTask with the target URL and sitekey to our API. We'll queue it instantly.
We Solve
Capzy's proprietary solver returns the PerimeterX clearance cookies (_px3 / _px2 / _pxhd) needed to access the protected page. ProxyLess is routed for you; AntiPerimeterXTask uses your own proxy.
Get Token
Poll getTaskResult — when status is 'ready', the solution contains the token to inject into the target page.
Quick integration
import requests, time
API = "https://api.capzy.ai"
KEY = "capzy_your_key_here"
# Step 1: Create task
task = requests.post(f"{API}/createTask", json={
"clientKey": KEY,
"task": {
"type": "AntiPerimeterXTask",
"proxyPort": "8080",
"proxyType": "http",
"proxyLogin": "user",
"websiteURL": "https://example.com",
"proxyAddress": "123.45.67.89",
"proxyPassword": "pass"
}
}).json()
task_id = task["taskId"]
print(f"Task created: {task_id}")
# Step 2: Poll for result
while True:
result = requests.post(f"{API}/getTaskResult", json={
"clientKey": KEY,
"taskId": task_id
}).json()
if result["status"] == "ready":
print("Solved!", result["solution"])
break
elif result["status"] == "failed":
print("Failed:", result.get("errorDescription"))
break
time.sleep(1)
# Step 3: Use the result — drop-in Cookie: header replay
sol = result["solution"]
headers = {
"Cookie": sol["cookie"],
"User-Agent": sol.get("userAgent", ""),
}
# IMPORTANT: route through the SAME proxy you supplied at solve time
resp = requests.get("https://target.example.com/", headers=headers, proxies={
"http": "http://USER:PASS@PROXY_HOST:PORT",
"https": "http://USER:PASS@PROXY_HOST:PORT",
})
print(resp.status_code, len(resp.text), "bytes")Task parameters
typetypestringreqyesAntiPerimeterXTaskProxyLess (residential routed) or AntiPerimeterXTask (your proxy)websiteURLtypestringreqyesThe page URLproxyTypetypestringreqyesProxy protocol: http or httpsproxyAddresstypestringreqyesProxy IP address or hostnameproxyPorttypenumberreqyesProxy port numberproxyLogintypestringreqnoProxy username (if auth required)proxyPasswordtypestringreqnoProxy password (if auth required)userAgenttypestringreqyesUser-Agent string to use. Must match the UA you use when submitting the tokenSolution response
tokentypestringThe winning `_px3` (or `_px2` / `_pxhd`) cookie value alone — the cleanest token-form payload for clients that just need the clearance.cookietypestringPre-built `name=value; name=value` Cookie header string with every `_px*` / `_pxhd` cookie. Drop directly into a `Cookie:` request header.cookiestypearrayStructured cookie array `{name, value, domain, path}` for clients building their own cookie jar. Includes every `_px*` and `_pxhd` cookie present on the context after the solve.userAgenttypestringExact User-Agent the solver browser used. PerimeterX correlates UA with the TLS fingerprint that produced the clearance — reuse verbatim on replay.ipBoundtypebooleanAlways `true`. PerimeterX clearance is IP-bound — replay through the same proxy that solved.challengePresentedtypeboolean`true` if the Hold Captcha widget actually rendered and we exercised the press-and-hold path. `false` if PX silent-passed the session on fingerprint alone (still a successful solve, but the press handler wasn't tested).holdDurationSectypenumberHow long we held the press button, in seconds. Zero on silent passes.holdStrategytypestringEither `challengeTime` (we captured the server-supplied duration from the bundle) or `fallback-window` (the bundle's duration wasn't capturable for this deployment and we used a community-tuned 8.5–11s window).challengeTimeMstypenumberWhen `holdStrategy=challengeTime`, the actual server-supplied hold duration in milliseconds. Null when we fell back to the window.collectorEventstypearrayRecords of POSTs to PX's `collector-*.perimeterx.net/api/v[12]/collector/{s2s,ocaptcha,captcha}` endpoints during the solve. Each entry: `{url, status, body_excerpt, at}`. Useful for diagnosing failures — empty means the press never reached PX's collector at all.uuidtypestringVisitor ID PX bound the clearance to (the `_pxvid` cookie value). Only present when `challengePresented=true`. Pin your downstream session to this UUID — submit as `_pxvid` cookie alongside the `_px3` clearance so PX validates the triple.vidtypestringVisitor identifier (often same as `uuid`, sometimes set separately by the PX bundle via `window._pxhc.vid`). Only present when `challengePresented=true`. Pin alongside `uuid` for sites that enforce the separate vid.Example response
Full getTaskResult response shape. The fields in the table above describe what's inside solution — the outer envelope (errorId, status) is identical for every captcha type.
{
"errorId": 0,
"status": "ready",
"solution": {
"vid": "aeaa41ad-53c7-11f1-933e-72f891b6838a",
"uuid": "aeaa41ad-53c7-11f1-933e-72f891b6838a",
"token": "abcdef1234567890.xyz789.abc...",
"cookie": "_px3=abcdef1234567890.xyz789.abc...; _pxhd=hardened_device_cookie",
"cookies": [
{
"name": "_px3",
"path": "/",
"value": "abcdef1234567890.xyz789.abc...",
"domain": ".example.com"
},
{
"name": "_pxvid",
"path": "/",
"value": "aeaa41ad-53c7-11f1-933e-72f891b6838a",
"domain": ".example.com"
},
{
"name": "_pxhd",
"path": "/",
"value": "hardened_device_cookie_value",
"domain": ".example.com"
}
],
"ipBound": true,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"holdStrategy": "challengeTime",
"challengeTimeMs": 9100,
"collectorEvents": [
{
"at": 12.3,
"url": "https://collector-PXzC5j78di.perimeterx.net/api/v2/collector/s2s",
"status": 200,
"body_excerpt": "{\"do\":[]}"
}
],
"holdDurationSec": 9.42,
"challengePresented": true
}
}Error response
Failures use the same envelope with errorId: 1 plus errorCode + errorDescription. See the error-code reference for the full list.
{
"errorId": 1,
"errorCode": "ERROR_CAPTCHA_UNSOLVABLE",
"errorDescription": "Solver gave up — automatically refunded."
}Pending response
While the solver is still working, getTaskResult returns status: "processing". Poll every 1–2 seconds until ready or failed.
{
"errorId": 0,
"status": "processing"
}Features
task types
required: AntiPerimeterXTask