Was this helpful?
How to bypass GeeTest v4 on Hoyoverse
Technical engineer
The Hoyoverse website (account.hoyoverse.com) uses the GeeTest v4 form for protection. The main feature of this captcha implementation on this site is the mandatory presence of the dynamic risk_type parameter.
This parameter is generated with every captcha load request, is valid for a single use only, and has a short lifespan. If you try to use an old risk_type or skip it, the solution will not be accepted. In this guide, we will break down how to correctly extract all necessary parameters and send the task via API.
Task Parameters
To solve GeeTest v4, you must use the geetest_v4 method.
| Parameter | Type | Required | Description |
|---|---|---|---|
| method | String | Yes | Must be set to geetest_v4 |
| captcha_id | String | Yes | Static captcha identifier of the website |
| pageurl | String | Yes | Full URL of the page where the captcha is located |
| risk_type | String | Yes | Dynamic parameter obtained from the captcha load request |
| json | Integer | No | Set to 1 to get the response in JSON format |
How to find parameters
Since risk_type is dynamic, it cannot be simply copied from the page source code. It must be intercepted from the network request at the moment the captcha is initialized.
- Open the site https://account.hoyoverse.com/ in your browser.
- Press F12 to open Developer Tools (DevTools) and go to the Network tab.
- Enable Preserve log, in case the page reloads.
- Perform the action that triggers the captcha (e.g., start the login or registration process).
- In the Network tab filter, type load or gcaptcha4.
- Find the GET request to an address similar to:
https://gcaptcha4.geetest.com/load?callback=geetest_...&captcha_id=370be92975ddbfb1db5bc6aa64c7dfae&...&risk_type=slide|1786624661.017822|40124b10a3d945c7aa301ca38e94567c|8bd35df9a93bc9141838c1a086f32587feca335233f167878c83d6a1741ccbc9 - Click on this request and check its Query String Parameters or Payload.
- Copy the values of the captcha_id and risk_type parameters.
Important: The value of risk_type looks like a string separated by vertical bars (for example, slide|1786624661.017822|hash1|hash2). You must copy it entirely. URL-encoded characters (for example, %7C) will be automatically decoded by the browser into |.
Code Examples
cURL
Example of sending a task via command line. Replace key with your real API key.
bash
curl -X POST 'https://api.2captcha.com/in.php' \
-d 'key=YOUR_API_KEY' \
-d 'method=geetest_v4' \
-d 'captcha_id=370be92975ddbfb1db5bc6aa64c7dfae' \
-d 'pageurl=https://account.hoyoverse.com/' \
-d 'risk_type=slide|1786624309.063893|db6954184c18499d9402db6caa497e25|db6c2c6d8e2babd6f11edff49ded4a9f43a19a8cf66cc5eee0f356c073eb57c9' \
-d 'json=1'
Python + requests
Full example in Python, including task creation and polling loop until the result is obtained.
python
import requests
import time
API_KEY = 'YOUR_API_KEY'
CAPTCHA_ID = '370be92975ddbfb1db5bc6aa64c7dfae'
PAGE_URL = 'https://account.hoyoverse.com/'
# Value obtained from the network request (vertical bars |)
RISK_TYPE = 'slide|1786624309.063893|db6954184c18499d9402db6caa497e25|db6c2c6d8e2babd6f11edff49ded4a9f43a19a8cf66cc5eee0f356c073eb57c9'
# 1. Sending the task
url = 'https://api.2captcha.com/in.php'
payload = {
'key': API_KEY,
'method': 'geetest_v4',
'captcha_id': CAPTCHA_ID,
'pageurl': PAGE_URL,
'risk_type': RISK_TYPE,
'json': 1
}
response = requests.post(url, data=payload)
result = response.json()
if result.get('status') == 1:
task_id = result.get('request')
print(f"Task created, ID: {task_id}")
# 2. Waiting for the solution
res_url = 'https://api.2captcha.com/res.php'
while True:
time.sleep(5) # Pause between requests
res_params = {
'key': API_KEY,
'action': 'get',
'id': task_id,
'json': 1
}
res_response = requests.get(res_url, params=res_params).json()
if res_response.get('status') == 1:
print("Captcha solved successfully!")
print(f"Result: {res_response.get('request')}")
break
elif res_response.get('request') == 'CAPCHA_NOT_READY':
continue
else:
print(f"Error getting result: {res_response.get('request')}")
break
else:
print(f"Task creation error: {result.get('request')}")
How to Use the Received Tokens
When the API returns a successful response for GeeTest v4, it provides a JSON object containing four crucial fields: lot_number, pass_token, gen_time, and captcha_output.
To make the target website accept the solution, you must inject these values exactly as the real widget would. There are two common ways websites handle this:
- Hidden Form Fields: The site may automatically read these values from hidden inputs before submission. You need to create or update inputs with the exact names: lot_number, pass_token, gen_time, and captcha_output.
- JavaScript Callback: Many modern implementations use a callback function to process the result. You can trigger it manually via browser automation tools (like Playwright or Selenium) by executing a script similar to this:
javascript
// Example of injecting tokens via JavaScript
const tokens = {
lot_number: "YOUR_LOT_NUMBER",
pass_token: "YOUR_PASS_TOKEN",
gen_time: "YOUR_GEN_TIME",
captcha_output: "YOUR_CAPTCHA_OUTPUT"
};
// 1. Inject into hidden fields (if the site uses them)
for (const [key, value] of Object.entries(tokens)) {
let input = document.querySelector(`input[name="${key}"]`);
if (!input) {
input = document.createElement("input");
input.type = "hidden";
input.name = key;
document.body.appendChild(input);
}
input.value = value;
}
// 2. Trigger the callback (replace 'onCaptchaSuccess' with the actual function name used by the site)
if (typeof window.onCaptchaSuccess === "function") {
window.onCaptchaSuccess(tokens);
}
Note: You must inspect the target website's source code to find the exact name of the callback function they use (often found near the initGeetest4 initialization).
Testing in Sandbox Mode
Before integrating the solution into your production code, it is highly recommended to test the correctness of your parameters using the 2Captcha Sandbox.
The Sandbox allows you to verify if you have gathered all the necessary captcha parameters correctly, without needing to run a full automation cycle on the actual website.
How the Sandbox works:
-
Send the request: First, send the task via the API using the parameters you extracted from the target website (
captcha_id,risk_type,pageurl, etc.). Make sure to replace your regular API key with the Sandbox API key (which can be found in your settings: https://2captcha.com/setting#sandbox). -
Switch to Worker mode: After sending the task, open the Sandbox interface and switch the mode to "Worker".
-
Receive the captcha: In this mode, you will personally receive the task you just submitted. The Sandbox will display the captcha exactly as a real human worker would see it.
-
Verify the result:
- If the captcha loads correctly and you are able to solve it, it means all your parameters (especially
risk_type) were passed correctly. - If the captcha fails to load or displays an error, it indicates a problem with your parameters (e.g., an expired
risk_type, or an incorrectcaptcha_idorpageurl).
- If the captcha loads correctly and you are able to solve it, it means all your parameters (especially
This method allows you to quickly debug your parameter extraction process and ensure that your automation will function correctly on the live website.
Common Errors and Solutions
| Error / Problem | Cause | Solution |
|---|---|---|
| ERROR_CAPTCHA_UNSOLVABLE or captcha not solved | The risk_type parameter has expired or was reused. | Intercept risk_type from the network request again before every new solving attempt. It is single-use. |
| ERROR_BAD_PARAMETERS | The risk_type parameter is missing from the API request or passed with a typo. | Make sure the parameter key in the request is spelled exactly as risk_type. |
| CAPCHA_NOT_READY for too long | Servers need more time to process the GeeTest v4 task. | Increase the polling interval to 7-10 seconds. This is normal behavior for complex captchas. |
| Website does not accept the received token | The token was received successfully but not injected into the form correctly. | If you are using browser automation, make sure you inject all returned fields (lot_number, pass_token, gen_time, captcha_output) and trigger the corresponding website JavaScript callback. |
Useful Links
- API testing sandbox: https://2captcha.com/setting#sandbox
- GeeTest API documentation: https://2captcha.com/api-docs/geetest
- Python SDK on GitHub: https://github.com/2captcha/2captcha-python
- Other examples of bypassing captchas on websites: https://2captcha.com/h?category=sites