Web Automation

How Kasada detects bots and scrapers (2026)

How Kasada detects bots and scrapers (2026) — conceptual illustration
On this page

Kasada is one of the more distinctive anti-bot WAFs because of how its client-side challenge is built: a custom VM executing obfuscated bytecode, paired with a real proof-of-work computation. It fronts targets like Realtor.com, RealEstate.com.au, Target, Foot Locker and Hotels.com, and is well-known for breaking automation that relies on static reverse-engineering — the bytecode rotates every few weeks.

This is a reference on how Kasada is structured and what it measures.

Quick facts

Challenge fileips.js / p.js (VM bytecode)
Headersx-kpsdk-ct, x-kpsdk-cd
Distinct signalReal proof-of-work computation
Block styleSilent 429 / 403
Best approachReal-browser VM execution

What Kasada is

Kasada is a reverse-proxy WAF that sits between visitors and the origin. Every request is scored against IP reputation, the output of its in-browser VM, TLS handshake characteristics, and behavioural telemetry.

Low-trust requests surface as one of two responses:

  • A silent 429 Too Many Requests with x-kpsdk-* headers — frequently even on the very first request, which is itself a fingerprint of Kasada rather than actual rate limiting.
  • A proof-of-work challenge served from /ips.js or /p.js that the browser must solve before any further request is honoured.

The four signal categories

1. IP address reputation

  • Datacenter IPs (AWS, GCP, Azure, DigitalOcean, OVH…) — pre-scored low. Kasada is particularly aggressive here; most cloud ranges are blocked outright on Realtor.com and Target.com.
  • Residential IPs — assigned by ISPs to home connections, higher baseline trust.
  • Mobile IPs — cell tower and CGNAT pools, highest baseline trust.

2. The Kasada VM and proof-of-work

This is the layer Kasada is unique for. Instead of a minified-but-readable sensor script, Kasada ships a VM-bytecode payload (ips.js / p.js) executed by a custom interpreter embedded in the same script. The VM mints two headers that authorise subsequent requests:

  • x-kpsdk-ct — a client token tied to the device fingerprint.
  • x-kpsdk-cd — a proof-of-work result that takes a real browser roughly 100ms of CPU to compute. Headless or remotely-computed attempts are throttled.

The VM also collects the usual fingerprint surface — canvas/WebGL, audio context, installed fonts, screen metrics, timezone, navigator.webdriver, the shape of window.chrome, plugin list — and feeds it into the bytecode state. Because the bytecode rotates frequently, pre-built solvers tend to decay within weeks.

3. HTTP and TLS fingerprinting

Before any HTML is exchanged, Kasada fingerprints the client from the TLS handshake (JA3/JA4) and HTTP/2 behaviour.

  • Most scraping libraries still default to HTTP/1.1. Real Chrome and Firefox haven't in years.
  • libcurl and Go's net/http produce JA3 signatures that don't match any real browser.
  • HTTP/2 fingerprinting tracks pseudo-header order, SETTINGS frame values, and window-update sizes.

4. Behavioural and pattern analysis

Kasada runs continuous ML pattern analysis:

  • Missing real-browser headers (Sec-Fetch-*, Accept-Language, sec-ch-ua).
  • x-kpsdk-* tokens from a previous response sent from a different IP.
  • The same proof-of-work result reused across many requests instead of recomputed per navigation.
  • Honeypot link hits.
  • Bursty timing.

What this means for developers

Kasada is the WAF where the VM matters more than anything else — without a valid x-kpsdk-cd, no other signal will save the request. Three general tooling categories:

  • HTTP clients with browser-impersonating TLScurl_cffi, curl-impersonate, tls-client. They match the handshake but cannot execute the VM.
  • Stealth-patched browsersCamoufox, patchright, Playwright with stealth plugins. Execute the VM in a real browser context.
  • Managed scraping APIs — services like Scrappey that keep pace with ips.js rotations on the user's behalf.

For reference, a minimal managed-API example:

import requests

response = requests.post(
    'https://publisher.scrappey.com/api/v1',
    json={
        'cmd': 'request.get',
        'url': 'https://example.com/search?q=...',
        'session': 'kasada-session-1'
    },
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
print(response.json()['solution']['response'])

Reusing the session value across requests keeps the x-kpsdk-* tokens and trust score warm — re-computing a fresh proof-of-work on every request is both slow and a strong automation signal.

Sites commonly fronted by Kasada

Real-estate, retail, hospitality and ticketing: Realtor.com, RealEstate.com.au, Target.com, Footlocker.com, Hotels.com. Many of these rotate between Kasada, Cloudflare, Akamai, DataDome and PerimeterX depending on conditions.

Summary

Kasada produces a continuous trust score from IP reputation, the ips.js VM with its proof-of-work output, TLS/HTTP/2 fingerprints, and behavioural patterns. The VM is the most distinctive piece — static reverse-engineering decays quickly because the bytecode rotates, which is why real-browser execution is the dominant approach in production.

Related terms

Concept map

How How Kasada detects bots and scrapers (2026) connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Web Automation
Building map…

Frequently asked questions

What makes Kasada different from other WAFs?

It ships a custom VM running obfuscated bytecode plus a genuine proof-of-work the browser must compute. The bytecode rotates often, so static reverse-engineering decays within weeks.

What are the x-kpsdk headers?

x-kpsdk-ct is a client token tied to the device, and x-kpsdk-cd is the proof-of-work result. Without a valid x-kpsdk-cd, no other signal saves the request.

Why do I get a 429 on my very first request?

That silent 429 with x-kpsdk headers is Kasada's low-trust response, not real rate limiting — it means you have not solved the VM challenge yet.

Last updated: 2026-05-28