Quick start
The full path from key to token. All you need is Python or Node.js and a few minutes.
#Step 1. Key and balance
Open the bot, press Start, then My key and Top up. For details, see Getting started.
to create a task, your balance must be at least the price of one task, see Pricing and limits.
#Step 2. Check your key
The getBalance method is free and immediately shows that your key works.
curl -X POST https://api.tokenwave.org/getBalance \
-H "Content-Type: application/json" \
-d '{"clientKey": "YOUR_API_KEY"}'
import requests
print(requests.post("https://api.tokenwave.org/getBalance", json={"clientKey": "YOUR_API_KEY"}).json())
const res = await fetch("https://api.tokenwave.org/getBalance", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: "YOUR_API_KEY" }),
}).then((r) => r.json());
console.log(res);
Expected response: { "errorId": 0, "balance": 5.0 }. If you get ERROR_KEY_DOES_NOT_EXIST, check your key.
#Step 3. Get the page parameters, create a task, and wait for the token
The script does everything at once: it takes gid, sitekey and cookies from the Steam sign-up page, creates a task, and polls for the result.
import time
import requests
API = "https://api.tokenwave.org"
KEY = "YOUR_API_KEY"
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
JOIN = "https://store.steampowered.com/join/"
def call(method, payload):
r = requests.post(f"{API}/{method}", json={"clientKey": KEY, **payload}, timeout=30).json()
if r.get("errorId"):
raise RuntimeError(r.get("errorCode"))
return r
# 1. Steam page parameters: two requests in one session
s = requests.Session()
s.headers["User-Agent"] = UA
s.get(JOIN, timeout=20)
ref = s.post(JOIN + "refreshcaptcha/", data={"hcaptcha": 1, "count": 1}, timeout=20, headers={
"X-Requested-With": "XMLHttpRequest",
"Origin": "https://store.steampowered.com",
"Referer": JOIN,
}).json()
cookies = "; ".join(f"{k}={v}" for k, v in s.cookies.get_dict().items())
# 2. create the task
task_id = call("createTask", {"task": {
"type": "HCaptchaTask",
"websiteURL": JOIN,
"websiteKey": ref["sitekey"],
"data": ref["gid"],
"isInvisible": True,
"userAgent": UA,
"cookies": cookies,
"fallbackToActualUA": True,
}})["taskId"]
# 3. wait for the solution (up to 2 minutes)
deadline = time.time() + 120
while time.time() < deadline:
time.sleep(3)
res = call("getTaskResult", {"taskId": task_id})
if res["status"] == "ready":
token = res["solution"]["gRecaptchaResponse"]
print("token:", token[:40], "…") # use it in your Steam request within 60 seconds
break
else:
raise RuntimeError("TIMEOUT")
const API = "https://api.tokenwave.org";
const KEY = "YOUR_API_KEY";
const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36";
const JOIN = "https://store.steampowered.com/join/";
async function call(method, payload) {
const r = await fetch(`${API}/${method}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: KEY, ...payload }),
}).then((r) => r.json());
if (r.errorId) throw new Error(r.errorCode);
return r;
}
// 1. Steam page parameters: two requests in one session
const page = await fetch(JOIN, { headers: { "User-Agent": UA } });
const cookies = page.headers.getSetCookie().map((c) => c.split(";")[0]).join("; ");
const ref = await fetch(JOIN + "refreshcaptcha/", {
method: "POST",
headers: {
"User-Agent": UA,
Cookie: cookies,
"Content-Type": "application/x-www-form-urlencoded",
"X-Requested-With": "XMLHttpRequest",
Origin: "https://store.steampowered.com",
Referer: JOIN,
},
body: "hcaptcha=1&count=1",
}).then((r) => r.json());
// 2. create the task
const { taskId } = await call("createTask", {
task: {
type: "HCaptchaTask",
websiteURL: JOIN,
websiteKey: ref.sitekey,
data: ref.gid,
isInvisible: true,
userAgent: UA,
cookies,
fallbackToActualUA: true,
},
});
// 3. wait for the solution (up to 2 minutes)
const deadline = Date.now() + 120000;
while (Date.now() < deadline) {
await new Promise((r) => setTimeout(r, 3000));
const res = await call("getTaskResult", { taskId });
if (res.status === "ready") {
console.log("token:", res.solution.gRecaptchaResponse.slice(0, 40), "…"); // use it in your Steam request within 60 seconds
break;
}
}
#Step 4. Use the token
The gRecaptchaResponse token is single-use and valid for 60 seconds. Pass it in your Steam request within the same session in which you got the gid: with the same cookies, userAgent and IP.
#Pre-launch checklist
- the key is active and the balance is at least the price of one task;
userAgent,cookiesand IP (proxy) belong to one session;gidis fresh: obtained right before creating the task;- the result is polled no more often than once every 2–3 seconds;
- the token is used within 60 seconds;
- on
ERROR_CAPTCHA_UNSOLVABLE, take a newgidinstead of repeating the old task.
#What's next
- All task and response fields are in Task types.
- How a task goes from creation to result is in Task lifecycle.
- What each error means is in Error codes.