AWS WAF Captcha

Solve AWS WAF challenges automatically with our API

Overview

AWS WAF (Web Application Firewall) uses JavaScript challenges to protect websites. Our API solves these challenges and returns the required cookie token.

Supported Task Types

Task TypeProxy RequiredDescription
AntiAwsWafTaskProxyLessNoWeb challenge — uses our built-in proxy infrastructure
AntiAwsWafTaskYesWeb challenge — requires your own proxy
AntiAwsWafMobileTaskNoMobile app token — minted by the genuine AWS WAF mobile SDK on real devices. No URL, parameters, or proxy. See Mobile App Token.

Create Task

Endpoint: POST /createTask

Request Parameters

ParameterTypeRequiredDescription
clientKeyStringYesYour API key
task.typeStringYesAntiAwsWafTaskProxyLess or AntiAwsWafTask
task.websiteURLStringYesTarget page URL with WAF protection
task.awsChallengeJSStringNoURL of the challenge.js script
task.awsApiJsStringNoURL of the jsapi.js script (CAPTCHA flow)
task.awsKeyStringNoThe key value from captcha page
task.awsIvStringNoThe iv value from captcha page
task.awsContextStringNoThe context value from captcha page
task.awsProblemUrlStringNoThe problem endpoint URL
task.awsApiKeyStringNoThe api_key value
task.awsExistingTokenStringNoPrevious aws-waf-token for refresh
task.proxyStringNoProxy (required for AntiAwsWafTask). See Proxy Format

Response

{
  "errorId": 0,
  "taskId": "61138bb6-19fb-11ec-a9c8-0242ac110006"
}

Get Task Result

Endpoint: POST /getTaskResult

Request

{
  "clientKey": "YOUR_API_KEY",
  "taskId": "61138bb6-19fb-11ec-a9c8-0242ac110006"
}

Response (Ready)

{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "cookie": "aws-waf-token=xxxxxxxx...",
    "token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:...",
    "captchaVoucher": "eyJ...",
    "userAgent": "Mozilla/5.0 ..."
  }
}

captchaVoucher is returned only for the visual-CAPTCHA flow (Situation 4) — submit it to the Amazon CVF endpoint /aaut/verify/cvf/{jwt}. The PoW flow (challenge.js) returns just cookie + token.


Mobile App Token (AntiAwsWafMobileTask)

Some native mobile apps protect their API with the AWS WAF mobile SDK instead of the web JavaScript challenge. For these, the aws-waf-token is minted on-device by the app's genuine SDK (a PBKDF2 proof-of-work over device signals) — there is no challenge.js, no page parameters, and no proxy.

AntiAwsWafMobileTask returns a genuine, freshly-minted mobile aws-waf-token. Present it to the target API exactly as the app does — as a Cookie: aws-waf-token=<token> header.

No parameters needed

Unlike the web task types, the mobile task takes only task.type — no websiteURL, no awsChallengeJS/awsApiJs, no proxy. The token is device/PoW-based and works from your own IP.

Request

{
  "clientKey": "YOUR_API_KEY",
  "task": { "type": "AntiAwsWafMobileTask" }
}

Response (Ready)

{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:DAoA...:...",
    "cookie": "aws-waf-token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:DAoA...:...",
    "userAgent": "gyg_app/... CFNetwork/... Darwin/...",
    "captchaMethod": "mobile_sdk_pow"
  }
}

Send the returned cookie (or build the header yourself as aws-waf-token=<token>) with your request to the protected mobile API endpoint.

Fast & fresh

Mobile tokens are served from a continuously-refreshed warm pool — solves typically return in 1-3 seconds. Tokens are single-use and short-lived; request one per protected call and present it promptly.

Per-app coverage

Mobile tokens are minted per target app. Contact us to confirm or add coverage for the app you're targeting.


Parameter Situations (web challenges)

AWS WAF can be configured in different ways. Choose the situation that matches your target website.


Situation 1: Automatic Detection

When to use: You only have the website URL and want us to handle everything automatically.

Recommended approach

Auto-detection is the simplest method. Start here and only use manual parameters if auto-detection fails or you need more control.

Simply provide the websiteURL. Our system will visit the page, look for window.gokuProps (containing key, iv, context) and detect any challenge.js or jsapi.js scripts automatically.

{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/protected-page"
  }
}

Situation 2: Manual Parameters

When to use: You have extracted key, iv, context, and challenge.js URL manually.

Required parameters: awsKey, awsIv, awsContext, awsChallengeJS

How to find them:

  1. Open DevTools (F12) → Network tab
  2. Look for requests to *.token.awswaf.com
  3. Find window.gokuProps in the HTML containing key, iv, context
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/protected-page",
    "awsKey": "AQIDAHjA1234567890abcdefghijklmnop...",
    "awsIv": "a1b2c3d4e5f6g7h8",
    "awsContext": "eyJ0eXBlIjoiQ0FQVENIQSIsImNhcHRjaGFTY3JpcH...",
    "awsChallengeJS": "https://b516434d791a.aa24f28d.eu-west-1.token.awswaf.com/b516434d791a/challenge.js"
  }
}

Situation 3-1: Challenge.js Only

When to use: You can find challenge.js on the page but not the manual parameters (key, iv, context).

This is the most common scenario. The challenge.js script handles the WAF challenge (PoW token generation) automatically.

How to find it:

  1. Open DevTools → Network tab
  2. Filter by challenge.js
  3. Copy the full URL (format: https://{apiKey}.{accountId}.{region}.token.awswaf.com/{apiKey}/challenge.js)
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/protected-page",
    "awsChallengeJS": "https://b516434d791a.aa24f28d.eu-west-1.token.awswaf.com/b516434d791a/challenge.js"
  }
}

Situation 3-2: jsapi.js Only

When to use: You cannot find challenge.js on the page, but you can find jsapi.js. The challenge.js script is assembled from the code inside jsapi.js, so either URL works.

challenge.js vs jsapi.js

Both URLs point to the same WAF system. If you can only find jsapi.js in the network requests, use this situation. Our system will handle the rest.

How to find it:

  1. Open DevTools → Network tab
  2. Filter by jsapi.js
  3. Copy the full URL (format: https://{apiKey}.{accountId}.{region}.captcha.awswaf.com/{apiKey}/jsapi.js)
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/protected-page",
    "awsApiJs": "https://b516434d791a.aa24f28d.eu-west-1.captcha.awswaf.com/b516434d791a/jsapi.js"
  }
}

Situation 4: Problem URL (Visual CAPTCHA)

When to use: You have the problem endpoint URL containing CAPTCHA configuration. This is used for visual CAPTCHA challenges (e.g., grid image selection).

The problem URL contains information about the visual CAPTCHA type and required solutions.

How to find it:

  1. Open DevTools → Network tab
  2. Filter by problem
  3. Look for URLs like: https://xxx.captcha.awswaf.com/xxx/problem?kind=visual&...
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/protected-page",
    "awsProblemUrl": "https://xxx.us-east-1.captcha.awswaf.com/xxx/problem?kind=visual&domain=example.com&problem=gridcaptcha-5-0.15-0&num_solutions_required=2"
  }
}

Optional: awsApiJs

You can optionally include awsApiJs alongside awsProblemUrl for faster solving, but it is not required.


Situation 5: Token Refresh (Secondary Verification)

When to use: You need to upgrade an existing token for higher security operations (SignUp, checkout, etc.). The problem endpoint typically contains an api_key value that is constant per website.

Some protected actions require a "fresh" token even if you already have a valid one.

Required parameters: awsExistingToken + awsApiJs or awsChallengeJS (whichever is available on the page)

Optional: awsApiKey - the api_key value found in the problem endpoint URL

{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/signup",
    "awsApiJs": "https://xxx.captcha.awswaf.com/xxx/jsapi.js",
    "awsApiKey": "your_api_key_value",
    "awsExistingToken": "aws-waf-token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:..."
  }
}

Or with challenge.js:

{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "AntiAwsWafTaskProxyLess",
    "websiteURL": "https://example.com/signup",
    "awsChallengeJS": "https://xxx.token.awswaf.com/xxx/challenge.js",
    "awsExistingToken": "aws-waf-token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:..."
  }
}

How to Find the Right Parameters

challenge.js vs jsapi.js - which one do I need?

Use awsChallengeJS (challenge.js) for basic page access. Use awsApiJs (jsapi.js) for protected actions like sign up, checkout, or form submissions that require CAPTCHA-level validation.

Step-by-step Guide

  1. Open the target page in Chrome with DevTools (F12) → Network tab
  2. Filter by awswaf to find requests to *.awswaf.com domains
  3. Identify the script URLs:
What you seeDomain patternParameter to use
challenge.js*.token.awswaf.com or *.sdk.awswaf.comawsChallengeJS
jsapi.js*.captcha.awswaf.com or *.captcha-sdk.awswaf.comawsApiJs
  1. Copy the full URL and use it in your task payload along with websiteURL

Which parameter should I use?

Your goalParameterWhy
Access a protected pageawsChallengeJSPage loads only need a PoW (Proof of Work) token
Sign up / Create accountawsApiJsSign up endpoints typically require a CAPTCHA-validated token
Checkout / PurchaseawsApiJsPayment flows usually require CAPTCHA-level validation
LoginEither worksTry awsChallengeJS first - use awsApiJs if you get a 405 response
Not sureawsApiJsCAPTCHA tokens work everywhere, PoW tokens may be rejected on protected actions

Tip

If both URLs are available on the page, you can provide both awsChallengeJS and awsApiJs in the same request. Our system will use the optimal combination.


How to Identify AWS WAF

Signs that a website uses AWS WAF:

IndicatorWhere to Look
Cookie nameaws-waf-token in browser cookies
Network requestsRequests to *.token.awswaf.com, *.captcha.awswaf.com, *.sdk.awswaf.com, or *.captcha-sdk.awswaf.com
Scriptschallenge.js or jsapi.js from awswaf.com
Challenge pagePage asking to verify with AWS branding

DevTools Quick Check:

Network tab → Filter: "awswaf" → Look for challenge.js or jsapi.js

Code Examples

import requests
import time

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.capbypass.pro"

def solve_aws_waf(website_url, challenge_js=None, api_js=None):
    # Build task
    task = {
        "type": "AntiAwsWafTaskProxyLess",
        "websiteURL": website_url
    }
    if challenge_js:
        task["awsChallengeJS"] = challenge_js
    if api_js:
        task["awsApiJs"] = api_js

    # Create task
    response = requests.post(f"{BASE_URL}/createTask", json={
        "clientKey": API_KEY,
        "task": task
    })
    task_id = response.json()["taskId"]

    # Poll for result
    while True:
        result = requests.post(f"{BASE_URL}/getTaskResult", json={
            "clientKey": API_KEY,
            "taskId": task_id
        }).json()

        if result["status"] == "ready":
            return result["solution"]["cookie"]

        if result.get("errorId"):
            raise Exception(result.get("errorDescription"))

        time.sleep(2)

# Usage - Situation 1 (auto-detect)
cookie = solve_aws_waf("https://example.com")

# Usage - Situation 3-1 (challenge.js)
cookie = solve_aws_waf(
    "https://example.com",
    challenge_js="https://xxx.token.awswaf.com/xxx/challenge.js"
)

# Usage - Situation 3-2 (jsapi.js)
cookie = solve_aws_waf(
    "https://example.com",
    api_js="https://xxx.captcha.awswaf.com/xxx/jsapi.js"
)
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.capbypass.pro';

async function solveAwsWaf({ websiteURL, awsChallengeJS, awsApiJs }) {
  // Build task
  const task = {
    type: 'AntiAwsWafTaskProxyLess',
    websiteURL
  };
  if (awsChallengeJS) task.awsChallengeJS = awsChallengeJS;
  if (awsApiJs) task.awsApiJs = awsApiJs;

  // Create task
  const createRes = await fetch(`${BASE_URL}/createTask`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ clientKey: API_KEY, task })
  });
  const { taskId } = await createRes.json();

  // Poll for result
  while (true) {
    const resultRes = await fetch(`${BASE_URL}/getTaskResult`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clientKey: API_KEY, taskId })
    });
    const result = await resultRes.json();

    if (result.status === 'ready') {
      return result.solution.cookie;
    }

    if (result.errorId) {
      throw new Error(result.errorDescription);
    }

    await new Promise(r => setTimeout(r, 2000));
  }
}

Typical Solve Time

Flow TypeAverageMaximum
PoW (challenge.js)5-15 seconds60 seconds
CAPTCHA (jsapi.js)10-30 seconds120 seconds

Error Codes

Error CodeDescription
ERROR_KEY_DOES_NOT_EXISTInvalid API key
ERROR_ZERO_BALANCEInsufficient balance
ERROR_CAPTCHA_UNSOLVABLEChallenge could not be solved
ERROR_TASK_NOT_FOUNDTask ID not found
ERROR_INVALID_TASK_DATAMissing or invalid parameters
ERROR_PROXY_NOT_DEFINEDProxy required for a non-ProxyLess task type — use the ProxyLess variant or supply task.proxy
ERROR_PROXY_CONNECTION_FAILEDCould not connect through your proxy (refused, unreachable, or bad credentials) - check the proxy is alive and reachable
ERROR_PROXY_BANNEDThe target blocked your proxy IP (datacenter or flagged) - use a residential or mobile proxy
ERROR_INVALID_DEVELOPER_KEYThe provided developerKey is invalid or disabled
ERROR_WRONG_TASK_TYPEWrong task type for this site (e.g., standard vs enterprise)
ERROR_TIMEOUTTask exceeded timeout
ERROR_TASK_QUEUE_FULLServer is at capacity — retry in a few seconds
ERROR_TASK_TYPE_COMING_SOONTask type is not yet available
ERROR_TASK_TYPE_INACTIVETask type is currently disabled
ERROR_WORKER_CRASHEDSolver process exited mid-solve — balance refunded, safe to retry
ERROR_INTERNALInternal server error

Next Steps

On this page