What is AWS WAF Captcha?
AWS WAF Captcha is Amazon's bot detection on sites using AWS Web Application Firewall. When the WAF rule escalates a request, the customer's browser is served an interstitial page containing a window.gokuProps object (key, iv, context) and a challenge.js script that performs a proof-of-work + encrypted fingerprint round-trip back to the WAF token endpoint. We ship two task types: - AntiAwsWafTask* — the token flow. You hit the WAF interstitial in your own scraper once, extract the four gokuProps fields, and pass them to us. We do the proof-of-work + encrypted payload assembly server-side and return a valid aws-waf-token in 1-3 seconds. No browser on our side. - AwsWafClassification — image-grid only. When the WAF escalates to a 9-tile pick challenge ("select all chairs", "select all bags", etc.), submit the base64 tiles + question code and we return the matching indices in under 3 seconds. You keep your own browser session.
How it works
Send Task
POST your AntiAwsWafTask with the target URL and sitekey to our API. We'll queue it instantly.
We Solve
AntiAwsWafTask*: Capzy's proprietary solver handles the AWS WAF token and image-grid challenges end-to-end and returns the aws-waf-token cookie. AwsWafClassification: classification-only mode — submit the 9 base64 tiles + question code (e.g. aws:grid:chair) and we return the matching indices. You keep your own browser session.
Get Token
Poll getTaskResult — when status is 'ready', the solution contains the token to inject into the target page.
Quick integration
import requests, time
API = "https://api.capzy.ai"
KEY = "capzy_your_key_here"
# Step 1: Create task
task = requests.post(f"{API}/createTask", json={
"clientKey": KEY,
"task": {
"type": "AntiAwsWafTask",
"proxyPort": "8080",
"proxyType": "http",
"proxyLogin": "user",
"websiteURL": "https://example.com/protected-page",
"proxyAddress": "123.45.67.89",
"proxyPassword": "pass"
}
}).json()
task_id = task["taskId"]
print(f"Task created: {task_id}")
# Step 2: Poll for result
while True:
result = requests.post(f"{API}/getTaskResult", json={
"clientKey": KEY,
"taskId": task_id
}).json()
if result["status"] == "ready":
print("Solved!", result["solution"])
break
elif result["status"] == "failed":
print("Failed:", result.get("errorDescription"))
break
time.sleep(1)
# Step 3: Use the result — paste the token into the site's captcha form field
token = result["solution"]["token"]
# Browser side: set the textarea value or the hidden input. Then submit.
# Server-to-server: post the token alongside the form fields you normally send.
resp = requests.post("https://target.example.com/submit", data={
"username": "...",
"captcha_response": token, # <-- replace with the field name your site uses
})
print(resp.status_code)Task parameters
typetypestringreqyesAntiAwsWafTaskProxyLess or AntiAwsWafTask (token flow), or AwsWafClassification (image-only)websiteURLtypestringreqyesURL of the page that triggered the AWS WAF challengeawsKeytypestringreqnowindow.gokuProps.key extracted from the WAF interstitial. Pass with awsIv + awsContext + awsChallengeJS for the 1-3 second fast path.awsIvtypestringreqnowindow.gokuProps.iv from the WAF interstitialawsContexttypestringreqnowindow.gokuProps.context from the WAF interstitialawsChallengeJStypestringreqnoFull URL of the challenge.js <script src=...> tag on the WAF page, e.g. https://xxxx.token.awswaf.com/abc/challenge.jsuserAgenttypestringreqnoOptional. Defaults to a current Chrome desktop UA.imagestypestring[]reqnoAwsWafClassification only — array of base64-encoded grid tile images (typically 9)questiontypestringreqnoAwsWafClassification only — the target label, e.g. "aws:grid:chair", "aws:grid:bag", "aws:grid:spoon"proxyTypetypestringreqyesProxy protocol: http or httpsproxyAddresstypestringreqyesProxy IP address or hostnameproxyPorttypenumberreqyesProxy port numberproxyLogintypestringreqnoProxy username (if auth required)proxyPasswordtypestringreqnoProxy password (if auth required)userAgenttypestringreqyesUser-Agent string to use. Must match the UA you use when submitting the tokenSolution response
tokentypestringAWS WAF challenge token. Drop into the `aws-waf-token` cookie or POST it as `wafToken` to your AWS WAF–protected endpoint. Token is bound to the IP that solved it.Example response
Full getTaskResult response shape. The fields in the table above describe what's inside solution — the outer envelope (errorId, status) is identical for every captcha type.
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "0.AbCdEf...long_aws_waf_token_string..._endsHere"
}
}Error response
Failures use the same envelope with errorId: 1 plus errorCode + errorDescription. See the error-code reference for the full list.
{
"errorId": 1,
"errorCode": "ERROR_CAPTCHA_UNSOLVABLE",
"errorDescription": "Solver gave up — automatically refunded."
}Pending response
While the solver is still working, getTaskResult returns status: "processing". Poll every 1–2 seconds until ready or failed.
{
"errorId": 0,
"status": "processing"
}Features
task types
required: AntiAwsWafTask