cdpfleet Docs Sign up free

Examples & benchmarks / #77 · 2026-10-30 · Benchmark · Medium · for web scraping

Kasada and AWS WAF on real sites: twelve browsers, four sites, one exit each

Two real sites behind Kasada and two behind AWS WAF, loaded once by each of twelve browsers and by a returning Camoufox profile, through one sticky residential exit per site, with the vendor signals and how long an automatic check took to clear. Dated 2026-10-30.

Google Chrome Microsoft Edge Brave Opera Yandex Browser Naver Whale Chromium Patchright Firefox WebKit Camoufox

Run on production on 2026-10-30: ✓ Node.js ✓ Python ✓ Java ✓ C# ✓ Go

A benchmark: the results below are what this setup measured on the dates shown, on our own test runs. Sites, networks and browsers change, so rerun the code before you rely on the numbers.

The problem

Kasada and AWS WAF were the two vendors our vendor survey found on too few public pages for their own lab case. This one takes the four real sites from our sweep where each vendor showed up on every load — two Kasada sites (one our sweep rated medium, one hard) and two AWS WAF sites (both easy for headless Chrome in the sweep) — and loads each once with twelve browsers and a returning Camoufox profile, through one residential exit per site, recording what each load ended on and how long an automatic check took.

What we used, and why

WhatWhy
Twelve browsersChrome headful and headless, Edge, Brave, Opera, Yandex, Whale, Chromium headless and Patchright (all Chromium), Firefox, WebKit, and Camoufox (based on Firefox source; not affiliated with Mozilla). Rebrowser needs a Playwright 1.52 client, so it's left out of a program written for 1.60.
proxy: cdpfleet-resi-country-us-session-<id>One sticky residential exit per site, shared by every setup on that site, so a difference between rows is the browser.
One session at a time per siteEach site's setups run one after another; the four sites run side by side.
page.on("response")The status of the page's first response and of the last main-page document 8 s later. Kasada answers a visitor it wants to check with 429 and a script; AWS WAF's automatic check answers 202 with its challenge.js. When either clears by itself the page reloads with 200: that is cleared, with the seconds it took.
Vendor signals, by name onlyKasada: its ips.js script, x-kpsdk-* headers and KP_UIDz cookies. AWS WAF: an awswaf.com or challenge.js request, the x-amzn-waf-action header and the aws-waf-token cookie. Cookie and header values are never read.
page.evaluate() after 8 sAWS WAF's CAPTCHA, or a short "verify you are human" page, is challenge; a near-empty page (Kasada's 429 answer that never cleared), an "access denied" page or a final error status is blocked; anything else content. Nothing is clicked.
profileA returning visitor: Camoufox loads the site once with a new profile, the profile is saved, and a second session with it loads the site again.
LAB_SITES_KASADA_AWSWAFThe four URLs come from the environment, so the published programs don't name the sites; set your own to repeat the measurement.

How it works

  1. For each site, take one sticky residential exit and, one session at a time, open each of the twelve setups, load the page once, wait 8 s, and read the page, the vendor signals and the document statuses.
  2. Classify what the page ended on; a network error gets one retry.
  3. Then load the site with Camoufox and a new profile, wait for the profile to be saved, load it again with the same profile and record the second visit. Delete the profile.

The code

The same program in five languages (also on GitHub, with the raw output). Set these environment variables first:

// npm install [email protected]
// env: CDPFLEET_API_KEY, LAB_SITES_KASADA_AWSWAF (comma-separated URLs of the pages to test; one load per page per setup, nothing clicked)
import { randomBytes } from 'node:crypto';
import { chromium, firefox, webkit } from 'playwright';

const KEY = process.env.CDPFLEET_API_KEY;
const RUN = randomBytes(3).toString('hex');
const SITES = process.env.LAB_SITES_KASADA_AWSWAF.split(',').map((url, i) => ({ site: String.fromCharCode(65 + i), url }));
// Every browser the fleet offers that a Playwright 1.60 client can drive (Rebrowser needs 1.52, so it's left out).
const SETUPS = [
  ['chrome_headful', 'Chrome, headful', 'chrome', chromium, false],
  ['chrome_headless', 'Chrome, headless', 'chrome', chromium, 'new'],
  ['edge', 'Edge, headful', 'edge', chromium, false],
  ['brave', 'Brave, headful', 'brave', chromium, false],
  ['opera', 'Opera, headful', 'opera', chromium, false],
  ['yandex', 'Yandex, headful', 'yandex', chromium, false],
  ['whale', 'Whale, headful', 'whale', chromium, false],
  ['chromium_headless', 'Chromium, headless', 'chromium', chromium, true],
  ['patchright', 'Patchright, headful', 'patchright', chromium, false],
  ['firefox', 'Firefox, headful', 'firefox', firefox, false],
  ['webkit', 'WebKit, headful', 'webkit', webkit, false],
  ['camoufox', 'Camoufox, headful', 'camoufox', firefox, false],
];

// What the page shows after it loaded and had 8 s to run its checks, in the lab's words. AWS WAF's
// CAPTCHA ("Let's confirm you are human") is interactive: a challenge. A near-empty page 8 s later
// (Kasada's 429 answer is a blank page with a script) or an "access denied" page is blocked.
const STATE = `(() => {
  const text = document.body ? document.body.innerText : '';
  const t = (document.title + ' ' + text.slice(0, 600)).replace(/\\s+/g, ' ');
  if (document.querySelector('#captcha-container, awswaf-captcha') || (/confirm you are human|verify you are (a )?human|are you a robot|solve the puzzle/i.test(t) && text.length < 4000)) return 'challenge';
  if (/access (to this page has been )?denied|has been blocked|you don.t have permission to access|request (unsuccessful|blocked)|too many requests/i.test(t) && text.length < 4000) return 'blocked';
  if (text.trim().length < 200) return 'blank';
  return 'content';
})()`;

const KASADA_URL = /\/ips\.js(\?|$)|\/(tl|fp)(\?|$)/;
const AWS_URL = /awswaf\.com|\/challenge\.js(\?|$)/;

async function launch(engine, headless, proxy, profile) {
  for (let attempt = 1; ; attempt++) {
    const res = await fetch(`https://starter.cdpfleet.com/${engine}/session`, {
      method: 'POST',
      headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
      body: JSON.stringify({ proxy, headless, record: false, ...(profile ? { profile } : {}) }),
    });
    if (res.ok) return (await res.json()).wsUrl;
    if (![429, 503].includes(res.status) || attempt === 5) throw new Error(`launch ${res.status} ${await res.text()}`);
    await new Promise((r) => setTimeout(r, (Number(res.headers.get('retry-after')) || 5) * 1000));
  }
}

const failed = () => ({ outcome: 'error', status: 0, final_status: 0, kasada: false, aws_waf: false, cookies: [] });

// One session, one load. Records the status of the page's first response and of the last main-frame
// document 8 s later (an interstitial that clears itself reloads the page), which vendor's scripts,
// headers or cookies showed up (cookie and header NAMES only; values are never read), and the state.
async function visit(setup, url, proxy, profile) {
  const [, , engine, type, headless] = setup;
  const browser = await type.connect(await launch(engine, headless, proxy, profile), { headers: { 'x-api-key': KEY } });
  try {
    const context = profile ? browser.contexts()[0] : await browser.newContext();
    const tab = await context.newPage();
    const seen = { kasada: false, aws_waf: false, waf_action: null, docs: [] };
    const t0 = Date.now();
    tab.on('request', (r) => {
      if (KASADA_URL.test(r.url()) || Object.keys(r.headers()).some((h) => h.startsWith('x-kpsdk'))) seen.kasada = true;
      if (AWS_URL.test(r.url())) seen.aws_waf = true;
    });
    tab.on('response', (r) => {
      const h = r.headers();
      if (Object.keys(h).some((n) => n.startsWith('x-kpsdk'))) seen.kasada = true;
      if (h['x-amzn-waf-action']) { seen.aws_waf = true; if (/^(challenge|captcha)$/.test(h['x-amzn-waf-action'])) seen.waf_action ??= h['x-amzn-waf-action']; }
      if (r.request().isNavigationRequest() && r.frame() === tab.mainFrame()) seen.docs.push([r.status(), Date.now() - t0]);
    });
    let status = 0;
    try {
      status = (await tab.goto(url, { waitUntil: 'domcontentloaded', timeout: 45000 }))?.status() ?? 0;
    } catch (err) {
      // A reset HTTP/2 connection is a refusal, not a network failure.
      return { ...failed(), outcome: /ERR_HTTP2_PROTOCOL_ERROR/.test(err.message) ? 'blocked' : 'error' };
    }
    await tab.waitForTimeout(8000);
    let outcome = await tab.evaluate(STATE).catch(() => 'error');
    const [finalStatus, finalAt] = seen.docs.at(-1) || [status, 0];
    let clearedS = null;
    // A 202/429 check that passed by itself reloads the page with a success status: cleared, even if
    // the new page hasn't rendered yet at the 8 s mark. Without that reload it never cleared.
    if (outcome === 'content' || outcome === 'blank') {
      if (finalStatus >= 400) outcome = 'blocked';
      else if (status >= 400 || status === 202) {
        if (seen.docs.length > 1 && finalStatus !== 202) { outcome = 'cleared'; clearedS = Math.round(finalAt / 100) / 10; } else outcome = 'blocked';
      } else if (outcome === 'blank') outcome = 'blocked';
    }
    const cookies = (await context.cookies()).map((c) => c.name).filter((n) => /^(KP_|aws-waf)/i.test(n)).sort();
    if (cookies.some((n) => /^KP_/i.test(n))) seen.kasada = true;
    if (cookies.some((n) => /^aws-waf/i.test(n))) seen.aws_waf = true;
    return { outcome, status, final_status: finalStatus, ...(clearedS != null ? { cleared_s: clearedS } : {}), kasada: seen.kasada, aws_waf: seen.aws_waf, ...(seen.waf_action ? { waf_action: seen.waf_action } : {}), cookies: [...new Set(cookies)] };
  } finally {
    await browser.close();
  }
}

async function api(method, path) {
  const res = await fetch(`https://cdpfleet.com${path}`, { method, headers: { 'x-api-key': KEY } });
  return res.json().catch(() => ({}));
}
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

// One sticky residential exit per site; its setups run one after another (one session at a time per
// site), and the sites run side by side. A network error gets one more try.
async function site({ site, url }) {
  const proxy = `cdpfleet-resi-country-us-session-c77${RUN}${site}-lifetime-30`;
  const results = {};
  for (const setup of SETUPS) {
    let r = await visit(setup, url, proxy).catch(failed);
    if (r.outcome === 'error') r = await visit(setup, url, proxy).catch(failed);
    results[setup[0]] = r;
  }
  // A returning visitor: Camoufox with a profile, a first visit and then a second session.
  const name = `case77-${RUN}-${site}`;
  const camoufox = SETUPS.find((s) => s[0] === 'camoufox');
  await visit(camoufox, url, proxy, name).catch(() => null);
  for (let j = 0; j < 60 && (await api('GET', '/v1/me/profiles')).profiles?.find((p) => p.name === name)?.in_use !== false; j++) await sleep(2000);
  results.camoufox_returning = await visit(camoufox, url, proxy, name).catch(failed);
  await api('DELETE', `/v1/me/profiles/${name}`);
  return { site, results };
}

const sites = await Promise.all(SITES.map(site));
console.log(JSON.stringify({ measured_at: new Date().toISOString().slice(0, 10), setups: Object.fromEntries([...SETUPS.map((s) => [s[0], s[1]]), ['camoufox_returning', 'Camoufox, returning profile (2nd visit)']]), sites }, null, 2));

What we got

SetupSite A, a footwear retailer (Kasada)Site B, a property portal (Kasada)Site C, a travel-booking site (AWS WAF)Site D, a transit-app site (AWS WAF)Measured
Chrome, headfulblocked (429)cleared (429 → 200) · 7.4 scleared (202 → 200) · 3.4 serror2026-10-30
Chrome, headlessblocked (429)blocked (429)cleared (202 → 200) · 4.8 sblocked (202 → 403)2026-10-30
Edge, headfulblocked (429)blocked (429)cleared (202 → 200) · 3.9 scleared (202 → 200) · 4.6 s2026-10-30
Brave, headfulblocked (429)cleared (429 → 200) · 7.8 scleared (202 → 200) · 3.1 scleared (202 → 200) · 4.9 s2026-10-30
Opera, headfulblocked (429)blocked (429)cleared (202 → 200) · 3.4 scleared (202 → 200) · 4.6 s2026-10-30
Yandex, headfulblocked (429)blocked (429)cleared (202 → 200) · 5.2 scleared (202 → 200) · 4.6 s2026-10-30
Whale, headfulblocked (429)blocked (429)cleared (202 → 200) · 5.1 scleared (202 → 200) · 4.7 s2026-10-30
Chromium, headlessblocked (429)blocked (429)cleared (202 → 200) · 4.3 sblocked (202 → 403)2026-10-30
Patchright, headfulblocked (429)blocked (429)cleared (202 → 200) · 5.1 scleared (202 → 200) · 4.6 s2026-10-30
Firefox, headfulblocked (429)blocked (429)cleared (202 → 200) · 4.4 scleared (202 → 200) · 4.8 s2026-10-30
WebKit, headfulblocked (429)blocked (429)cleared (202 → 200) · 5.8 scleared (202 → 200) · 4.6 s2026-10-30
Camoufox, headfulcleared (429 → 200) · 3.9 sblocked (429)cleared (202 → 200) · 3.9 scleared (202 → 200) · 4.5 s2026-10-30
Camoufox, returning profile (2nd visit)content (200)content (200)errorcontent (200)2026-10-30

From the Node.js run on 2026-10-30. IP addresses are replaced with placeholders (203.0.113.x); equal addresses stay equal. The other languages produced the same findings.

Raw output (Node.js)
{
  "measured_at": "2026-10-30",
  "setups": {
    "chrome_headful": "Chrome, headful",
    "chrome_headless": "Chrome, headless",
    "edge": "Edge, headful",
    "brave": "Brave, headful",
    "opera": "Opera, headful",
    "yandex": "Yandex, headful",
    "whale": "Whale, headful",
    "chromium_headless": "Chromium, headless",
    "patchright": "Patchright, headful",
    "firefox": "Firefox, headful",
    "webkit": "WebKit, headful",
    "camoufox": "Camoufox, headful",
    "camoufox_returning": "Camoufox, returning profile (2nd visit)"
  },
  "sites": [
    {
      "site": "A",
      "results": {
        "chrome_headful": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "chrome_headless": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "edge": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "brave": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "opera": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "yandex": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "whale": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "chromium_headless": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "patchright": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "firefox": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "webkit": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "camoufox": {
          "outcome": "cleared",
          "status": 429,
          "final_status": 200,
          "cleared_s": 3.9,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        },
        "camoufox_returning": {
          "outcome": "content",
          "status": 200,
          "final_status": 200,
          "kasada": true,
          "aws_waf": false,
          "cookies": []
        }
      }
    },
    {
      "site": "B",
      "results": {
        "chrome_headful": {
          "outcome": "cleared",
          "status": 429,
          "final_status": 200,
          "cleared_s": 7.4,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "chrome_headless": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "edge": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "brave": {
          "outcome": "cleared",
          "status": 429,
          "final_status": 200,
          "cleared_s": 7.8,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "opera": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "yandex": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "whale": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "chromium_headless": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "patchright": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "firefox": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "webkit": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "camoufox": {
          "outcome": "blocked",
          "status": 429,
          "final_status": 429,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        },
        "camoufox_returning": {
          "outcome": "content",
          "status": 200,
          "final_status": 200,
          "kasada": true,
          "aws_waf": false,
          "cookies": [
            "KP_UIDz",
            "KP_UIDz-ssn"
          ]
        }
      }
    },
    {
      "site": "C",
      "results": {
        "chrome_headful": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 3.4,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "chrome_headless": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.8,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "edge": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 3.9,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "brave": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 3.1,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "opera": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 3.4,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "yandex": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 5.2,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "whale": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 5.1,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "chromium_headless": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.3,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "patchright": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 5.1,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "firefox": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.4,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "webkit": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 5.8,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "camoufox": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 3.9,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        },
        "camoufox_returning": {
          "outcome": "error",
          "status": 0,
          "final_status": 0,
          "kasada": false,
          "aws_waf": false,
          "cookies": []
        }
      }
    },
    {
      "site": "D",
      "results": {
        "chrome_headful": {
          "outcome": "error",
          "status": 0,
          "final_status": 0,
          "kasada": false,
          "aws_waf": false,
          "cookies": []
        },
        "chrome_headless": {
          "outcome": "blocked",
          "status": 202,
          "final_status": 403,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "edge": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.6,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "brave": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.9,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "opera": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.6,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "yandex": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.6,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "whale": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.7,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "chromium_headless": {
          "outcome": "blocked",
          "status": 202,
          "final_status": 403,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "patchright": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.6,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "firefox": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.8,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "webkit": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.6,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "camoufox": {
          "outcome": "cleared",
          "status": 202,
          "final_status": 200,
          "cleared_s": 4.5,
          "kasada": false,
          "aws_waf": true,
          "waf_action": "challenge",
          "cookies": [
            "aws-waf-token"
          ]
        },
        "camoufox_returning": {
          "outcome": "content",
          "status": 200,
          "final_status": 200,
          "kasada": false,
          "aws_waf": true,
          "cookies": [
            "aws-waf-token"
          ]
        }
      }
    }
  ]
}

Takeaways