Kasada is one of the most advanced bot protection systems on the web, used by Twitch, Kick, Nike, and Arc'teryx. Unlike Cloudflare Turnstile, very few solvers support Kasada — and almost no documentation exists online about how to bypass it. In this guide, you'll learn exactly how Kasada works, why it's hard to bypass, and how to solve it programmatically using the NSLSolver API.
What is Kasada?
Kasada (formerly Kasada IPS) is a bot mitigation platform that combines browser fingerprinting with proof-of-work (PoW) challenges. It's designed to detect and block automated traffic at the edge, before requests ever reach the origin server.
Kasada protects some of the world's most heavily-trafficked platforms:
- Twitch — live streaming platform (login, GQL API)
- Kick — streaming and live content platform
- Nike — sneaker drops and product pages
- Arc'teryx — outdoor apparel (checkout and account)
How Kasada protection works
When a browser visits a Kasada-protected page, the following sequence happens:
- The page loads a JavaScript file called p.js from a unique path on the target domain.
- p.js collects an extensive browser fingerprint — canvas, WebGL, audio context, navigator properties, screen dimensions, installed fonts, and more.
- The script generates a proof-of-work solution (a computationally expensive hash challenge) to prove the client is a real browser.
- The fingerprint and PoW result are packaged into x-kpsdk-ct (client token), x-kpsdk-cd (challenge data), x-kpsdk-v (version), and x-kpsdk-h (hardware hash) headers.
Every subsequent request to the protected API must include these headers with valid, non-expired values. Without them, the server returns a 429 or redirects to a challenge page.
Why Kasada is hard to bypass
Kasada is significantly harder to bypass than most CAPTCHA systems:
- !Heavy browser fingerprinting — Kasada collects 50+ browser signals and compares them against known browser profiles. Headless browsers and spoofed user agents are detected instantly.
- !Proof-of-work challenges — the PoW component requires real computational work, preventing simple replay attacks and adding latency to brute-force attempts.
- !Frequent updates — Kasada regularly changes its detection methods, fingerprint collection, and p.js obfuscation. Solutions that work today may break tomorrow.
- !Very few solvers support it — most CAPTCHA solving services (2Captcha, Anti-Captcha, CapSolver) don't offer Kasada solving at all, making it one of the hardest protections to work around.
The solution: NSLSolver Kasada API
NSLSolver handles the entire Kasada challenge flow server-side. You send us the target URL and configuration, and we return the x-kpsdk headers you need:
- No browser required — we solve challenges on our infrastructure and return just the headers.
- Always up to date — we monitor Kasada's changes and update our solvers automatically.
- Simple REST API — one POST request, get headers back in seconds.
Step 1: Install the Python SDK
Install the official NSLSolver Python SDK from PyPI:
Step 2: Understand the parameters
Kasada solving requires more parameters than a simple CAPTCHA. You'll need to inspect the target site's network traffic to find these values:
| Parameter | Required | Description |
|---|---|---|
| url | Yes | The full URL of the Kasada-protected page |
| user_agent | Yes | Your browser's User-Agent string — must match exactly in your subsequent requests |
| ua_version | Yes | Chrome major version number from the User-Agent (e.g., 145) |
| kasada_config.p_js_path | Yes | Path to Kasada's p.js script — find it in your browser's Network tab |
| kasada_config.fp_host | Yes | Hostname that serves the Kasada fingerprint page (often the login domain) |
| kasada_config.tl_host | Yes | Hostname for the Kasada TL token endpoint (often the API domain) |
Step 3: Solve the Kasada challenge
Use the NSLSolver SDK with KasadaConfig to solve the challenge. Here's a Twitch example:
from nslsolver import NSLSolver, KasadaConfig
solver = NSLSolver("nsl_YOUR_API_KEY")
result = solver.solve_kasada(
url="https://passport.twitch.tv",
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
ua_version=145,
kasada_config=KasadaConfig(
p_js_path="/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/p.js",
fp_host="passport.twitch.tv",
tl_host="gql.twitch.tv"
)
)
print(result.headers)The API returns the solved x-kpsdk headers you need:
{
"success": true,
"headers": {
"x-kpsdk-ct": "eyJ0eXAi...a_long_token",
"x-kpsdk-cd": "AQAAAJY...proof_of_work_solution",
"x-kpsdk-v": "j-0.0.0",
"x-kpsdk-h": "SW50ZWw...browser_hash"
},
"cost": 0.002
}Step 4: Use the headers in your requests
Attach the returned headers to your requests to the protected API. Make sure the User-Agent matches exactly what you passed to the solver:
import requests
# After solving Kasada with NSLSolver:
kasada_headers = result.headers
# Make your request with the solved headers
response = requests.post(
"https://gql.twitch.tv/gql",
headers={
"x-kpsdk-ct": kasada_headers["x-kpsdk-ct"],
"x-kpsdk-cd": kasada_headers["x-kpsdk-cd"],
"x-kpsdk-v": kasada_headers["x-kpsdk-v"],
"x-kpsdk-h": kasada_headers["x-kpsdk-h"],
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
"Content-Type": "application/json"
},
json={"query": "..."}
)
print(response.status_code)Complete example with error handling
Here's a production-ready example with retries and error handling:
from nslsolver import NSLSolver, KasadaConfig
import requests
import time
API_KEY = "nsl_YOUR_API_KEY"
TARGET_URL = "https://passport.twitch.tv"
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"
def solve_kasada(retries=3):
"""Solve Kasada challenge via NSLSolver Python SDK."""
solver = NSLSolver(API_KEY)
for attempt in range(retries):
try:
result = solver.solve_kasada(
url=TARGET_URL,
user_agent=USER_AGENT,
ua_version=145,
kasada_config=KasadaConfig(
p_js_path="/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/p.js",
fp_host="passport.twitch.tv",
tl_host="gql.twitch.tv"
)
)
if result.success:
return result.headers
print(f"Attempt {attempt + 1} failed")
except Exception as e:
print(f"Error: {e}")
if attempt < retries - 1:
time.sleep(3)
return None
# Solve and use the headers
headers = solve_kasada()
if headers:
print("Got Kasada headers, making request...")
resp = requests.post(
"https://gql.twitch.tv/gql",
headers={
**headers,
"User-Agent": USER_AGENT,
"Content-Type": "application/json"
},
json={"query": "..."}
)
print(f"Status: {resp.status_code}")
else:
print("Failed to solve Kasada after retries.")Pricing and performance
Kasada solving is priced per solve, reflecting the computational cost of the PoW challenges:
- $$1.50 per 1,000 solves — pay only for successful solves
- ~3-10 seconds average solve time — PoW challenges take longer than simple CAPTCHAs
- %90%+ success rate — we monitor and adapt to Kasada's frequent updates
Important: The User-Agent you pass to NSLSolver must exactly match the User-Agent you use in your subsequent requests. Kasada validates this header against the fingerprint — a mismatch will cause an immediate block.
Ready to bypass Kasada?
Create a free account and get 100 requests to try it out. No credit card required.