GigaSolve Documentation
GigaSolve handles bot protection challenges — Akamai, Cloudflare, PerimeterX, DataDome, and more. You send a task with the required parameters, we return a valid token or cookie. That's it.
Introduction
If you've never used a solver API before, start here.
Bot protection systems like Akamai, Cloudflare, and PerimeterX sit in front of websites and block automated traffic. They do this by running JavaScript in the browser that fingerprints your environment — checking things like TLS handshakes, header order, timing, and browser APIs. If you fail these checks, your request is blocked or challenged.
GigaSolve solves these challenges on your behalf. You describe the target (URL, proxy, any extra parameters the challenge needs), we run a real browser environment through the challenge, and we hand you back the token or cookie you need to pass.
You still make the actual request to the target site yourself — GigaSolve only handles the challenge part.
How it works
The full flow, from submitting a task to using the result.
- Submit a task. POST to
/v1/task/submitwith your API key and task parameters. You get back atask_idimmediately. - Poll for the result. GET
/v1/task/result/:task_idevery second. Status goesQUEUED → RUNNING → SUCCESS(orFAILED). - Use the token. When status is
SUCCESS, theresultfield contains the cookie or token. Attach it to your request and proceed. - Re-solve when needed. Most tokens are single-use or expire after a short time. Don't cache them — re-solve before each protected action.
Credits are only deducted when a task reaches SUCCESS. Failed tasks cost nothing.
Your account & API key
Register through the GigaSolve website. Your API key is emailed to you on sign-up.
Your API key looks like gs_4a3f8b2c.... It authenticates every request you make. Keep it private — anyone with your key can spend your credits.
You can view your balance, top up credits, and manage your key from your dashboard on the website. You do not need to call any API to do this.
If your key is compromised, rotate it immediately from the dashboard. The old key is invalidated the moment you generate a new one.
Quickstart
The fastest way to get a token.
import time, requests
API_KEY = "gs_your_key_here"
BASE = "https://api.gigasolve.xyz"
headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
}
# 1. Submit
resp = requests.post(f"{BASE}/v1/task/submit", headers=headers, json={
"task_type": "turnstile",
"proxy": "http://user:pass@ip:port",
"target_url": "https://peet.ws/turnstile-test/managed.html",
"site_key": "0x4AAAAAAABS7TtLxsNa7Z2e",
}).json()
task_id = resp["task_id"]
# 2. Poll
while True:
time.sleep(1)
r = requests.get(f"{BASE}/v1/task/result/{task_id}", headers=headers).json()
if r["status"] == "SUCCESS":
print("Token:", r["result"]["token"])
break
if r["status"] == "FAILED":
raise Exception(r.get("error", "task failed"))That's the entire flow. Swap out the task type and parameters for whatever you need — the polling loop stays the same for every task.
Authentication
Every request to the API requires your key in a single header.
x-api-key: gs_4a3f8b2c1d9e...There's no login flow, no tokens, no OAuth. Just send the header on every request. If it's missing or wrong, you get a 401.
Check balance
Check your remaining credit balance at any time.
GET https://api.gigasolve.xyz/v1/user/balance
x-api-key: gs_4a3f8b2c1d9e...Response
{
"ok": true,
"credits": 8420
}1000 credits = $1 USD. The API also returns 402 Payment Required when you submit a task without enough credits — so you can use this endpoint proactively to check before submitting.
Credits & pricing
1000 credits = $1 USD. Credits are deducted only on successful solves.
| Task type | Credits per solve | USD equivalent |
|---|---|---|
| akamai | 2 | $0.002 |
| sbsd | 2 | $0.002 |
| sec_cpt | 2 | $0.002 |
| kasada | 2 | $0.002 |
| kasada_cd | 2 | $0.002 |
| funcaptcha | 2 | $0.002 |
| hcaptcha | 2 | $0.002 |
| hcaptcha_pro | 14 | $0.014 |
| recaptchav3 | 2 | $0.002 |
| datadome-slider | 2 | $0.002 |
| datadome-invisible | 2 | $0.002 |
| datadome-device-check | 2 | $0.002 |
| turnstile | 2 | $0.002 |
| cloudflare_waf | 2 | $0.002 |
| aws | 2 | $0.002 |
| perimeterx_invisible | 6 | $0.006 |
| perimeterx_hold | 10 | $0.010 |
Top up via the dashboard using USDT (TRC-20 or ERC-20), Bitcoin, or Litecoin. Credits are added automatically once the payment confirms on-chain.
If a task fails — bad proxy, timeout, site changed — you are not charged. The credit check happens at submit time to verify you have enough, but the deduction only happens on SUCCESS.
Proxies
Most tasks require a proxy. The quality of your proxy directly affects your solve rate.
Use residential or mobile proxies
Datacenter IPs are well-known and blocked by most bot protection systems before the challenge even runs. Residential and mobile proxies route your traffic through real consumer IPs, which pass the initial IP reputation checks.
If you're getting consistent failures on a site that should work, try a different proxy before anything else. It's the most common cause of unexpected failures.
Supported formats
# Username + password
http://user:pass@ip:port
# No auth
http://ip:port
# SOCKS5
socks5://user:pass@ip:portIP consistency is critical
When you solve a challenge and then make the actual request to the target site, you must use the same proxy IP for both. Most bot protection systems tie the token or cookie to the originating IP. If you switch IPs between the solve and the request, the token will be rejected.
Rotating proxies (where each request gets a different IP) will not work for most task types. Use sticky sessions that keep the same IP for the duration of your workflow.
TLS & sessions
One of the most common reasons tokens fail immediately after being generated.
Modern bot protection doesn't just look at your cookies — it also inspects your TLS fingerprint and HTTP header order. If the token was generated by a browser-like environment but your request is coming from a standard Python requests client, sites like Akamai and Cloudflare can detect the mismatch and invalidate the token on first use.
What this means in practice
- Use a TLS client that mimics a real browser. In Python, curl_cffi or tls-client are the standard choices.
- Match your header order to what a real Chrome browser sends. The order matters — sites check it.
- Use the same User-Agent throughout your entire session.
- Don't mix TLS fingerprints. If you solve with one client and request with another, you'll get flagged.
Recommended Python setup
from curl_cffi import requests as curl_requests
# impersonate="chrome120" sets the correct TLS fingerprint + header order
session = curl_requests.Session(impersonate="chrome120")
# Use this session for your actual requests, not just for solving
response = session.get("https://target-site.com/", headers={
"cookie": "_abck=ABC123~0~YAAAA..." # token from GigaSolve
})GigaSolve handles the TLS configuration on our end when solving. But your subsequent requests to the target site are your responsibility — that's where most integration bugs come from.
Polling for results
Submit the task, get a task ID, poll until done.
After submitting a task you receive a task_id. Hit GET /v1/task/result/:task_id with your API key to check the status.
| Status | Meaning |
|---|---|
| QUEUED | Received, waiting to start |
| RUNNING | Currently being solved |
| SUCCESS | Solved — result is in the response |
| FAILED | Could not solve — check error for the reason |
Poll every 1 second. Most tasks complete in 5–30 seconds depending on the protection type. Tasks time out after 120 seconds and return FAILED.
Reusable polling helper
import time, requests
def solve(api_key, task_payload, timeout=120):
base = "https://api.gigasolve.xyz"
headers = {"x-api-key": api_key}
task = requests.post(f"{base}/v1/task/submit", headers=headers, json=task_payload).json()
if not task.get("ok"):
raise Exception(f"Submit error: {task.get('error')}")
deadline = time.time() + timeout
while time.time() < deadline:
time.sleep(1)
r = requests.get(f"{base}/v1/task/result/{task['task_id']}", headers=headers).json()
if r["status"] == "SUCCESS":
return r["result"]
if r["status"] == "FAILED":
raise Exception(r.get("error", "task failed"))
raise TimeoutError("task did not complete in time")Token lifetime
Tokens expire. Never cache them.
Every protection system has different rules about how long a token or cookie remains valid, but the general pattern is:
- Most tokens are single-use or near-single-use. After you perform a protected action (login, add to cart, checkout), the token is typically invalidated.
- Time-based expiry is common. Even unused tokens often expire within a few minutes.
- IP invalidation. Using a token from a different IP than the one it was solved on will invalidate it immediately on most sites.
The correct pattern is: solve → use immediately → re-solve for the next request. Don't try to reuse tokens across requests or store them for later.
A token returning as "invalid" on the target site does not mean the solver failed. In most cases it means the token expired, the wrong proxy was used, or the TLS fingerprint didn't match. Check those first before assuming a solver issue.
Errors & troubleshooting
What errors mean and what to do about them.
| HTTP status | Meaning | Fix |
|---|---|---|
| 400 | Missing or invalid parameter | Check the request body against the task type's parameter table |
| 401 | Bad or missing API key | Check the x-api-key header |
| 402 | Not enough credits | Top up from the dashboard |
| 429 | Rate limited | Max 60 requests/minute per key — add a delay between requests |
| 502 | Solver temporarily unavailable | Retry after a few seconds |
Task returned FAILED
Check the error field in the response. Common reasons:
- Proxy blocked / timeout — the proxy couldn't reach the target. Try a different proxy.
- Invalid parameters — a URL or key was wrong. Double-check what you're passing.
- Site changed — bot protection updates happen. If a task that was working suddenly fails consistently, let us know.
- Solve timeout — the challenge took longer than 120 seconds. Retry — it may succeed on the next attempt.
Token works once then stops
This is almost always one of three things: the token expired, you switched proxy IPs between the solve and the request, or your HTTP client's TLS fingerprint doesn't match what the site expects. See the TLS & sessions section.
Akamai _abck
Generates a valid _abck cookie for Akamai Bot Manager protected sites.
Akamai protects sites by running a JavaScript challenge that collects browser signals and posts them to a dynamic script endpoint. The result is an _abck cookie. Once you have a valid cookie, you can proceed to the protected action.
Finding the script URL
Fetch the protected page and look for a script tag near the bottom of <body>. It looks like this:
<script type="text/javascript" src="/WGlx/lc_w/w/vez/w0HNXw/EmubktLXh3/H34" defer></script>The path is dynamic and changes per session — parse it from the response every time, never hardcode it.
Parameters
| Field | Type | Description |
|---|---|---|
| proxy required | string | Residential proxy. Must be the same IP you use for subsequent requests. |
| target_url required | string | The protected page URL (e.g. product page, homepage). |
| akamai_js_url required | string | Full URL of the Akamai script tag, parsed from the page HTML. |
| page_fp required | string | Page fingerprint value — extracted from the page source. |
{
"task_type": "akamai",
"proxy": "http://user:pass@ip:port",
"target_url": "https://shop.lululemon.com/",
"akamai_js_url": "https://shop.lululemon.com/WGlx/lc_w/w/vez/w0HNXw/...",
"page_fp": "424541475255414d424b41585f5e50495c5148"
}Result
{ "cookie": "_abck=ABC123~0~YAAAA..." }The _abck cookie is typically invalidated after each protected action (login, add to cart, checkout). Re-solve before the next one.
Akamai sbsd / bm_sc
Handles the sbsd variant, returning a valid bm_sc cookie.
Some sites use sbsd in addition to or instead of _abck. The approach is the same — parse the script URL from the page HTML and pass it through.
{
"task_type": "sbsd",
"proxy": "http://user:pass@ip:port",
"target_url": "https://aswbe-i.ana.co.jp/...",
"sbsd_js_url": "https://aswbe-i.ana.co.jp/NAOAvP/g/p/QDWF9UmqEw/...",
"init_cookies": {
"bm_s": "your_bm_s_value",
"bm_sc": "your_bm_sc_value"
}
}| Field | Type | Description |
|---|---|---|
| sbsd_js_url required | string | Parse from the page HTML, same process as Akamai script URL. |
| init_cookies optional | object | Existing cookies from your session if you have them. |
Akamai sec_cpt
Solves the Akamai proof-of-work challenge served when your request looks suspicious.
When Akamai isn't satisfied with the browser environment, it serves a sec_cpt challenge page instead of the normal response. The challenge includes a nonce, difficulty level, and token — all of which you extract from the response and pass to GigaSolve.
{
"task_type": "sec_cpt",
"sec_cpt": "ADE36B02B21573BDBB5BFBF91F336959~1~...",
"sec_json": {
"nonce": "30cc8a4637ca...",
"difficulty": 5000,
"token": "AAQAAAAL_____...",
"count": 10,
"timestamp": 1758097163
}
}Extract sec_cpt and sec_json directly from the challenge response and pass them through without modification.
Kasada ct
Returns a valid x-kpsdk-ct token for Kasada-protected API endpoints.
Kasada protection typically runs on API calls made after the initial page load. You need the x-kpsdk-ct header to make authenticated calls to these endpoints.
{
"task_type": "kasada",
"proxy": "http://user:pass@ip:port",
"target_url": "https://arcteryx.com/",
"protected_api_domain": "arcteryx.com",
"kasada_js_domain": "arcteryx.com"
}| Field | Type | Description |
|---|---|---|
| target_url required | string | The page that loads before the protected API calls begin. |
| protected_api_domain required | string | Domain of the API endpoint that requires the Kasada token. |
| kasada_js_domain required | string | Domain serving the Kasada JS — usually the same as above. |
Kasada cd
Handles the Kasada cd variant with a different parameter set.
When hitting a Kasada-protected endpoint directly, the server may return a challenge response containing ct, st, fc, and site values. Pass these through as-is.
{
"task_type": "kasada_cd",
"ct": "0b3jqi5b3LjWE63tZoPso...",
"st": "1756879688265",
"fc": "eyJmZWF0dXJlRmxhZ3Mi...",
"site": "arcteryx"
}PerimeterX Invisible
Generates a _px3 cookie for PerimeterX-protected sites — no visible challenge.
The invisible variant runs silently in the background. You won't see a CAPTCHA page — the protection validates passively as you browse. Pass the site's PX script URL and app ID.
{
"task_type": "perimeterx_invisible",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.walmart.com/",
"perimeterx_js_url": "https://www.walmart.com/px/PXu6b0qd2S/init.js",
"pxAppId": "PXu6b0qd2S"
}| Field | Type | Description |
|---|---|---|
| perimeterx_js_url required | string | The init.js URL — look for it in the page source. |
| pxAppId required | string | The PX app ID — visible in the script URL (e.g. PXu6b0qd2S). |
PerimeterX Hold
Solves an active PerimeterX block page and returns a valid cookie to continue.
When PerimeterX has explicitly blocked your request and is showing a CAPTCHA or "Access Denied" page, use this task type. You need to provide the values from the block response.
{
"task_type": "perimeterx_hold",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.walmart.com/",
"pxvid": "84439b81-676a-11f0-b082-def9cefce6ae",
"pxuuid": "1d90e990-982a-11f0-9531-bb778ceab4d7",
"pxAppId": "PXu6b0qd2S",
"perimeterx_js_url": "https://client.px-cloud.net/PXu6b0qd2S/main.min.js",
"captcha_js_url": "https://www.walmart.com/px/PXu6b0qd2S/captcha/captcha.js",
"init_cookies": {
"pxhd": "3a72e00e1ce54a44b3d59b42a8eead42..."
}
}| Field | Type | Description |
|---|---|---|
| pxvid required | string | From the _pxvid cookie in the blocked response. |
| pxuuid required | string | From the pxuuid field in the block response body. |
| init_cookies optional | object | Any existing PX cookies in your session. |
Funcaptcha
Solves Arkose Labs challenges and returns a token. Used on Coinbase, Roblox, and others.
{
"task_type": "funcaptcha",
"proxy": "http://user:pass@ip:port",
"target_url": "https://login.coinbase.com/signup",
"custom_api_host": "ark.coinbase.com",
"public_key": "32FBE3BC-228C-4967-9D76-8B27B3EBCF08",
"blob_data": "rFZpYTN0..."
}| Field | Type | Description |
|---|---|---|
| custom_api_host required | string | The Arkose API host for this site — e.g. ark.coinbase.com. Found in the page source. |
| public_key required | string | Funcaptcha public key — a UUID found in the page source or JS. |
| blob_data optional | string | Some sites pass an additional data blob. Include it if the page sets one. |
hCaptcha
Returns a h-captcha-response token for standard hCaptcha.
{
"task_type": "hcaptcha",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.yelp.com/",
"site_key": "6660d4df-1884-4ac6-a933-e5f3bd460946"
}hCaptcha Pro
Same as hCaptcha but for enterprise / Pro tier — significantly stronger challenge, higher cost.
Same parameters as hcaptcha. Use this task type specifically when the site uses hCaptcha's enterprise tier, which has stricter bot detection. If you're not sure which tier the site uses, try hcaptcha first — if it fails consistently, switch to hcaptcha_pro.
{
"task_type": "hcaptcha_pro",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.wolt.com/",
"site_key": "85fed6af-162f-4a66-a7ab-8822a7d81f72"
}reCAPTCHA v3
Returns a scored g-recaptcha-response token. The action must match what the site expects.
reCAPTCHA v3 runs invisibly and returns a score. The token is scoped to an action — if the site expects login and you send a token generated with submit, the score won't be accepted.
{
"task_type": "recaptchav3",
"proxy": "http://user:pass@ip:port",
"target_url": "https://2captcha.com/demo/recaptcha-v3",
"site_key": "6Lcyqq8oAAAAAJE7eVJ3aZp_hnJcI6LgGdYD8lge",
"action": "demo_action",
"title": "Google reCAPTCHA V3 demo",
"enterprise": false
}| Field | Type | Description |
|---|---|---|
| action required | string | The action string the site passes to reCAPTCHA — find it in the page JS. |
| title required | string | The page <title> tag value. |
| enterprise optional | bool | Set true if the site uses reCAPTCHA Enterprise. |
Cloudflare Turnstile
Returns a cf-turnstile-response token. Turnstile runs invisibly in the page.
Turnstile is Cloudflare's managed challenge widget — it validates the browser silently and returns a token that the site submits server-side. Find the sitekey in the page source (it starts with 0x4).
{
"task_type": "turnstile",
"proxy": "http://user:pass@ip:port",
"target_url": "https://peet.ws/turnstile-test/managed.html",
"site_key": "0x4AAAAAAABS7TtLxsNa7Z2e",
"action": "login"
}| Field | Type | Description |
|---|---|---|
| site_key required | string | Found in the page source — starts with 0x4. |
| action optional | string | The action name if the page passes one to the widget. |
Cloudflare WAF
Bypasses the Cloudflare managed challenge interstitial and returns a cf_clearance cookie.
When Cloudflare shows a "Checking your browser..." interstitial page before the real content, this task type handles it. The returned cf_clearance cookie lets you access the site directly.
{
"task_type": "cloudflare_waf",
"proxy": "http://user:pass@ip:port",
"target_url": "https://pastebin.com/login",
"target_method": "GET"
}Cloudflare ties cf_clearance to the IP it was issued for. You must use the exact same proxy for all subsequent requests. Switching IPs immediately invalidates it.
DataDome Invisible
Generates a datadome cookie for sites where DataDome runs silently in the background.
{
"task_type": "datadome-invisible",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.tripadvisor.com/",
"datadome_js_url": "https://js.datadome.co/tags.js",
"ddjskey": "2F05D671381DB06BEE4CC52C7A6FD3",
"ddoptions": "{\"ajaxListenerPath\": true}"
}| Field | Type | Description |
|---|---|---|
| datadome_js_url required | string | Usually https://js.datadome.co/tags.js — confirm from the page source. |
| ddjskey required | string | Site-specific key from the DataDome script tag. |
| ddoptions required | string | JSON string of options from the DataDome script tag init call. |
DataDome Slider
Solves the DataDome slider CAPTCHA shown when DataDome has flagged a request.
When you've been challenged with the slider, pass the endpoint that returned the challenge and your existing datadome cookie. That cookie is what triggered the slider — DataDome uses it to track your session.
{
"task_type": "datadome-slider",
"proxy": "http://user:pass@ip:port",
"target_url": "https://mygift.giftcardmall.com/api/card/getCardBalance",
"target_method": "POST",
"init_cookies": {
"datadome": "your_existing_datadome_cookie"
}
}DataDome Device Check
Handles the DataDome device check — a deeper browser validation challenge.
Stricter than the invisible variant. DataDome uses this when it requires more thorough browser environment validation before granting access.
{
"task_type": "datadome-device-check",
"proxy": "http://user:pass@ip:port",
"target_url": "https://www.cma-cgm.com/",
"target_method": "GET"
}AWS WAF
Returns a valid aws-waf-token for AWS WAF-protected endpoints.
AWS WAF runs a JavaScript challenge to verify the client before allowing access to the protected resource. Locate the challenge script URL in the page source — it's served from a domain containing awswaf.com.
{
"task_type": "aws",
"proxy": "http://user:pass@ip:port",
"target_url": "https://sportsbook.caesars.com/us/ia/bet/",
"aws_js_url": "https://b470c5d1aeb4.edge.sdk.awswaf.com/b470c5d1aeb4/06faba802dee/challenge.js"
}| Field | Type | Description |
|---|---|---|
| aws_js_url required | string | The AWS WAF challenge script. The domain contains awswaf.com. |