Skip to content

PerimeterX Invisible

Request a clearance for a URL, with no 403 to capture. This flow needs a URL and a proxy. There is no block to capture, because PerimeterX issues the clearance after observing the session rather than after a challenge.

POST /createTask · example
{
  "clientKey": "capzy_YOUR_API_KEY",
  "task": {
    "type": "PerimeterXInvisibleTask",
    "websiteURL": "https://www.example.com/login",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
    "proxyType": "http",
    "proxyAddress": "123.45.67.89",
    "proxyPort": "8080",
    "proxyLogin": "user",
    "proxyPassword": "pass"
  }
}

Illustrative values. Replace the inputs with values from your current integration.

The protected URL plus your proxyYour session proxy requiredThe _px3 clearance PerimeterX mints

Pick the page you need access to.

This flow needs a URL and a proxy. There is no block to capture, because PerimeterX issues the clearance after observing the session rather than after a challenge.

Your API key authenticates Capzy.
Provider keys, challenge IDs, images, and session values belong inside task.

Use the page your client calls.

  1. Open the page your client needs access to, for example a login or account page, and confirm it loads PerimeterX.
  2. Send that full URL as websiteURL. A block body, cookies and identifiers are all optional here.
  3. Keep the original request in your client so you can run it once the clearance is returned.
Input collection example - replace illustrative values
{
  "websiteURL": "https://example.com/login"
}

Use the page itself, not a challenge iframe URL.

How PerimeterX Invisible works

PerimeterX does not always show a press-and-hold. On many pages it scores the session quietly and issues a clearance cookie with no challenge at all, which means there is no 403 to capture and nothing to solve. The block-replay flow has no input in that situation, and a plain press task can report failure even though PerimeterX had already issued a valid cookie.

We open the URL on your proxy and let the PerimeterX sensor observe a real session: a loaded page, scripted cursor and scroll activity, and the telemetry the client reports while that happens. PerimeterX then issues the clearance it would issue for any trusted visitor, and we return it. If a press-and-hold does appear we hold it and report that in challengePresented. The clearance is bound to the solving IP and User-Agent, so replay through the same proxy with the returned userAgent.

  • No 403 or block body required, just the URL
  • Returns the _px3 clearance PerimeterX mints for an observed session
  • silentPass tells you whether a challenge was shown at all
  • Holds a press-and-hold automatically if one does appear
  • PerimeterX cookies only, never the target site own session cookies
  • Bring your own proxy, since the clearance is IP-bound

Know what goes in.

Choose a field to see its purpose, where to get it, and its place in the request. Optional values omitted from the example can be added when your flow uses them.

Send the page your client needs and your proxy. Nothing else is required. Use this when your request is not returning a 403 block body, or when you simply want a valid clearance for a page before calling it.

Request authentication

Required task inputs

Optional context

Proxy connection

websiteURL

stringRequired

Full URL of the protected page, for example a login or account page. Use the page itself, not a challenge iframe URL such as `iframe.hsprotect.net`, which renders nothing on its own.

Where it comes from

Copy the full page URL from the address bar or the document request in Network, including the path where this flow runs.

Open the input guide
Example valuehttps://www.example.com/login
POST /createTask · selected configuration
{
  "clientKey": "capzy_YOUR_API_KEY",
  "task": {
    "type": "PerimeterXInvisibleTask",
    "websiteURL": "https://www.example.com/login",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
    "proxyType": "http",
    "proxyAddress": "123.45.67.89",
    "proxyPort": "8080",
    "proxyLogin": "user",
    "proxyPassword": "pass"
  }
}

The selected field is highlighted when present. Preserve the declared value type and current challenge context.

Make your first request.

Create the task, keep its taskId, and poll until status is ready. Then read the selected variant's solution.

More examples
  1. Create the task

    Send clientKey and the selected task to /createTask from your server. Keep the returned taskId.

  2. Wait for the solution

    Send that same key and ID to /getTaskResult. While processing, wait two seconds before checking again. Stop on Ready or an error.

  3. Apply the result

    Apply solution.cookie or solution.cookies, reuse solution.userAgent, and send your request through the same proxy. Read silentPass to see whether PerimeterX showed a challenge or cleared the session without one.

solve_perimeterx_invisible.py
import json, os, time
import requests

API = "https://api.capzy.ai"
KEY = os.environ["CAPZY_API_KEY"]
task = json.loads("{\"type\":\"PerimeterXInvisibleTask\",\"websiteURL\":\"https://www.example.com/login\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\"proxyType\":\"http\",\"proxyAddress\":\"123.45.67.89\",\"proxyPort\":\"8080\",\"proxyLogin\":\"user\",\"proxyPassword\":\"pass\"}")

def call(path, payload):
    response = requests.post(f"{API}/{path}", json={"clientKey": KEY, **payload}, timeout=30)
    response.raise_for_status()
    data = response.json()
    if data.get("errorId", 0) or data.get("status") == "failed":
        raise RuntimeError(data.get("errorDescription") or data.get("errorCode") or "Task failed")
    return data

created = call("createTask", {"task": task})
for attempt in range(60):
    result = call("getTaskResult", {"taskId": created["taskId"]})
    if result.get("status") == "ready":
        solution = result["solution"]
        print(solution)
        break
    time.sleep(2)
else:
    raise TimeoutError("Task is still processing; keep the taskId to check it later.")

Before runningReplace all illustrative inputs with your captured values. Set CAPZY_API_KEY in your environment. Install requests with pip install requests.

Polling and failuresThe example checks HTTP/API failures, uses 30-second request timeouts, and stops after 60 result checks. Retain taskId if your task is still processing.

Understand what comes back.

Follow this task from creation to completion. Response fields and usage follow your selected request variant.

The _px3 clearance PerimeterX mints

Apply solution.cookie or solution.cookies, reuse solution.userAgent, and send your request through the same proxy. Read silentPass to see whether PerimeterX showed a challenge or cleared the session without one.

string
The clearance cookie value on its own, `_px3` where present and `_px2` otherwise.
string
Ready-to-paste `Cookie:` header value containing the PerimeterX cookies. Only `_px*`, `_pxhd` and `pxcts` are returned, never the target site own session cookies.
array
The same PerimeterX cookies as `{name, value, domain, path}` for building your own jar.
string
User-Agent used during the solve. The clearance is bound to it, so replay with this exact value.
boolean
`true` when PerimeterX never showed a challenge and issued the clearance from the observed session, which is the normal result for this task. `false` means a press-and-hold appeared and we held it.
boolean
The inverse of `silentPass`. `true` only when a widget actually rendered and was pressed.
string
The visitor id (`_pxvid`) the clearance was issued against. Pin it in your downstream session so PerimeterX sees one continuous visitor.
number
How much telemetry the PerimeterX client reported during the solve. A larger figure means the session was observed for longer before the clearance was issued. Diagnostic only.
boolean
Always `true`. The clearance is tied to the solving IP, so replays must use the same proxy.
POST /getTaskResult · example response
{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "token": "<_px3 cookie value>",
    "cookie": "_pxvid=<uuid>; _px3=<value>",
    "cookies": [
      {
        "name": "_pxvid",
        "value": "<uuid>",
        "domain": ".example.com",
        "path": "/"
      },
      {
        "name": "_px3",
        "value": "<value>",
        "domain": ".example.com",
        "path": "/"
      }
    ],
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
    "silentPass": true,
    "challengePresented": false,
    "vid": "<the _pxvid the clearance was issued against>",
    "telemetryBytes": 35162,
    "ipBound": true
  }
}

Illustrative values. Additional metadata may be returned; only Ready contains a completed solution.

Use the result

Apply solution.cookie or solution.cookies, reuse solution.userAgent, and send your request through the same proxy. Read silentPass to see whether PerimeterX showed a challenge or cleared the session without one.

Execution context result is the parsed Ready response from the polling example. session, when referenced, is your existing requests.Session (or browser-compatible session) with the original cookie jar, headers, and solving proxy configured in session.proxies for both http and https. Keep this client for the complete flow. task is the task object you submitted. For Shape, action_body is the original protected request body as bytes or a string, with its original Content-Type in session.headers. Install curl_cffi when the fragment imports it; match the target's required browser/TLS identity.

Use the result · Python

from http.cookies import SimpleCookie
sol = result["solution"]
cookie_values = SimpleCookie()
cookie_values.load(sol["cookie"])
for name, cookie in cookie_values.items():
    session.cookies.set(name, cookie.value, domain="target.example.com", path="/")
session.headers["User-Agent"] = sol["userAgent"]
# session retains the original cookie jar and the solve's proxy.
resp = session.get("https://target.example.com/", timeout=30)
print(resp.status_code)

When something doesn't work.

Check your captured values, the selected variant, and the response before starting another task.

When should I use this instead of the standard PerimeterX task?

Use it when you have no 403 to send. Some tenants rarely challenge: PerimeterX scores the session, issues a clearance, and never renders a press-and-hold. There is no block body to capture in that case, so the block-replay flow has no input, and a press task can report failure even though a valid cookie was available. This task asks for the clearance directly. If your request IS returning a 403 block, prefer `AntiPerimeterXTask` with `blockData`, because solving your own block binds the clearance to the session that was flagged.

What does silentPass mean in the response?

`silentPass: true` means PerimeterX never showed a challenge and issued the clearance after observing the session. That is the expected result for this task. `silentPass: false` means a press-and-hold did appear and we held it, so the clearance came from a solved challenge. Both return a usable cookie, and the field is there so you know which one you are holding. A silent-pass clearance was never tested against a challenge, so if your own session is separately flagged, solve your 403 with the block task instead.

Why is a proxy required?

PerimeterX binds the clearance to the IP it was issued to. A cookie minted on one exit is rejected when the request comes from another, so the solve and your replay have to share a proxy. Use a sticky session long enough to cover both. Reuse the returned `userAgent` as well, because the clearance is tied to that too.

How long does it take?

Around 15 to 25 seconds. Most of that is deliberate: PerimeterX issues a clearance for a session it has actually observed, so the page is loaded and cursor and scroll activity is driven for long enough that the client has something real to report. An idle page load reports almost nothing and is far less likely to earn a clearance.

What do I do with the response?

Apply `cookie` to your `Cookie:` header, or `cookies` if you keep a jar, set `User-Agent` to the returned `userAgent`, and send your request through the same proxy you supplied. Keep the returned `vid` on your session so PerimeterX sees one continuous visitor rather than a new one on every call.

Can I use it to keep a session alive?

Yes, as a refresh. PerimeterX rotates `_px3` frequently, so re-run the task on the same proxy when the cookie expires and keep the same `vid`. Replay from a normal HTTP client rather than an automation-flagged browser, since PerimeterX re-scores the client on every page load and an instrumented browser is re-challenged even with a valid clearance.

Connect PerimeterX Invisible to your workflow.

Get your Capzy API key and use this guide's integration.

$2.00Per 1,000 solves
20.0sAverage solve time

PerimeterXInvisibleTask · Live configuration