Kasada ACTIVE
KPSDK x-kpsdk-* minter — full solve, or a request-based payload transformer.
Overview
Kasada protects sites with an ips.js bytecode runtime (a dispatcher VM). A client runs it, builds a payload, and POSTs it to /tl to mint a cleared x-kpsdk-ct token; every subsequent request to a protected endpoint then carries a fresh x-kpsdk-cd proof-of-work.
VexSolver reimplements that runtime as a pure-Go VM — fully request-based, no browser, no headless Chromium. Every request-side header is reverse-engineered and generated natively, not replayed from a template. You can use it two ways:
- › Full solve —
POST /api/solve. We do every network hop and hand back the token bundle. Simplest to integrate. - › Payload transformer —
POST /api/kasada/payload. You own the TLS session, proxy, cookie jar and header order; we only turn the ips.js into a/tlbody. This is the Hyper-Solutions-compatible contract.
/api/kasada/payload) for production scraping: the token is minted from your egress IP, so it never has to be replayed from a different IP than it was earned on, and there is no url field for us to misroute. Use full solve (/api/solve) when you just want a token and do not want to make the fetches yourself.Payload transformer — POST /api/kasada/payload
A drop-in for the Hyper Solutions Kasada endpoint (docs.hypersolutions.co/api-reference/kasada) — an existing Hyper integration repoints by changing only the base URL. You fetch the challenge yourself and send us the ips.js; we return the exact headers and the base64 body to POST to /tl.
Request fields:
- ›
script— the raw ips.js body you fetched (required) - ›
ipsLink— the ips.js URL withx-kpsdk-vandx-kpsdk-imappended as query params (required). Withoutx-kpsdk-imthe payload is not bound to your handshake and/tlrejects it. - ›
userAgent— the exact UA your TLS client sends. Desktop and mobile both supported. - ›
acceptLanguage— yourAccept-Languageheader - ›
ip— your egress IP (informational) - ›
ct— optional. Your preflightx-kpsdk-ct(from your own/fpor the block page). Supply it and we return a complete header set you can send verbatim. We will not mint one — it is bound to your session. - ›
dv— optional, mobile only. Yourx-kpsdk-dv. It is a per-app-build constant; supplied ⇒ echoed back, omitted ⇒ absent. We never fabricate it.
curl -X POST https://api.vexsolver.com/api/kasada/payload \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
"acceptLanguage": "en-US,en;q=0.9",
"ip": "203.0.113.7",
"ct": "0f3HMyTUeHEy8vuVEHmB...",
"ipsLink": "https://www.twitch.tv/149e9513-.../2d206a39-.../ips.js?x-kpsdk-v=j-1.2.308&x-kpsdk-im=AALP1ZtNVs0v...",
"script": "<the full ips.js body you fetched>"
}'Response — attach headers to your /tl POST and send the base64-decoded payload as the body:
{
"headers": {
"x-kpsdk-ct": "0f3HMyTUeHEy8vuVEHmB...",
"x-kpsdk-im": "AALP1ZtNVs0vAz3hL1IT...",
"x-kpsdk-v": "j-1.2.308",
"x-kpsdk-dt": "13cz64jzaez034dy49aw52cz218y79wb2zdjez8asy11jbx9jiwc1h0",
"Content-Type": "application/octet-stream"
},
"payload": "<base64 — decode to bytes before POSTing to /tl>"
}Full transformer flow (what your client does around us)
The transformer does exactly one step: ips.js → /tl body. The fetches on either side are yours, through your own proxy and TLS client, so the whole session shares one IP.
- Fetch the challenge. GET the protected page (or
/fp). The response carries a preflightx-kpsdk-ctheader, aKPSDK:MC:<im>marker in the body (that<im>is yourx-kpsdk-im), and theips.jssrc. - Fetch ips.js from that
src, appending?x-kpsdk-v=…&x-kpsdk-im=<im>. Keep both the URL and the body. - Call
/api/kasada/payloadwithscript(the ips.js body),ipsLink(that URL), yourct,userAgent,ip,acceptLanguage. - POST
/tlyourself with the returnedheadersand the base64-decodedpayloadas the body. The server responds with the clearedx-kpsdk-ct, anx-kpsdk-st, andx-kpsdk-cr: true. - For every protected request, mint a fresh
x-kpsdk-cdvia/api/kasada/cd(below) and send it alongside the clearedx-kpsdk-ct.
Per-request proof-of-work — POST /api/kasada/cd (FREE)
Kasada requires a fresh x-kpsdk-cd on every request to a protected endpoint — a single cd replayed across requests is a stale proof and starts failing. So this endpoint is a sub-millisecond local computation and is billed at 0 credits: scraping 10k pages calls it 10k times and costs nothing extra.
- ›
st— thex-kpsdk-stfrom your/tlresponse (required) - ›
ct— the clearedx-kpsdk-ctfrom your/tlresponse (required) - ›
domain— the protected host (required) - ›
rst— optional but recommended. Your local clock in ms when the/tlresponse landed. Supplying it makesdthe real round-trip; omit it and we model a plausible one. Do not derive it from wall-clock age —stis issued once,cdis per-request.
curl -X POST https://api.vexsolver.com/api/kasada/cd \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"st": 1777215098000,
"rst": 1777215098310,
"ct": "0dhS2BUe4yb8whd4APoV...",
"domain": "www.twitch.tv"
}'
# response
{ "payload": "{\"workTime\":...,\"id\":\"...\",\"answers\":[15,14],\"d\":310,\"st\":1777215098000}" }Send payload as the x-kpsdk-cd header on your protected request, next to x-kpsdk-ct.
Headers we generate (all reverse-engineered, pure Go)
- ›
x-kpsdk-ct— 175-char cleared token, from the VM cipher output - ›
x-kpsdk-im— integrity marker binding the payload to your handshake - ›
x-kpsdk-v— version (j-1.2.308default) - ›
x-kpsdk-dt— device timing digest: 14 duration fields differenced from a monotone timeline, base32-encoded in random order. Fully reversed — produced, not templated. Returned inside the payloadheaders. - ›
x-kpsdk-cd— per-request proof-of-work (geometric-difficulty nonce search). Minted by/api/kasada/cd.
x-kpsdk-cr, x-kpsdk-st, x-kpsdk-h and friends are responseheaders the server issues back — you read them, you do not generate them.
Full solve — POST /api/solve
Prefer to hand us the whole job? /api/solve does every hop — fetch, VM run, /tl POST, cr=true verify — and returns the token bundle in cookie_map. Pass a page url (we auto-discover the challenge) or a direct pjs_url to skip discovery.
curl -X POST https://api.vexsolver.com/api/solve \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"vendor": "kasada",
"url": "https://www.twitch.tv",
"pjs_url": "https://k.twitchcdn.net/149e9513-.../2d206a39-.../p.js"
}'Response:
{
"success": true,
"vendor": "kasada",
"source": "go_kasada",
"target": "https://www.twitch.tv",
"elapsed_ms": 1820,
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
"cookie_map": {
"x-kpsdk-ct": "0dlCkpczkzzZ9bVkjiBiUOZwDDfFm3Cs...",
"x-kpsdk-cd": "{\"workTime\":...,\"answers\":[15,14],\"d\":310,\"st\":...}",
"x-kpsdk-v": "j-1.2.308",
"x-kpsdk-dt": "13cz64jzaez034dy49aw52cz218y79wb2zdjez8asy11jbx9jiwc1h0",
"x-kpsdk-im": "AALTLVJfWjWK797ZyO5QFiScq8Sds...",
"KP_UIDz": "0dlCkpczkzzZ9bVkjiBiUOZwDDfFm3Cs...",
"KP_UIDz-ssn": "0dlCkpczkzzZ9bVkjiBiUOZwDDfFm3Cs..."
}
}Replay: send your protected request with the same User-Agent, the KP_UIDz cookies, and the x-kpsdk-ct + a fresh x-kpsdk-cd (mint it per-request via /api/kasada/cd).
Vercel BotID is built on Kasada
Vercel BotID's Deep tier IS Kasada KPSDK proxied through a UUID-namespaced path (/<deploy>/<kasada>/p.js). When you hit a BotID-protected site (v0.app, vercel.com, etc.), VexSolver auto-routes to the BotID flow which uses this same Kasada engine plus the x-is-human JWE signature for the Basic tier. See Vercel BotID.
vendor: "kasada" + pjs_url (full solve), or send us the ips.js via /api/kasada/payload, and we route them immediately.Typical performance
- › Transformer (
/api/kasada/payload): ~1–2 s in-process VM run - › Per-request cd (
/api/kasada/cd): sub-millisecond, free - › Full solve, warm (
/api/solve): ~1–2 s via the native fast-replay path - › Full solve, cold rotation: falls back to the full goja VM (~30 s). Still succeeds (
cr=true); subsequent solves of that rotation are warm. - › Verified with
x-kpsdk-cr: trueon every tested deployment
Pricing
/api/kasada/payload and /api/solve: 1 credit per success — failures are refunded automatically. /api/kasada/cd is free, so the correct per-request-PoW usage pattern is never punished.
