Skip to content
voidcaptcha

Concepts

TLS API

Some sites refuse a request before any challenge appears, on the shape of the TLS handshake alone. This endpoint makes the request for you with a real Chrome fingerprint and returns the answer unchanged.

What it does#

It is not a CAPTCHA endpoint. You give it a URL; it performs that request with a byte-exact Chrome ClientHello, the matching HTTP/2 settings and Chrome’s own header order, and hands you back the target’s response — its status, its headers, its body. This is the same engine the solvers use underneath; this endpoint is it, exposed.

Because the profile owns the fingerprint, the browser headers can never disagree with the handshake. user-agent, sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform, accept-language and accept-encoding are all owned by the profile: send them and they are ignored, because a value that disagrees with the handshake is the exact tell this endpoint exists to avoid.

Every other header you send is forwarded to the target, in Chrome’s order. Nothing about the request that reached us is: the address you called from, the country you called from and the fact that you came through us are all removed before the request is made. Cookies are the one exception to “everything else is forwarded” — send them as x-void-cookie and they arrive at the target as cookie, so a browser session on this site can never be relayed by accident.

Making a request#

POST https://api.voidcaptcha.com/v1/fetch. The target goes in a header, not the body — the body is yours and is forwarded to the target untouched. Your key is a bearer token for the same reason.

curl
curl -s -X POST https://api.voidcaptcha.com/v1/fetch \
  -H "authorization: Bearer void_a1b2c3d4e5f60718293a4b5c6d7e8f90" \
  -H "x-url: https://example.com/login" \
  -H "x-type: GET" \
  -H "x-client: chrome154" \
  -H "x-proxy: user:pass@host:port"

The headers that steer the engine:

headers
x-url         the target URL                                    required
x-type        GET POST PUT PATCH DELETE HEAD OPTIONS          default GET
x-client      profile name: chrome152 · chrome153 · chrome154  default newest · or rotate / rotate:windows,linux / rotate:chrome154,chrome153 — one whole Chrome persona per session, reported in x-void-profile
              ...-linux variants available for a Linux persona
x-proxy       host:port:user:pass · user:pass@host:port ·      default none
              http://user:pass@host:port · socks5://…            (our IP)
x-protocol    http2 (default) · 1.1 · http3
x-void-header-order   comma-separated names: the exact wire order for your own headers; unnamed ones follow
x-session     cookie-jar and keep-alive isolation id, private to your key   default: a fresh session per request
x-timeout     seconds                                          default 45
x-redirects   0 to receive redirects instead of following them default 1
x-kind        navigate (page load) or fetch (XHR) header shape inferred
x-soft-id     your own label, echoed into your usage history   optional
x-void-cookie sent to the target as its cookie header            optional

Tip

x-session is how you keep a cookie jar across calls. Two requests with the same session id share cookies and a connection; two with different ids share nothing.

What comes back#

The target’s response, as it was: the same status code, the same headers, the same body. A 403 from the target is returned as a 403 — we performed the request you asked for and that was the answer. Three headers are added:

added headers
x-void-status       the target's status code
x-void-elapsed-ms   how long the request took
x-void-request-id   our id for it, quote this in support

A failure on our side — a target that never answered, an engine that could not be reached, a URL we refuse — comes back in the same JSON shape as the rest of the API, with an errorCode, and is not charged.

What it costs#

$1.00 per 10,000 requests, billed per request against the same balance as everything else and shown in the same usage history. A request that we refused or that never reached the target costs nothing; a request that was delivered is charged whatever the target answered, because delivering it is the work.

It is not covered by a subscription. A subscription prices captcha threads, which does not describe an HTTP fetch, so this is per-request only.

Limits#

Warning

Targets that resolve to a private, loopback, link-local or otherwise reserved address are refused. The check is on the resolved address, not the hostname, so pointing a name you control at an internal address does not get past it.

Requests count against your account’s concurrency in the same way solves do, so an account at its thread limit is refused here too. If you do not pass x-proxy the request leaves from our address — fine for reading a public page, wrong for anything that has to match a session you hold elsewhere.

Last updated on 2 August 2026