GeeTest
GeeTest has two live generations. v4 is keyed by a single captchaId; v3 uses a gt key plus a short-lived challenge. Both share the same task type, so the parameters you send decide which path runs.
v3 vs. v4
v4 is the modern widget: pass a captchaId and get back captcha_id, lot_number, pass_token, and gen_time. v3 is the older flow: pass the gt key and the per-load challenge, and get back challenge, validate, and seccode. Look at how the site initialises the widget: initGeetest4 means v4, initGeetest with a gt means v3.
GeeTest v4
proxy optionalThe current GeeTest generation. Identified by a captchaId rather than a gt/challenge pair. Use the proxy variant (proxyType/proxyAddress/proxyPort) when the widget is IP-scored.
GeeTestTaskProxyLessGeeTestTaskwebsiteURL*The page the GeeTest widget is on.captchaId*The v4 captcha id passed to initGeetest4.riskTypeBound flow selector: one of icon, ts, tok, or hmac. Forward the site's value verbatim.solution with captcha_id, lot_number, pass_token, and gen_time. Submit these fields back to the site.
For signed v4 flows the site issues a specific riskType. Forward it exactly as received. A wrong or missing value returns "illegal risk_type".
GeeTest v3
proxy optionalThe legacy generation, identified by a gt key and a per-load challenge string. Same task type as v4, but you supply gt + challenge instead of captchaId.
GeeTestTaskProxyLessGeeTestTaskwebsiteURL*The page the GeeTest widget is on.gt*The v3 public gt key.challenge*The per-load challenge value the site fetches before rendering.solution with challenge, validate, and seccode. Submit these fields back to the site.
The v3 challenge is single-use and expires quickly. Fetch it immediately before creating the task.
Example
A minimal v4 task body:
{
"clientKey": "capzy_YOUR_KEY",
"task": {
"type": "GeeTestTaskProxyLess",
"websiteURL": "https://example.com/login",
"captchaId": "e392e1d7fdf9d0d5a2a01e7e3c9c1a4d"
}
}riskType (icon, ts, tok, or hmac) to the session. It must be forwarded exactly as the site produced it. Altering or omitting it returns “illegal risk_type”.See Using proxies for the proxy fields, and Getting the result for the polling loop that returns solution.