# Takion API

Takion API is an antibot and captcha bypass API. One HTTPS request returns the fresh cookies, headers, and tokens you need to get through a protected wall, so you can scrape and automate at scale with

There is nothing to run locally and no headless browser to babysit. You send one POST, you get back a valid token or cookie set, and you attach it to your own request. The same API key works for every vendor, and every endpoint returns the same JSON shape.

{% hint style="success" icon="bolt" %}
New here? Start with [Interacting with our APIs](/start) to get your key and make your first call, then jump to the wall you are facing.
{% endhint %}

## Why Choose Takion API?

Takion API provides a seamless solution for bypassing any antibot or captcha protection without the need for browser automation. Our API is designed to give you fast, efficient, and reliable access to websites that are otherwise blocked by advanced security systems.

### **Key Advantages of Takion API:**

* **No Browser Automation**: Unlike other services, we eliminate the need for browser automation. Our API is more efficient and less prone to errors that come from browser updates or inconsistencies, providing you with a smoother and faster experience. This on your end means as well minimal proxy usage during resolutions.
* **Access Any Website, Any Time**: With our technology, you can access and scrape any website protected by Antibots, without interruptions or challenges.
* **Support for Any Browser OS/Version**: Our API works across all browser operating systems and versions, giving you the flexibility to solve challenges with the verions/os you prefer.
* **Custom Solutions**: We can develop tailored frameworks or modules to meet your specific needs. Whether it’s for bypassing antibots, automating websites, or handling other challenges, we’ve got you covered.
* **Free Trials Available**: Try our service with a free trial before committing. We’re confident in our API’s performance and want you to experience its benefits first-hand.
* **Simple and Fast Implementation**: Get up and running quickly with easy-to-follow guides, client libraries, and example scripts in various programming languages.
* **Uninterrupted Service**: Our API runs 24/7, ensuring you always have access. If there are changes to antibots, we update our system to keep your operations smooth.
* **Trusted by Many**: Proven reliable and effective by our clients, Takion API has been delivering consistent results for months.
* **Dedicated Servers Available**: Need more power? We offer dedicated servers as part of your plan for maximum performance.
* **One Plan Covers Everything**: Our plans include access to all APIs—Reese84, UTMVC, GeeTest, and more—with no hidden fees.

### **Plans and Pricing**

Full access to every antibot and captcha API is included in one plan with no hidden fees. Larger or bespoke needs (dedicated servers, custom monthly volume) get a **custom plan**. Just ask.

* **Free trial:** request a key via [our Dashboard](https://takionapi.tech/trial).
* **Subscribe:** [takionapi.tech/pricing](https://takionapi.tech/pricing).

### **Source Code Availability**

Interested in the source code for any of our services? We’re open to discussing offers. Get in touch via Discord for more information.

### **Custom Solutions & Frameworks**

Other than just APIs, we offer **custom solutions** and **frameworks** tailored to your specific needs.\
Read more [here](/modules) and contact us via Discord for any question.

### **Join Us**

For free trials, support, or custom requests, join our [**Discord server**](https://takionapi.tech/discord). We’re always available to assist you and develop solutions that fit your exact needs.

Check out[ our blog](https://takionapi.tech/discord) as well!

{% embed url="<https://takionapi.tech/discord>" %}


# Interacting with our APIs

Every Takion endpoint speaks plain HTTPS and shares the same authentication, the same subdomain pattern, and the same error codes. Learn it once here, then each vendor page only covers what is uniqueL

## API Key

You need an API key to call any endpoint. Request a trial key [via Discord](https://takionapi.tech/discord) or [purchase a plan](https://takionapi.tech/pricing).

A key looks like this:

```
TAKION_API_XXXXXXXX
```

## Endpoints <a href="#endpoints" id="endpoints"></a>

Each antibot has its own subdomain, so interactions stay organized:

```
https://<vendor>.takionapi.tech      e.g. https://datadome.takionapi.tech
```

Different walls expect different parameters and return different tokens, so always check that vendor's page for the exact endpoint, request body, and response.

### Authentication

Send your key one of two ways:

**Header**

```
x-api-key: TAKION_API_XXXXXXXX
```

**Query parameter**

```
?api_key=TAKION_API_XXXXXXXX
```

### Browser Details

Our solutions are not browser-based, but they read the headers you send to build a realistic fingerprint:

* `User-Agent`
* `Sec-Ch-Ua`
* `Accept-Language`

{% hint style="success" %}
Providing accurate browser headers based on your produces more realistic tokens. If you send none, the latest chrome versions on MacOS will be used, but matching the headers you will send on the final request is strongly recommended.
{% endhint %}

### Plan Details and Status

Check your key's status two ways:

* Use [your Dashboard](https://takionapi.tech/dashboard)
* Send `GET /plan` on any Aantibot subdomain for a JSON response with your plan details

## Get plan status

> Returns the current status of the authenticated API key — plan name, request usage against your quota, and validity. Use it to monitor consumption in real time.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — Plan status","version":"1.0.0"},"servers":[{"url":"https://{vendor}.takionapi.tech","description":"Any antibot subdomain exposes /plan.","variables":{"vendor":{"default":"datadome","description":"The antibot subdomain to query (datadome, incapsula, geetest, perimeterx, castle, nudata, cognito, akamai, cloudflare, hcaptcha).\n"}}}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"Plan":{"type":"object","description":"Your plan details. The field names below are representative — confirm them against a live `/plan` response and adjust before publishing.\n","properties":{"valid":{"type":"boolean","description":"Whether the key is currently active and within its limit."},"plan":{"type":"string","description":"The subscription tier name."},"requests_used":{"type":"integer","description":"Requests consumed in the current period."},"requests_limit":{"type":"integer","description":"Total requests included in the current period."},"resets_at":{"type":"string","format":"date-time","nullable":true,"description":"When the usage counter resets (null for non-cyclic plans)."}},"additionalProperties":true},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message."}}}}},"paths":{"/plan":{"get":{"operationId":"getPlan","summary":"Get plan status","description":"Returns the current status of the authenticated API key — plan name, request usage against your quota, and validity. Use it to monitor consumption in real time.\n","responses":{"200":{"description":"Plan details for the authenticated key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Plan"}}}},"401":{"description":"Invalid API key — the key is wrong, expired, or over its request limit.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

### Error Codes

* **400 - Invalid Input Parameters**: Review the data provided; there’s an issue with it.
* **401 - Invalid API Key**: The API key is invalid, expired, or the request limit has been exceeded.
* **500 - Internal Server Error**: Something unexpected occurred on our end. Contact us for support.


# Datadome

A DataDome bypass without a browser. Takion solves DataDome's tags.js (ch/le), captcha, and interstitial challenges and returns a valid Datadome cookie, so your requests get through and stay through.

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is Datadome?**

DataDome is an application-layer (layer 7) bot-management system that protects sites against scraping, credential stuffing, and DDoS. It scores every request on signals like TLS fingerprint and HTTP header order, and when something looks automated it issues a challenge. Because its detection is so sensitive, a working bypass has to replicate a real browser's request shape precisely. The TLS signature and the exact order of headers both matter.

A rotating proxy pool is recommended: IP bans are common, and rotating IPs keeps disruption low.

## How Datadome Works

On first visit, or after a number of requests, a protected site challenges you and, once solved, issues a **`datadome`** cookie that grants access for a set period. If a site sets a **`datadome`** cookie, it is running DataDome.

There are two main challenge types:

### Datadome challenges

#### <mark style="color:purple;">**GeeTest (Sliding Captcha)**</mark>&#x20;

This requires solving a sliding puzzle before access is granted

<figure><img src="/files/rlsHBC65RkBg0gt6q2sy" alt=""><figcaption></figcaption></figure>

Based on the website configuration the puzzle resolution could be omitted, asking only for a swipe, the flow is the same.

<figure><img src="/files/HA5zt4WAJQTEQjiD35zN" alt=""><figcaption></figcaption></figure>

#### <mark style="color:purple;">**Interstitial Device Check**</mark>&#x20;

This newer challenge verifies a user’s device, sometimes displaying a blank page or a "Verify your device" message.<br>

<figure><img src="/files/5Cuyd0JlJvcbeUCtdLDU" alt=""><figcaption></figcaption></figure>

***

## **Detecting Datadome Websites**

When you hit a DataDome-protected page you often get a `403` with an unusual HTML body. The key part is the `dd` object, which is used to build the challenge URL:

```html
<html>
    <head>
        <title>footlocker.com</title>
    </head>
    <body style="margin:0">
        <p id="cmsg">Please enable JS and disable any ad blocker</p>
        <script data-cfasync="false">
            var dd = {
                'rt': 'i',
                'cid': 'AHrlqAAAAAMAxVzL7Hc0p40AWXJFuQ==',
                'hsh': 'A55FBF4311ED6F1BF9911EB71931D5',
                'b': 1239798,
                's': 17434,
                'host': 'geo.captcha-delivery.com'
            }
        </script>
        <script data-cfasync='false'>
            (function() {
                // ...
            }
            )();
        </script>
        <script data-cfasync="false" src="https://interstitial.captcha-delivery.com/i.js"></script>
    </body>
</html>
```

The `rt` field tells you which challenge you are facing before you even start:

* `i`: interstitial
* `c`: captcha slider

{% hint style="warning" %}
Some sites ship a custom implementation and may return JSON or a different HTML shape. Detect on the `datadome` cookie and the `dd` object rather than on an exact page layout.
{% endhint %}

***

## Some websites using Datadome <a href="#some-websites-using-it" id="some-websites-using-it"></a>

Most of the tickets websites are using Incapsula to protect their website. Here are some examples of websites using Incapsula and the cookies/challenge they require:

| Website                                                              |
| -------------------------------------------------------------------- |
| [footlocker.com](https://www.footlocker.pt/) (and all other domains) |
| [uefa](https://euro2024-sales.tickets.uefa.com/)                     |
| [hermes.com](https://www.hermes.com/)                                |
| [ticketing.liverpoolfc.com](https://ticketing.liverpoolfc.com/)      |
| [ticketing.manutd.com](https://ticketing.manutd.com/)                |
| [tickets.mancity.com](https://tickets.mancity.com/)                  |
| [seatgeek.com](https://www.seatgeek.com/)                            |
| ...                                                                  |

## Our API <a href="#our-api" id="our-api"></a>

Takion automates the whole challenge flow and returns the `datadome` cookie, so you can access protected sites without solving anything yourself. Continue to the reference


# Bypass Solution

Our solution automates solving challenges like sliding captchas and interstitial device checks, allowing seamless access to Datadome protected websites without any worry.

## **How the Solution Works**

To bypass DataDome's protection, follow a simple logic, when a website returns you a datadome challenge, either:\
\
The full challenge html

```html
<!DOCTYPE html>
<html lang="en"  style="background-color:#ffffff">
    <head>
        <title>You have been blocked | Bot or Not?</title>
<!-- ... --->
```

A redirect to follow

```json
{
    "url": "https://geo.captcha-delivery.com/captcha/?initialCid=...&hash=...&cid=...&t=fe&referer=...&s=...&e=...&dm=..."
}
```

Or one to build and follow

```html
<html lang="es">
    <head>
        <title>idealista.com</title>
    </head>
    <body style="margin:0">
        <p id="cmsg">Please enable JS and disable any ad blocker</p>
        <script data-cfasync="false">
            var dd = {
                'rt': 'i',
                'cid': 'AHrlqAAAAAMAycYDrCG87_UAVNwdBA==',
                'hsh': 'AC81AADC3279CA4C7B968B717FBB30',
                'b': 1709036,
                's': 17156,
                'e': '...',
                'qp': '',
                'host': 'geo.captcha-delivery.com',
                'cookie': '...'
            }
        </script>
        <script data-cfasync="false" src="https://ct.captcha-delivery.com/i.js"></script>
    </body>
</html>

```

Whatever it is, you send it to us, we do the work for you and return you a valid datadome cookie. One POST.

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the Datadome subdomain:

```
https://datadome.takionapi.tech/generate
```

## Generate the datadome cookie

> Solves the DataDome challenge (slider or interstitial device check) from the challenge-page HTML and returns a valid \`datadome\` cookie plus the \`user\_agent\` it was minted for. Attach the cookie as \`Cookie: datadome=\<cookie>\` on your own request, sent with the matching User-Agent (and ideally through /tls, below).<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — DataDome","version":"1.0.0"},"servers":[{"url":"https://datadome.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"GenerateRequest":{"type":"object","required":["html","referer","proxy"],"properties":{"html":{"type":"string","description":"The DataDome challenge-page HTML (the 403 body containing the `dd` object). Get it by requesting the target page via /tls.\n"},"referer":{"type":"string","description":"The Referer of the page that served the challenge."},"proxy":{"type":"string","description":"Proxy to solve behind, so the cookie binds to the right IP. Format `ip:port` or `ip:port:user:pass`.\n"},"chrome_version":{"type":"string","description":"Chrome full version to emulate."},"macos_version":{"type":"string","description":"macOS version to emulate."}},"additionalProperties":true},"GenerateResponse":{"type":"object","properties":{"cookie":{"type":"string","description":"The `datadome` cookie value. Attach it as `Cookie: datadome=<cookie>`.\n"},"user_agent":{"type":"string","description":"The User-Agent the cookie was minted for — send it on the request that carries the cookie.\n"}},"additionalProperties":true},"Error":{"type":"object","description":"Every error is a JSON object with a single `error` string. Two tiers: auth/quota problems return HTTP 401 and unexpected failures return HTTP 500 (see the shared responses), while input-validation and \"blocked\" conditions on /generate return HTTP 200 with this same shape — so always check for `error` before using the result.\n","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — returned as HTTP 401 with an `error` message (no key, bad key, quota reached, or expired key).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"post":{"operationId":"generateDatadome","summary":"Generate the datadome cookie","description":"Solves the DataDome challenge (slider or interstitial device check) from the challenge-page HTML and returns a valid `datadome` cookie plus the `user_agent` it was minted for. Attach the cookie as `Cookie: datadome=<cookie>` on your own request, sent with the matching User-Agent (and ideally through /tls, below).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"responses":{"200":{"description":"Success returns the generated cookie. IMPORTANT: input-validation and \"blocked\" conditions ALSO return HTTP 200 with an `error` field (not a 4xx), so always check for `error` before reading `cookie`.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GenerateResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```

## Send a TLS-fingerprinted request (optional)

> Sends an HTTP request from Takion with a realistic browser TLS\
> fingerprint and header order, through your proxy — used to fetch the\
> DataDome challenge page (you get back the 403 + challenge HTML to feed\
> into \`/generate\`) and to re-request the protected page with the\
> \`datadome\` cookie attached.\
> \
> \*\*(Important) This endpoint is optional.\*\* If your own HTTP client\
> already reproduces the TLS and header fingerprint that matches the\
> User-Agent you send, you are good to go — just attach the cookie from\
> \`/generate\` to your own requests and skip \`/tls\` entirely.\
> \
> Use \`/tls\` only if you cannot match that fingerprint yourself. It is\
> always kept up to date and backed by a large bank of TLS\
> fingerprints / User-Agents, so you never have to chase browser changes.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — DataDome","version":"1.0.0"},"servers":[{"url":"https://datadome.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"TlsRequest":{"type":"object","required":["proxy","method","url"],"properties":{"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format."},"method":{"type":"string","description":"HTTP method for the upstream request.","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]},"url":{"type":"string","format":"uri","description":"The target URL to request."},"headers":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Request headers to send upstream (order is preserved)."},"json":{"type":"object","nullable":true,"description":"JSON body to send (sets a JSON content type).","additionalProperties":true},"data":{"type":"string","nullable":true,"description":"Raw request body (alternative to `json`)."}},"additionalProperties":true},"TlsResponse":{"type":"object","properties":{"status_code":{"type":"integer","description":"HTTP status returned by the upstream server."},"body":{"type":"string","description":"Raw response body from the upstream server."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Response headers from the upstream server."}},"additionalProperties":true},"Error":{"type":"object","description":"Every error is a JSON object with a single `error` string. Two tiers: auth/quota problems return HTTP 401 and unexpected failures return HTTP 500 (see the shared responses), while input-validation and \"blocked\" conditions on /generate return HTTP 200 with this same shape — so always check for `error` before using the result.\n","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — returned as HTTP 401 with an `error` message (no key, bad key, quota reached, or expired key).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/tls":{"post":{"operationId":"tlsRequest","summary":"Send a TLS-fingerprinted request (optional)","description":"Sends an HTTP request from Takion with a realistic browser TLS\nfingerprint and header order, through your proxy — used to fetch the\nDataDome challenge page (you get back the 403 + challenge HTML to feed\ninto `/generate`) and to re-request the protected page with the\n`datadome` cookie attached.\n\n**(Important) This endpoint is optional.** If your own HTTP client\nalready reproduces the TLS and header fingerprint that matches the\nUser-Agent you send, you are good to go — just attach the cookie from\n`/generate` to your own requests and skip `/tls` entirely.\n\nUse `/tls` only if you cannot match that fingerprint yourself. It is\nalways kept up to date and backed by a large bank of TLS\nfingerprints / User-Agents, so you never have to chase browser changes.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TlsRequest"}}}},"responses":{"200":{"description":"The upstream response. On a bad request the API returns 200 with an `error` field instead of an HTTP error, so check for `error` first.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TlsResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% hint style="danger" %}
When interacting with Datadome a good TLS Client is required
{% endhint %}

{% hint style="warning" %}
Note that **the interstitial challenge** will return a json, with other than the cookie, an url to follow. In case of hard-protection mode on datadome, you may get redirected to a captcha challenge that needs to be solved as well
{% endhint %}

{% tabs %}
{% tab title="Datadome Homepage" %}

```python
from tls_client import Session
from requests import post
from time import sleep

API_KEY = "TAKION_API_XXX"

if __name__ == "__main__":
    session = Session(
        client_identifier="chrome_136",
        random_tls_extension_order=True
    )

    while 1:
        print("(1) Loading page...")
        response = session.get(
            'https://datadome.co/', 
            headers={
                'Host': 'datadome.co',
                'sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"',
                'sec-ch-ua-mobile': '?0',
                'sec-ch-ua-platform': '"macOS"',
                'upgrade-insecure-requests': '1',
                'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
                'sec-purpose': 'prefetch;prerender',
                'purpose': 'prefetch',
                'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                'sec-fetch-site': 'none',
                'sec-fetch-mode': 'navigate',
                'sec-fetch-user': '?1',
                'sec-fetch-dest': 'document',
                'accept-language': 'en-GB,en;q=0.9',
                'priority': 'u=0, i',
            }
        )
        print(response.text[:200])
        if response.status_code == 200:
            print("\033[1;32m" + f"Page loaded successfully: {response.status_code=}" + "\033[0m")
            break
        print("\033[1;33m" + f"Datadome detected! {response.status_code=}" + "\033[0m")

        build_response = post(
            "https://datadome.takionapi.tech/build",
            json={
                "html": response.text,
                "referer": "https://datadome.co/",
                "datadome": session.cookies.get("datadome")
            },
            headers={
                "x-api-key": API_KEY
            }
        ).json()
        if (error := build_response.get("error")):
            print(error)
            sleep(3)
            continue
        
        challenge_url, ctype = build_response["url"], build_response["challenge_type"]
        print(f"(2) Detected \033[1;35m{ctype}\033[0m challenge, loading...")

        challenge_page = session.get(
            challenge_url, 
            headers={
            'Host': 'geo.captcha-delivery.com',
            'sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Sec-Fetch-Site': 'cross-site',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Dest': 'iframe',
            'Sec-Fetch-Storage-Access': 'active',
            'Referer': 'https://datadome.co/',
            'Accept-Language': 'en-GB,en;q=0.9',
        })

        print("(3) Solving challenge...")
        solved_response = post(
            "https://datadome.takionapi.tech/solve",
            json={
                "html": challenge_page.text,
            },
            headers={
                'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
                "accept-language": "en-GB,en;q=0.9",
                "x-api-key": API_KEY
            }
        ).json()

        if (error := solved_response.get("error")):
            print(error)
            sleep(3)
            continue

        print("(4) Posting challenge...")
        if solved_response["method"] == "POST": # Interstitial
            response = session.post(
                solved_response["url"],
                headers={
                    'Host': 'geo.captcha-delivery.com',
                    'sec-ch-ua-platform': '"macOS"',
                    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
                    'sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"',
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    'sec-ch-ua-mobile': '?0',
                    'Accept': '*/*',
                    'Origin': 'https://geo.captcha-delivery.com',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Storage-Access': 'active',
                    'Referer': 'https://geo.captcha-delivery.com/interstitial/',
                    'Accept-Language': 'en-GB,en;q=0.9',
                }, 
                data=solved_response["payload"]
            )
        else:
            response = session.get(
                solved_response["url"],
                headers={
                    'Host': 'geo.captcha-delivery.com',
                    'sec-ch-ua-platform': '"macOS"',
                    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
                    'sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"',
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    'sec-ch-ua-mobile': '?0',
                    'Accept': '*/*',
                    'Sec-Fetch-Site': 'same-origin',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Storage-Access': 'active',
                    'Referer': 'https://geo.captcha-delivery.com/captcha/',
                    'Accept-Language': 'en-GB,en;q=0.9',
                }, 
                params=solved_response["payload"]
            )
        cookie = response.json()["cookie"].split("datadome=")[1].split(";")[0]
        print(f"\033[1;34m(5)Generated cookie: {cookie[:17]}...{cookie[-17:]}\033[0m")
        session.cookies.set("datadome", cookie)
        continue
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **IP Banned Error**

This error is returned by the `/solve` endpoint when the challenge page indicates "You have been blocked" without offering a solvable challenge. It usually occurs due to a poor-quality IP or incorrect interaction flow (e.g., wrong TLS setup, incorrect headers, or skipping necessary steps in the request flow). To resolve it, compare your requests with browser interactions using tools like Burp or Charles. Pay close attention to missing headers, incorrect header order, or improper TLS configurations.

## **What User-Agent Should I Pass to `/generate`?**

Datadome requires that the same User-Agent used to load the challenge page is passed to the `/solve` endpoint. After the challenge is solved, the cookie can be used with any User-Agent. We recommend using the latest version of Chrome throughout the entire interaction flow for the most reliable results.

We highly suggest to pass your session's `Accept-Language` header too.

## **Other Issues and Support**

For any additional errors or questions, or if you require a custom solution for a specific Datadome-protected website,\
Feel free to contact us either via [Discord](https://takionapi.tech/discord) or [mail](mailto:support@takionapi.tech) in case of support/problems.


# Perimeter X Mobile

A PerimeterX bypass for mobile apps. Takion generates the PerimeterX mobile headers an iOS or Android app expects, including \_px3 and x-px-authorization, so your requests can pass

{% hint style="danger" %}
**Trial and plan access is gated.** A PerimeterX bypass can be abused for fraud, so trial access is not automatic, and PXHC additionally requires your key to be whitelisted for the service. Please contact us on [Discord](https://takionapi.tech/discord) or [via mail](mailto:sales@takionapi.tech) , we'll need to verify your business first.
{% endhint %}

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is PerimeterX Mobile?**

PerimeterX, known simply as px (now HUMAN), is a bot-management solution that protects mobile applications, APIs, and web apps from automated threats. It tells human traffic from bot traffic using advanced detection built into the app's SDK.

PerimeterX ships in several forms: web, hold captcha (pxhc), and a mobile version. This documentation focuses specifically on the **mobile** version used in apps on iOS and Android. The web and pxhc variants are covered separately in their respective docs.

## **How to Detect if an Application is Using PerimeterX**

PerimeterX protection can be identified in mobile app requests by inspecting the headers for specific values:

* **For px3:** headers resembling `3:5b0de...3c67add:MO...P5VNA==:1000:6xXz...=`
* **For px2:** headers resembling `2:eyJ1Ijoi...JkZWYyIn0=`

These headers are often passed as `x-px-original-token`, `x-px-authorization`, or `x-px-context`.

<figure><img src="/files/TVCzClmzY2AzV4l3fsoa" alt=""><figcaption></figcaption></figure>

Additionally, look for requests made to URLs such as:

* `https://collector-XXX.perimeterx.net/api/v1/collector/mobile`
* `https://collector-XXX.px-cloud.net/api/v2/collector`

<figure><img src="/files/iqk0OBnKy26f6W1N89mH" alt=""><figcaption></figcaption></figure>

### Some apps using PerimeterX <a href="#some-apps-using-perimeterx" id="some-apps-using-perimeterx"></a>

Some applications known to use PerimeterX for mobile protection:

<table><thead><tr><th>App Name</th><th>Package Name</th></tr></thead><tbody><tr><td>StockX</td><td><pre><code>com.stockx.stockx
</code></pre></td></tr><tr><td>TextNow</td><td><pre><code>com.enflick.android.TextNow
</code></pre></td></tr><tr><td>GrubHub</td><td><pre><code><strong>com.grubhub.android
</strong></code></pre></td></tr><tr><td>My B&#x26;B</td><td><pre><code>com.bathandbody.bbw
</code></pre></td></tr><tr><td>FanDuel</td><td><pre><code><strong>com.fanduel.sportsbook
</strong></code></pre></td></tr><tr><td>PrizePicks</td><td><pre><code>com.myprizepicks.myprizepicks
</code></pre></td></tr></tbody></table>

## Our API

Takion generates you all the **`x-px-*`** related header for interacting without issue into the application endpoints.


# Bypass Solution

The PerimeterX mobile bypass endpoint. You POST the app and device details, and Takion returns the PerimeterX mobile headers (\_px3, x-px-authorization or \_px2) the protected app expects.

## **How the Solution Works**

To bypass PerimeterX mobile protection:

1. **Provide our API with the device and app details.**
2. **Parse the returned headers and use them for requests to the protected application.**

{% hint style="info" %}
For app-specific requests, examples, more informations or plan pricing, please contact us on [Discord](https://takionapi.tech/discord) or [via mail](mailto:sales@takionapi.tech)
{% endhint %}

## **Required Details**

Since PerimeterX is mobile-based, our API requires a JSON input with the `package_name` of the Android app (for example `com.enflick.android.TextNow` for TextNow). Additional optional device information can be supplied for more accurate header generation.

Based on this information, the API returns all necessary headers for the specified app.

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the px-mobile subdomain:

```
https://px-mobile.takionapi.tech/generate
```

## Generate PX mobile headers

> Produces the \`X-PX-\*\` mobile headers (session id, authorization, vid, uuid, device fingerprint, …) for the given app package. Send them on your app-API request alongside the matching User-Agent.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX (Mobile)","version":"1.0.0"},"servers":[{"url":"https://px-mobile.takionapi.tech"}],"security":[{"ApiKeyQuery":[]},{"ApiKeyHeader":[]}],"components":{"securitySchemes":{"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"},"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"GenerateMobileRequest":{"type":"object","required":["package_name","proxy"],"properties":{"package_name":{"type":"string","description":"The Android/iOS app package the PX headers are for."},"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format."},"manufacturer":{"type":"string","description":"Device manufacturer to emulate (optional)."},"android_version":{"type":"string","description":"Android version to emulate (optional)."},"continent":{"type":"string","description":"Continent hint for the emulated device (optional)."},"language":{"type":"string","description":"Device language (optional)."}},"additionalProperties":true},"GenerateMobileResponse":{"type":"object","description":"The PX mobile headers. Send each on your app-API request (header names as shown), with the matching User-Agent.\n","properties":{"user-agent":{"type":"string"}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; validation and trial/whitelist gates return an `error` field too.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"post":{"operationId":"generatePxMobileHeaders","summary":"Generate PX mobile headers","description":"Produces the `X-PX-*` mobile headers (session id, authorization, vid, uuid, device fingerprint, …) for the given app package. Send them on your app-API request alongside the matching User-Agent.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateMobileRequest"}}}},"responses":{"200":{"description":"The PX mobile headers. On a bad request the API returns an `error` field instead — check for `error` before reading the headers.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GenerateMobileResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```

## Send a session-bound mobile TLS request (optional)

> Sends an HTTP request from Takion bound to the \`session\_id\` from\
> /generate, with a realistic mobile TLS fingerprint.\
> \
> \*\*(Important) This endpoint is optional.\*\* If your own client already\
> reproduces the mobile TLS + header fingerprint, just attach the generated\
> \`X-PX-\*\` headers to your own request and skip \`/mobile/tls\`. Use it only\
> when you can't match the fingerprint yourself.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX (Mobile)","version":"1.0.0"},"servers":[{"url":"https://px-mobile.takionapi.tech"}],"security":[{"ApiKeyQuery":[]},{"ApiKeyHeader":[]}],"components":{"securitySchemes":{"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"},"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TlsRequest":{"type":"object","required":["proxy","method","url"],"properties":{"proxy":{"type":"string"},"session_id":{"type":"string","nullable":true,"description":"The x-px-session-id from /generate."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","nullable":true,"additionalProperties":{"type":"string"}},"json":{"type":"object","nullable":true,"additionalProperties":true},"data":{"type":"string","nullable":true}},"additionalProperties":true},"TlsResponse":{"type":"object","properties":{"status_code":{"type":"integer"},"body":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; validation and trial/whitelist gates return an `error` field too.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/mobile/tls":{"post":{"operationId":"pxMobileTlsRequest","summary":"Send a session-bound mobile TLS request (optional)","description":"Sends an HTTP request from Takion bound to the `session_id` from\n/generate, with a realistic mobile TLS fingerprint.\n\n**(Important) This endpoint is optional.** If your own client already\nreproduces the mobile TLS + header fingerprint, just attach the generated\n`X-PX-*` headers to your own request and skip `/mobile/tls`. Use it only\nwhen you can't match the fingerprint yourself.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TlsRequest"}}}},"responses":{"200":{"description":"The upstream response (or an `error` field).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TlsResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="Simple Generation" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"  # YOUR API KEY

url = "https://px-mobile.takionapi.tech/generate"

querystring = {"api_key": API_KEY}

payload = {
    "package_name": "com.enflick.android.TextNow",
    "manufacturer": "samsung",
    "continent": "america"
}
headers = {
    "Content-Type": "application/json"
}

response = requests.request(
    "POST", url, json=payload, headers=headers, params=querystring)

print(response.text)
```

{% endtab %}

{% tab title="My B\&B" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"

url = "https://api.bbw.com/payments/v2/giftcard"

payload = {
    "lbCustomerID": "abyQtuW2FurvCkyKA3h2cLxUMh",
    "email": "xxx@gmail.com",
    "brand": "BBW",
}


def send_request_without_headers():
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    }
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(
        f"Response without headers: {response.status_code} / {response.text}")


def send_request_with_headers():
    px_headers = requests.post(
        "https://px-mobile.takionapi.tech/generate",
        json={"package_name": "com.bathandbody.bbw", "manufacturer": "samsung"},
        params={"api_key": API_KEY}
    ).json()
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    } | px_headers
    print(px_headers)
    exit(0)
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(f"Response with headers: {response.status_code} / {response.text}")


if __name__ == "__main__":
    send_request_without_headers()
    print(" -------------------- ")
    send_request_with_headers()
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **Issues and Support**

Most of the problems when interacting with px-mobile protected websites are due either:

* A bad proxy ip
* Bad TLS details not matching a correct mobile device
* Wrong internal app flow/details

Feel free to contact us either via [Discord](https://takionapi.tech/discord) or [mail](mailto:support@takionapi.tech) in case of support/problems.


# Perimeter X Web

A PerimeterX bypass for website. Takion generates the PerimeterX web cookies the website expects, including \_px3, \_pxcts, \_pxvid, ..., so your requests can pass.

{% hint style="danger" %}
**Trial and plan access is gated.** A PerimeterX bypass can be abused for fraud, so trial access is not automatic, and PXHC additionally requires your key to be whitelisted for the service. Please contact us on [Discord](https://takionapi.tech/discord) or [via mail](mailto:sales@takionapi.tech) , we'll need to verify your business first.
{% endhint %}

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is PerimeterX Web?**

PerimeterX, now HUMAN Security, builds a risk score from a device fingerprint and a deep telemetry analysis of your behavior, gathered through a series of encrypted posts as you use the page. It sets a `_px3` cookie that carries your trusted session. Its challenges rotate constantly, which is what makes it hard to keep up with by hand.

The web trust lives in the `_px3` cookie. Mobile apps running the PerimeterX SDK carry the same trust in an `x-px-authorization` header set instead (see [PerimeterX Mobile](/px-mobile)).

## **How to Detect if a website is Using PerimeterX**

If a site sets a `_px3` cookie, it is running PerimeterX / HUMAN. When traffic looks automated it serves a press-and-hold ("press and hold to confirm you are human") captcha before granting acces, that hold captcha is handled by the [Hold Captcha](/pxhc) flow. Common fingerprints:

* A `_px3` cookie on the response.
* A press-and-hold captcha page instead of the content.
* Collector posts to `*.perimeterx.net` or `*.px-cloud.net`.

<figure><img src="/files/r1bZPp8VEwYCTuhlQO5X" alt=""><figcaption></figcaption></figure>

### **Example of PerimeterX-Protected Websites**

Some applications known to use PerimeterX for websites protection include:

| [Zillow](https://www.zillow.com/)         |
| ----------------------------------------- |
| [Walmart](https://www.walmart.com/)       |
| [PrizePicks](https://www.prizepicks.com/) |
| [TextNow](https://www.textnow.com/)       |
| [SkyScanner](https://www.skyscanner.com/) |
| [StockX](https://stockx.com/)             |
| [Grubhub](https://www.grubhub.com/)       |
| [Fanatics](https://www.fanatics.com/)     |
| [Crunchbase](https://www.crunchbase.com/) |

## Our API <a href="#our-api" id="our-api"></a>

Takion automates the whole challenge flow and returns the `_px3` cookie alongside any other generated one during the resolution, so you can access protected sites without solving anything yourself. Continue to the reference


# Bypass Solution

The PerimeterX web bypass endpoint. You POST the website details, and Takion returns the PerimeterX web needed cookies that the protected website expects.

## **How the Solution Works**

To bypass PerimeterX protection:

1. **Provide our API with the website details**
2. **Parse the returned cookies and use them for requests to the protected website.**

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the px-web subdomain:

```
https://px-web.takionapi.tech/generate
```

## Generate a PX web session (\_px3 cookie)

> Solves PerimeterX for the given app and page and returns a session that carries the \`\_px3\` cookie plus a Takion \`x-px-session-id\`. Attach \`\_px3\` to your own requests, or keep sending through /tls with the session id.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX (Web)","version":"1.0.0"},"servers":[{"url":"https://px-web.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"GenerateWebRequest":{"type":"object","required":["proxy","user_agent"],"properties":{"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format."},"user_agent":{"type":"string","description":"The browser User-Agent to emulate (match it on your own requests)."},"app_id":{"type":"string","description":"The PX app id (`_pxAppId`) of the target."},"page_url":{"type":"string","format":"uri","description":"The page the session is for."},"fast_mode":{"type":"boolean","description":"Quicker solve with a slightly weaker PX score."}},"additionalProperties":true},"GenerateWebResponse":{"type":"object","properties":{"cookies":{"type":"object","description":"The PX cookies to replay, including `_px3`.","properties":{"_px3":{"type":"string"}},"additionalProperties":{"type":"string"}},"extra":{"type":"object","description":"Session metadata.","properties":{},"additionalProperties":true}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors return an `error` field too — always check for `error` first.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"post":{"operationId":"generatePxWebSession","summary":"Generate a PX web session (_px3 cookie)","description":"Solves PerimeterX for the given app and page and returns a session that carries the `_px3` cookie plus a Takion `x-px-session-id`. Attach `_px3` to your own requests, or keep sending through /tls with the session id.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateWebRequest"}}}},"responses":{"200":{"description":"The PX session. On a bad request the API returns an `error` field instead — check for `error` before reading `cookies` / `extra`.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GenerateWebResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```

## Send a session-bound TLS request (optional)

> Sends an HTTP request from Takion with a realistic browser TLS\
> fingerprint, bound to the \`session\_id\` from /generate so the PX cookies\
> stay valid across the flow.\
> \
> \*\*(Important) This endpoint is optional.\*\* If your own client already\
> reproduces the TLS + header fingerprint matching your User-Agent, just\
> attach the \`\_px3\` cookie from /generate to your own requests and skip\
> /tls. Use it only when you can't match the fingerprint yourself — it is\
> always kept up to date with a large bank of fingerprints.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX (Web)","version":"1.0.0"},"servers":[{"url":"https://px-web.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"TlsRequest":{"type":"object","required":["proxy","method","url"],"properties":{"proxy":{"type":"string"},"session_id":{"type":"string","nullable":true,"description":"The x-px-session-id from /generate (keeps PX state hot)."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","nullable":true,"additionalProperties":{"type":"string"}},"json":{"type":"object","nullable":true,"additionalProperties":true},"data":{"type":"string","nullable":true}},"additionalProperties":true},"TlsResponse":{"type":"object","properties":{"status_code":{"type":"integer"},"body":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors return an `error` field too — always check for `error` first.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/tls":{"post":{"operationId":"pxWebTlsRequest","summary":"Send a session-bound TLS request (optional)","description":"Sends an HTTP request from Takion with a realistic browser TLS\nfingerprint, bound to the `session_id` from /generate so the PX cookies\nstay valid across the flow.\n\n**(Important) This endpoint is optional.** If your own client already\nreproduces the TLS + header fingerprint matching your User-Agent, just\nattach the `_px3` cookie from /generate to your own requests and skip\n/tls. Use it only when you can't match the fingerprint yourself — it is\nalways kept up to date with a large bank of fingerprints.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TlsRequest"}}}},"responses":{"200":{"description":"The upstream response (or an `error` field).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TlsResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="Simple Generation" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"  # YOUR API KEY

url = "https://px-mobile.takionapi.tech/generate"

querystring = {"api_key": API_KEY}

payload = {
    "package_name": "com.enflick.android.TextNow",
    "manufacturer": "samsung",
    "continent": "america"
}
headers = {
    "Content-Type": "application/json"
}

response = requests.request(
    "POST", url, json=payload, headers=headers, params=querystring)

print(response.text)
```

{% endtab %}

{% tab title="My B\&B" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"

url = "https://api.bbw.com/payments/v2/giftcard"

payload = {
    "lbCustomerID": "abyQtuW2FurvCkyKA3h2cLxUMh",
    "email": "xxx@gmail.com",
    "brand": "BBW",
}


def send_request_without_headers():
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    }
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(
        f"Response without headers: {response.status_code} / {response.text}")


def send_request_with_headers():
    px_headers = requests.post(
        "https://px-mobile.takionapi.tech/generate",
        json={"package_name": "com.bathandbody.bbw", "manufacturer": "samsung"},
        params={"api_key": API_KEY}
    ).json()
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    } | px_headers
    print(px_headers)
    exit(0)
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(f"Response with headers: {response.status_code} / {response.text}")


if __name__ == "__main__":
    send_request_without_headers()
    print(" -------------------- ")
    send_request_with_headers()
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **Issues and Support**

Most of the problems when interacting with px-web protected websites are due either:

* A bad proxy ip
* Bad TLS details not matching the user agent
* Wrong website interaction flow/details

Feel free to contact us either via [Discord](https://takionapi.tech/discord) or [mail](mailto:support@takionapi.tech) in case of support/problems.


# Perimeter X Hold Captcha (pxhc)

A PerimeterX press-and-hold captcha bypass without a browser. When a PerimeterX site blocks you with the "press & hold to confirm you are human" challenge, Takion solves it and returns the \_px3 cookie

{% hint style="danger" %}
**Trial and plan access is gated.** A PerimeterX bypass can be abused for fraud, so trial access is not automatic, and PXHC additionally requires your key to be whitelisted for the service. Please contact us on [Discord](https://takionapi.tech/discord) or [via mail](mailto:sales@takionapi.tech) , we'll need to verify your business first.
{% endhint %}

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **How to Detect if a website is Using PerimeterX Hold Captcha**

During you interactions you may encounter a WAF challenge like this one

<figure><img src="/files/iEkIKpnplb5eMJxjM15P" alt=""><figcaption></figcaption></figure>

### **Example of PerimeterX-Protected Websites**

Some applications known to use PerimeterX for websites protection include:

| [Zillow](https://www.zillow.com/)         |
| ----------------------------------------- |
| [Walmart](https://www.walmart.com/)       |
| [PrizePicks](https://www.prizepicks.com/) |
| [TextNow](https://www.textnow.com/)       |
| [SkyScanner](https://www.skyscanner.com/) |
| [StockX](https://stockx.com/)             |
| [Grubhub](https://www.grubhub.com/)       |
| [Fanatics](https://www.fanatics.com/)     |
| [Crunchbase](https://www.crunchbase.com/) |

## Our API <a href="#our-api" id="our-api"></a>

Takion automates the whole WAF challenge flow and returns the `neded cookies`alongside any other generated one during the resolution, so you can access protected sites without solving anything yourself. Continue to the reference


# Bypass Solution

The PerimeterX Hold Captcha (pxhc) bypass endpoints and the flow to use in order to bypass a captcha.

## **How the Solution Works**

PXHC is **asynchronous**: you queue a solve and then poll for the result.

1. **Reach the block page.** Request the target until PerimeterX serves the `/blocked` press-and-hold page, then read the `_pxAppId`, `uuid`, and `vid` from its markup. (You can fetch it through the optional `/extra/tls` helper.)
2. **Queue the solve.** POST to `/{app_id}/solve` with the app id, page URL, and proxy. You get a `task_id` back.
3. **Poll the result.** POST the `task_id` to `/{app_id}/pull` until `status` is `solved`; the response then carries `cookies._px3`.
4. **Attach and send.** Put `_px3` (and any additional cookie) on your own request and continue.

{% hint style="info" %}
The solver is asynchronous cause the solving time is based on the required "press" time returned by px server during the challenge loading
{% endhint %}

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the px-web subdomain:

```
https://pxhc.takionapi.tech/generate
```

## Queue a PXHC solve

> Submits a press-and-hold captcha for the given PX \`app\_id\` and returns a \`task\_id\`. Poll /{app\_id}/pull with it until the task is solved.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX Hold Captcha (PXHC)","version":"1.0.0"},"servers":[{"url":"https://pxhc.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"parameters":{"AppId":{"name":"app_id","in":"path","required":true,"description":"The PerimeterX app id (`_pxAppId`) of the target.","schema":{"type":"string"}}},"schemas":{"SolveRequest":{"type":"object","required":["pxappid","page_url","proxy"],"properties":{"pxappid":{"type":"string","description":"The PX app id (same as the path `app_id`)."},"page_url":{"type":"string","format":"uri","description":"The /blocked page URL that served the captcha."},"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format."},"pxuuid":{"type":"string","description":"The PX uuid from the block page (optional; derived if omitted)."},"pxvid":{"type":"string","description":"The PX vid from the block page (optional)."}},"additionalProperties":true},"SolveResponse":{"type":"object","properties":{"task_id":{"type":"string","description":"Poll /{app_id}/pull with this id."}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. PXHC uses proper HTTP status codes: 400 (invalid input), 401 (auth/quota), 403 (whitelist/trial gate, sometimes 404), 404 (unknown task), 500 (internal).\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/{app_id}/solve":{"post":{"operationId":"solvePxhc","summary":"Queue a PXHC solve","description":"Submits a press-and-hold captcha for the given PX `app_id` and returns a `task_id`. Poll /{app_id}/pull with it until the task is solved.\n","parameters":[{"$ref":"#/components/parameters/AppId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolveRequest"}}}},"responses":{"200":{"description":"Task queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolveResponse"}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Access gated for this key/service — the key is not whitelisted for PXHC, or a trial is not available (this can also surface as 404).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Poll a PXHC task

> Returns the state of a queued task. Keep polling while \`status\` is \`pending\`; when \`status\` is \`solved\` the response carries \`cookies.\_px3\`.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — PerimeterX Hold Captcha (PXHC)","version":"1.0.0"},"servers":[{"url":"https://pxhc.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"parameters":{"AppId":{"name":"app_id","in":"path","required":true,"description":"The PerimeterX app id (`_pxAppId`) of the target.","schema":{"type":"string"}}},"schemas":{"PullResponse":{"type":"object","properties":{"status":{"type":"string","description":"Task state.","enum":["pending","solved","error"]},"solve_status":{"type":"string","description":"Detail on the solve outcome (present when finished)."},"cookies":{"type":"object","description":"Present when solved — carries `_px3`.","properties":{"_px3":{"type":"string"}},"additionalProperties":{"type":"string"}}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. PXHC uses proper HTTP status codes: 400 (invalid input), 401 (auth/quota), 403 (whitelist/trial gate, sometimes 404), 404 (unknown task), 500 (internal).\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/{app_id}/pull":{"post":{"operationId":"pullPxhc","summary":"Poll a PXHC task","description":"Returns the state of a queued task. Keep polling while `status` is `pending`; when `status` is `solved` the response carries `cookies._px3`.\n","parameters":[{"$ref":"#/components/parameters/AppId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["task_id"],"properties":{"task_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Current task state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullResponse"}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Unknown or expired task.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="Simple Generation" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"  # YOUR API KEY

url = "https://px-mobile.takionapi.tech/generate"

querystring = {"api_key": API_KEY}

payload = {
    "package_name": "com.enflick.android.TextNow",
    "manufacturer": "samsung",
    "continent": "america"
}
headers = {
    "Content-Type": "application/json"
}

response = requests.request(
    "POST", url, json=payload, headers=headers, params=querystring)

print(response.text)
```

{% endtab %}

{% tab title="My B\&B" %}

```python
import requests

API_KEY = "TAKION_API_XXXX"

url = "https://api.bbw.com/payments/v2/giftcard"

payload = {
    "lbCustomerID": "abyQtuW2FurvCkyKA3h2cLxUMh",
    "email": "xxx@gmail.com",
    "brand": "BBW",
}


def send_request_without_headers():
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    }
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(
        f"Response without headers: {response.status_code} / {response.text}")


def send_request_with_headers():
    px_headers = requests.post(
        "https://px-mobile.takionapi.tech/generate",
        json={"package_name": "com.bathandbody.bbw", "manufacturer": "samsung"},
        params={"api_key": API_KEY}
    ).json()
    headers = {
        "accept-language": "it-IT,it;q=0.9",
        "accept-charset": "UTF-8",
        "accept": "*/*",
        "content-type": "application/json",
    } | px_headers
    print(px_headers)
    exit(0)
    response = requests.post(
        url,
        json=payload,
        headers=headers
    )
    print(f"Response with headers: {response.status_code} / {response.text}")


if __name__ == "__main__":
    send_request_without_headers()
    print(" -------------------- ")
    send_request_with_headers()
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **Issues and Support**

Most of the problems when interacting with px-web protected websites are due either:

* A bad proxy ip
* Bad TLS details not matching the user agent
* Wrong website interaction flow/details

Feel free to contact us either via [Discord](https://takionapi.tech/discord) or [mail](mailto:support@takionapi.tech) in case of support/problems.


# Castle

A Castle bypass without a browser. Takion generates a valid x-castle-request-token / castle\_token in one call, so your login and checkout requests clear Castle's risk check and go through.

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is Castle?**

Castle ([castle.io](https://castle.io/)) is an account-security anti-bot layer. It scores logins, signups, and checkouts to stop account takeovers, fake-account creation, and policy-violating abuse. To do that it monitors browser characteristics, user behavior, and request patterns, and it expects every protected call to carry a valid `x-castle-request-token` (called `castle_token` on some sites) minted from those signals and the session's `__cuid` cookie.

### Detecting a Castle site <a href="#detecting-a-castle-site" id="detecting-a-castle-site"></a>

A page runs Castle when it loads the Castle SDK from the CDN. Look for a script tag like this:

```html
<script src="https://cdn.castle.io/v2/castle.js?pk_..."></script>
```

The value after the `?` is the script context you pass as the `scriptID`. Sites also set a `__cuid` cookie on the session that the token is bound to.

Another way to identifying it, would be to search for **`castle_token`** or **`x-castle-request-token`** and varinats between the browser requests.

## Some websites using Datadome <a href="#some-websites-using-it" id="some-websites-using-it"></a>

Most of the tickets websites are using Incapsula to protect their website. Here are some examples of websites using Incapsula and the cookies/challenge they require:

| Website                                          |
| ------------------------------------------------ |
| [Rockstar Games](https://www.rockstargames.com/) |
| [X (Twitter)](https://x.com/)                    |
| [DailyPay](https://www.dailypay.com/)            |
| ...                                              |

## Our API <a href="#our-api" id="our-api"></a>

Takion generates the `castle-token` and returns it with the `__cuid` it is bound to, so you can clear Castle-protected logins and checkouts without a browser. Continue to the reference:


# Bypass Solution

The Castle bypass runs in one call: GET /generate with the target (a website shortcut or the page's site\_key) returns a valid token

### How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass Castle:

1. Identify the target use a supported `website` shortcut (e.g. `twitter`, `rockstar`) or parse the **site key** (`pk_...`) from the page and pass it as `site_key`.
2. Call `/generate` with that, plus your session's `__cuid` if you already have one.
3. Read `token` from the response and attach it where the target expects it, carrying `__cuid` alongside.

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the Castle subdomain:

```
https://castle.takionapi.tech/generate
```

## Generate the Castle request token

> Returns a valid \`x-castle-request-token\` and the \`\_\_cuid\` cookie it is bound to. Identify the target with either the \`website\` shortcut (e.g. \`twitter\`, \`rockstar\`) or the page's \`site\_key\` (the \`pk\_...\` value). Pass your own \`\_\_cuid\` to bind to an existing session, or omit it and one is generated for you.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — Castle","version":"1.0.0"},"servers":[{"url":"https://castle.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"GenerateResponse":{"type":"object","properties":{"token":{"type":"string","description":"The Castle request token — send it as the `x-castle-request-token` header (or `castle_token` where the site expects that name).\n"},"__cuid":{"type":"string","description":"The `__cuid` the token is bound to — carry it on the same session."}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors on /generate return HTTP 200 with this shape — always check for `error` before using `token`.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"get":{"operationId":"generateCastleToken","summary":"Generate the Castle request token","description":"Returns a valid `x-castle-request-token` and the `__cuid` cookie it is bound to. Identify the target with either the `website` shortcut (e.g. `twitter`, `rockstar`) or the page's `site_key` (the `pk_...` value). Pass your own `__cuid` to bind to an existing session, or omit it and one is generated for you.\n","parameters":[{"name":"website","in":"query","required":false,"description":"Shortcut for a supported target so you don't have to parse the site key yourself. Provide this OR `site_key`.\n","schema":{"type":"string"}},{"name":"site_key","in":"query","required":false,"description":"The Castle public key (`pk_...`) from the page. Provide this OR `website`.","schema":{"type":"string"}},{"name":"__cuid","in":"query","required":false,"description":"Your session's `__cuid`. If omitted, Takion generates one and returns it — keep it on the session that sends the token.\n","schema":{"type":"string"}},{"name":"api_key","in":"query","required":false,"description":"Your API key (alternative to the x-api-key header; either is accepted).\n","schema":{"type":"string"}}],"responses":{"200":{"description":"Success returns the token + __cuid. On a bad request the API returns HTTP 200 with an `error` field instead — always check for `error` before reading `token`.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GenerateResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```

## Send a TLS-fingerprinted request (optional)

> Sends an HTTP request from Takion with a realistic browser TLS\
> fingerprint, through your proxy, carrying your cookie jar (including\
> \`\_\_cuid\`).\
> \
> \*\*(Important) This endpoint is optional.\*\* If your own client already\
> reproduces the TLS + header fingerprint matching your User-Agent, just\
> attach the \`x-castle-request-token\` and \`\_\_cuid\` from /generate to your\
> own request and skip /tls. Use it only when you can't match the\
> fingerprint yourself — it is always kept up to date.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — Castle","version":"1.0.0"},"servers":[{"url":"https://castle.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"TlsRequest":{"type":"object","required":["proxy","method","url"],"properties":{"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","nullable":true,"additionalProperties":{"type":"string"}},"json":{"type":"object","nullable":true,"additionalProperties":true},"data":{"type":"string","nullable":true},"params":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Query parameters to append to the URL."},"verify":{"type":"boolean","description":"Whether to verify TLS certificates upstream."}},"additionalProperties":true},"TlsResponse":{"type":"object","properties":{"status_code":{"type":"integer"},"body":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors on /generate return HTTP 200 with this shape — always check for `error` before using `token`.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/tls":{"post":{"operationId":"castleTlsRequest","summary":"Send a TLS-fingerprinted request (optional)","description":"Sends an HTTP request from Takion with a realistic browser TLS\nfingerprint, through your proxy, carrying your cookie jar (including\n`__cuid`).\n\n**(Important) This endpoint is optional.** If your own client already\nreproduces the TLS + header fingerprint matching your User-Agent, just\nattach the `x-castle-request-token` and `__cuid` from /generate to your\nown request and skip /tls. Use it only when you can't match the\nfingerprint yourself — it is always kept up to date.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TlsRequest"}}}},"responses":{"200":{"description":"The upstream response (or an `error` field).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TlsResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="DailyPay Generation" %}

```python
from requests import get
import requests
import re

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
    'cache-control': 'no-cache',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"macOS"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
}

params = {
    'utm_source': 'wwwlogin',
    'utm_medium': 'crossdomain',
}

response = requests.get('https://app.dailypay.com/login', params=params, headers=headers)

# Regex to extract the part after '?'
match = re.search(r'<script\s+src=["\'].*?cdn\.castle\.io/v2/castle\.js\?([^"\']+)["\'].*?>', response.text)

if not match:
    print("No scriptID found")
    exit(0)

script_id = match.group(1)

print(
    get(
        "https://castle.takionapi.tech/generate",
        params={
            "scriptID": script_id,
        },
        headers={
            "x-api-key": "TAKION_XXXX",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
            "sec-ch-ua": '"Google Chrome";v="127", "Chromium";v="127", "Not:A-Brand";v="99"'
        }
    ).json()
)
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **Issues and Support**

Most of the problems when interacting with Castle protected websites are due either:

* A bad proxy ip
* Bad TLS details not matching the user agent
* Wrong website interaction flow/details

Feel free to contact us either via [Discord](https://takionapi.tech/discord) or [mail](mailto:support@takionapi.tech) in case of support/problems.


# NuData

A NuData bypass without a browser. NuData scores behavior, so Takion generates the nds-pmd / x-src-nudetect-widgetdata  behavioral payload it expects and returns it ready to attach to your login or ch

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is NuData?**

NuData is a security service that protects sensitive actions such as logins and payments, commonly found on platforms like Ticketmaster and Kohl's. It check user actions to detect fraudulent activity.&#x20;

### Detecting a NuData site <a href="#detecting-a-castle-site" id="detecting-a-castle-site"></a>

Protected websites usually expect a parameter, often named **`nds-pmd`**, though the name may vary.

<figure><img src="/files/7a3rzlbx6y5wPWhLMpc6" alt=""><figcaption></figcaption></figure>

In other cases it may be called as **`x-src-nudetect-widgetdata`**, like for the **`stc.mastercard.com`** website.

<figure><img src="/files/85pQJohTg3vbMThxdehj" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
NuData scores logins, checkouts, and payments. It is a fraud gate, not a scraping wall. We take on these targets case by case. [Contact us first](https://takionapi.tech/contact) so we can confirm we can clear your specific flow before you build against it.
{% endhint %}

## Some websites using Datadome <a href="#some-websites-using-it" id="some-websites-using-it"></a>

Most of the tickets websites are using Incapsula to protect their website. Here are some examples of websites using Incapsula and the cookies/challenge they require:

| Website                                                                                                                     |
| --------------------------------------------------------------------------------------------------------------------------- |
| [ticketmaster.com](https://www.ticketmaster.com/) / [ticketmaster.sg](https://www.ticketmaster.sg/) (and other sub domains) |
| [kohls.com](https://www.kohls.com/)                                                                                         |
| [Mastercard](https://src.mastercard.com/)                                                                                   |
| ...                                                                                                                         |

## Our API <a href="#our-api" id="our-api"></a>

Takion generates the **`x-src-nudetect-widgetdata`** / **`nds-pmd`** (or whatever the website calls it) and returns it ready for your specific interaction.


# Bypass Solution

This documentation provides detailed information on generating the required NuData parameter.

## **How the Solution Works**

1. **Find the sensor script.** Identify the NuData script URL the page loads, for example `https://nudata.ticketmaster.com/2.2/w/w-481390/sync/js/` , `https://fc.kohls.com/2.2/w/w-756138/sync/js/ , https://src.mastercard.com/nudetect/2.2/w/w-802323/sync/js/`&#x20;
2. **Generate with one call.** Send that URL to the Takion NuData endpoint. We load the site's NuData settings, generate a valid payload server-side, and return `result` plus `input_name`.
3. **Attach and send.** Put the payload on your own login or checkout request under `input_name` (usually `nds-pmd`) and continue as normal. No browser runs on your side at any point.

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the Castle subdomain:

```
https://nudata.takionapi.tech/generate
```

## Generate a NuData payload

> Generates the NuData behavioral payload for the target. \`url\` and \`session\_id\` are query parameters; the simulated actions, cookies, proxy and checkout options go in the JSON body. GET also works (with the default login actions). Login mode is session-based — the first call returns a \`session\_id\`; send it back to continue. Checkout mode (\`checkout: true\`) costs 2 requests instead of 1.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — NuData","version":"1.0.0"},"servers":[{"url":"https://nudata.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"GenerateBody":{"type":"object","description":"Optional JSON body. Omit it for a GET-style call with the default login actions.\n","properties":{"actions":{"type":"array","description":"The user actions to simulate. Defaults to a password input + sign-in button when omitted.\n","items":{"type":"object","properties":{"type":{"type":"string","enum":["input","button"]},"name":{"type":"string"},"value_length":{"type":"integer","description":"For `input` actions — how many characters were typed."}},"additionalProperties":true}},"checkout":{"type":"boolean","description":"Generate a checkout payload instead of a login one (costs 2 requests)."},"click_targets":{"type":"array","description":"Checkout mode — the elements to click.","items":{"type":"string"}},"cookies":{"type":"object","description":"Client cookies for the init flow (optional).","additionalProperties":{"type":"string"}},"proxy":{"type":"string","description":"Proxy for the init flow (optional)."}},"additionalProperties":true},"GenerateResponse":{"type":"object","properties":{"session_id":{"type":"string","description":"Login mode — reuse this on the follow-up call to continue the same session.\n"}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Missing/invalid input or an expired session returns 400, auth/quota 401, and a generation or unexpected failure returns 500.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"post":{"operationId":"generateNudata","summary":"Generate a NuData payload","description":"Generates the NuData behavioral payload for the target. `url` and `session_id` are query parameters; the simulated actions, cookies, proxy and checkout options go in the JSON body. GET also works (with the default login actions). Login mode is session-based — the first call returns a `session_id`; send it back to continue. Checkout mode (`checkout: true`) costs 2 requests instead of 1.\n","parameters":[{"name":"url","in":"query","required":true,"description":"The NuData script URL of the target.","schema":{"type":"string","format":"uri"}},{"name":"session_id","in":"query","required":false,"description":"The `session_id` from a previous login call, to continue the same session (login mode only).\n","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBody"}}}},"responses":{"200":{"description":"The generated payload. In login mode the response carries a `session_id` to reuse on the follow-up call.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateResponse"}}}},"400":{"description":"Missing/invalid input or an expired/invalid session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"description":"Generation failed, or an unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="TicketMaster Login" %}

```python
import requests

API_KEY = ""

nudata_header = requests.get(
    "https://nudata.takionapi.tech/generate", 
    params={
        "url":"https://nudata.ticketmaster.com/2.2/w/w-481390/sync/js/",
        "api_key": API_KEY
    }
).json()["result"]

response = requests.post(
    "https://auth.ticketmaster.com/json/sign-in", 
    json={
        "email": "exampleuser@gmail.com",
        "password": "example!",
        "rememberMe": False,
        "externalUserToken": None
    }, 
    headers={
        "accept": "*/*",
        "accept-language": "en-us",
        "content-type": "application/json",
        "nds-pmd": nudata_header, # We are passing nudata header
        "origin": "https://auth.ticketmaster.com",
        "priority": "u=1, i",
        "referer": "https://auth.ticketmaster.com/as/authorization.oauth2?client_id=8bf7204a7e97.web.ticketmaster.us&response_type=code&scope=openid%20profile%20phone%20email%20tm&redirect_uri=https://identity.ticketmaster.com/exchange&visualPresets=tm&lang=en-us&placementId=mytmlogin&hideLeftPanel=false&integratorId=prd1741.iccp&intSiteToken=tm-us&TMUO=east_Yy+wr1Nf+xmww4O9ewBePc8SMn3/TKSDNBl6qJi7Lxk=&deviceId=xgSNBg0DvDU3NDc6OjY2Njo9Mz1i4D%2FZ9cE4fQ&doNotTrack=true",
        "sec-ch-ua": '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"macOS\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "tm-client-id": "8bf7204a7e97.web.ticketmaster.us",
        "tm-integrator-id": "prd1741.iccp",
        "tm-oauth-type": "tm-auth",
        "tm-placement-id": "mytmlogin",
        "tm-site-token": "tm-us",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
    }
)

print(response.text)
```

{% endtab %}

{% tab title="Comparison with and without header" %}

```python
import requests

API_KEY = ""

def test_without_nudata():
    return requests.post(
        "https://auth.ticketmaster.com/json/sign-in", 
        json={
            "email": "exampleuser@gmail.com",
            "password": "example!",
            "rememberMe": False,
            "externalUserToken": None
        }, 
        headers={
            "accept": "*/*",
            "accept-language": "en-us",
            "content-type": "application/json",
            # "nds-pmd": , We are not passing nudata header
            "origin": "https://auth.ticketmaster.com",
            "priority": "u=1, i",
            "referer": "https://auth.ticketmaster.com/as/authorization.oauth2?client_id=8bf7204a7e97.web.ticketmaster.us&response_type=code&scope=openid%20profile%20phone%20email%20tm&redirect_uri=https://identity.ticketmaster.com/exchange&visualPresets=tm&lang=en-us&placementId=mytmlogin&hideLeftPanel=false&integratorId=prd1741.iccp&intSiteToken=tm-us&TMUO=east_Yy+wr1Nf+xmww4O9ewBePc8SMn3/TKSDNBl6qJi7Lxk=&deviceId=xgSNBg0DvDU3NDc6OjY2Njo9Mz1i4D%2FZ9cE4fQ&doNotTrack=true",
            "sec-ch-ua": '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"macOS\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "tm-client-id": "8bf7204a7e97.web.ticketmaster.us",
            "tm-integrator-id": "prd1741.iccp",
            "tm-oauth-type": "tm-auth",
            "tm-placement-id": "mytmlogin",
            "tm-site-token": "tm-us",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
        }
    )

def test_with_nudata():
    nudata_header = requests.get(
        "https://nudata.takionapi.tech/generate", 
        params={
            "url": "https://nudata.ticketmaster.com/2.2/w/w-481390/sync/js/",
            "api_key": API_KEY
        }
    ).json()["result"]
    return requests.post(
        "https://auth.ticketmaster.com/json/sign-in", 
        json={
            "email": "exampleuser@gmail.com",
            "password": "example!",
            "rememberMe": False,
            "externalUserToken": None
        }, 
        headers={
            "accept": "*/*",
            "accept-language": "en-us",
            "content-type": "application/json",
            "nds-pmd": nudata_header, # We are passing nudata header
            "origin": "https://auth.ticketmaster.com",
            "priority": "u=1, i",
            "referer": "https://auth.ticketmaster.com/as/authorization.oauth2?client_id=8bf7204a7e97.web.ticketmaster.us&response_type=code&scope=openid%20profile%20phone%20email%20tm&redirect_uri=https://identity.ticketmaster.com/exchange&visualPresets=tm&lang=en-us&placementId=mytmlogin&hideLeftPanel=false&integratorId=prd1741.iccp&intSiteToken=tm-us&TMUO=east_Yy+wr1Nf+xmww4O9ewBePc8SMn3/TKSDNBl6qJi7Lxk=&deviceId=xgSNBg0DvDU3NDc6OjY2Njo9Mz1i4D%2FZ9cE4fQ&doNotTrack=true",
            "sec-ch-ua": '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"macOS\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "tm-client-id": "8bf7204a7e97.web.ticketmaster.us",
            "tm-integrator-id": "prd1741.iccp",
            "tm-oauth-type": "tm-auth",
            "tm-placement-id": "mytmlogin",
            "tm-site-token": "tm-us",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
        }
    )

if __name__ == "__main__":
    print("Response without nudata header:", test_without_nudata().status_code)
    response = test_with_nudata()
    print("Response with nudata header:", response.status_code, " / ", response.json())
```

{% endtab %}
{% endtabs %}


# GeeTest

A GeeTest solver without a browser. Takion solves GeeTest's slide, puzzle, icon, AI, .. challenges and returns the validation payload, so your requests get through without you clicking anything.

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is GeeTest?**

GeeTest is a widely used CAPTCHA provider that challenges users with several types of captcha, such as slides, puzzles, and AI-based captchas. Most sites use v3, and some have transitioned to v4. The two versions return different payload shapes:

* **v3**: `{'geetest_challenge': ..., 'geetest_validate': ..., 'geetest_seccode': ...}`
* **v4**: `{'captcha_id': ..., 'lot_number': ..., 'pass_token': ..., 'captcha_output': ...}`

<figure><img src="/files/T1BGKHZzXdA0DE4gskuY" alt="" width="225"><figcaption></figcaption></figure>

<figure><img src="/files/kxJhhBWRsYcG8DnXQ7vj" alt="" width="225"><figcaption></figcaption></figure>


# v3 Bypass Solution

The GeeTest v3 solver endpoint takes the captcha's gt and challenge parameters and returns the validation payload, so you never render or solve the widget yourself.

### How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass a GeeTest v3 captcha:

1. Parse the `gt` and `challenge` parameters (found in the page's HTML or from a specific endpoint).
2. Send the `gt` and `challenge` to our API, and retrieve the response.

### Endpoint <a href="#endpoint" id="endpoint"></a>

```
GET https://geetest.takionapi.tech/v3
```

### **Parameters**:

* **gt** (required): The captcha's gt parameter.
* **challenge** (required): The captcha's challenge parameter.
* **proxy** (optional): Proxy for solving (format: `ip:port` or `ip:port:mail:password`).

### Example Response

```json
{
  "response": {
    "geetest_challenge": "567fc6015320e44041dad5e517c73499",
    "geetest_validate": "ee08eee1cd458f705174a7638b74845b",
    "geetest_seccode": "ee08eee1cd458f705174a7638b74845b|jordan"
  }
}
```

{% hint style="info" %}
In order to access any of our endpoint you'll need **a valid API Key,** either [join our discord](https://takionapi.tech/discord) for a trial or [puchase a plan](https://takionapi.tech/buy)
{% endhint %}

## Solve GeeTest v3

> Solves a GeeTest v3 slide/click captcha from its \`gt\` and \`challenge\` values and returns the validated solution (\`geetest\_challenge\`, \`geetest\_validate\`, \`geetest\_seccode\`). GET with query params also works.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — GeeTest","version":"1.0.0"},"servers":[{"url":"https://geetest.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"V3Request":{"type":"object","description":"Provide `gt` and `challenge` (at least one is required).","properties":{"gt":{"type":"string","description":"The GeeTest `gt` value from the target."},"challenge":{"type":"string","description":"The GeeTest `challenge` value from the target."},"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format (optional)."}},"additionalProperties":true},"SolveResponse":{"type":"object","properties":{"response":{"type":"object","description":"The validated GeeTest solution — v3 carries `geetest_challenge`/`geetest_validate`/`geetest_seccode`; v4 carries `lot_number`/`pass_token`/`gen_time`/`captcha_output`.\n","additionalProperties":true}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Missing input returns 400, auth/quota 401, and an unsolvable captcha or unexpected failure returns 500.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v3":{"post":{"operationId":"solveGeetestV3","summary":"Solve GeeTest v3","description":"Solves a GeeTest v3 slide/click captcha from its `gt` and `challenge` values and returns the validated solution (`geetest_challenge`, `geetest_validate`, `geetest_seccode`). GET with query params also works.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3Request"}}}},"responses":{"200":{"description":"The solved v3 payload under `response`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolveResponse"}}}},"400":{"description":"Missing input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"description":"The captcha could not be solved, or an unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# v4 Bypass Solution

The GeeTest v4 solver endpoint takes the captcha's captcha\_id and returns the validation payload for slide, AI, puzzle, and icon challenges, so you never render or solve the widget yourself.

### How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass a GeeTest v4 captcha:

1. Parse the `captcha_id` and (optionally) `kind` from the captcha. The kind defaults to `ai` but may vary based on the captcha type (for example slide, puzzle, icon).
2. Send the `captcha_id` to our API, and retrieve the response.

### Endpoint <a href="#endpoint" id="endpoint"></a>

```
GET https://geetest.takionapi.tech/v4
```

### **Parameters**:

* **captcha\_id** (required): The captcha's `captcha_id`.
* **kind** (optional): The type of captcha to solve (defaults to "slide").
* **proxy** (optional): Proxy for solving (format: `ip:port` or `ip:Port:mail:password`).

### **Example Response**:

```json
{
  "response": {
    "captcha_id": "fcd636b4514bf7ac4143922550b3008b",
    "lot_number": "e4c0b946b91c4aeabbc343b9a0f048ca",
    "pass_token": "4856da4c49ca...3edea00d688e",
    "gen_time": "1725490466",
    "captcha_output": "Vt45iXQep...=="
  }
}
```

{% hint style="info" %}
In order to access any of our endpoint you'll need **a valid API Key,** either [join our discord](https://takionapi.tech/discord) for a trial or [puchase a plan](https://takionapi.tech/buy)
{% endhint %}

## Solve GeeTest v4

> Solves a GeeTest v4 captcha from its \`captcha\_id\` and returns the validated solution (\`lot\_number\`, \`pass\_token\`, \`gen\_time\`, \`captcha\_output\`) under \`response\`. GET with query params also works.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — GeeTest","version":"1.0.0"},"servers":[{"url":"https://geetest.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"V4Request":{"type":"object","required":["captcha_id"],"properties":{"captcha_id":{"type":"string","description":"The GeeTest v4 `captcha_id` from the target."},"kind":{"type":"string","description":"Challenge kind.","default":"ai"},"proxy":{"type":"string","description":"Proxy in `ip:port` or `ip:port:user:pass` format (optional)."}},"additionalProperties":true},"SolveResponse":{"type":"object","properties":{"response":{"type":"object","description":"The validated GeeTest solution — v3 carries `geetest_challenge`/`geetest_validate`/`geetest_seccode`; v4 carries `lot_number`/`pass_token`/`gen_time`/`captcha_output`.\n","additionalProperties":true}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Missing input returns 400, auth/quota 401, and an unsolvable captcha or unexpected failure returns 500.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v4":{"post":{"operationId":"solveGeetestV4","summary":"Solve GeeTest v4","description":"Solves a GeeTest v4 captcha from its `captcha_id` and returns the validated solution (`lot_number`, `pass_token`, `gen_time`, `captcha_output`) under `response`. GET with query params also works.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4Request"}}}},"responses":{"200":{"description":"The solved v4 payload under `response`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolveResponse"}}}},"400":{"description":"Missing input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"description":"The captcha could not be solved, or an unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Example Implementations

{% hint style="info" %}
Like any captcha, it is normal to have some unolvable captchas sometimes, just load and solve a new one
{% endhint %}

{% tabs %}
{% tab title="v3" %}

```python
from requests import get, post
from time import time

API_KEY = "TAKION_API_XXXX"

def load_geetestv3(challenge_type: str):
    if challenge_type.lower() not in ["slide", "icon"]:
        print(f"Invalid challenge '{challenge_type}")
        return False
    
    url = f'https://www.geetest.com/demo/gt/register-en{challenge_type.capitalize()}-official?t={time() * 1000}'
    return get(url).json()

def solve_geetest(challange, gt):
    params = {
        "challenge": challange,
        "gt": gt,
        "api_key": API_KEY
    }
    url = "https://geetest.takionapi.tech/v3"

    return get(url, params=params).json()

if __name__ == '__main__':
    for challenge in ["slide", "icon"]:
        print(f"Loading {challenge} challenge...")
        challenge_details = load_geetestv3(challenge)
        print(f"Solving... {challenge_details['challenge']}")
        response = solve_geetest(challenge_details['challenge'], challenge_details['gt'])
        print(f"Response: {response}")
```

{% endtab %}

{% tab title="v4" %}

```python

from requests import get, post
from time import time

API_KEY = "TAKION_API_XXXX"

def solve_geetest(captcha_id, kind):
    params = {
        "captcha_id": captcha_id,
        "kind": kind,
        "api_key": API_KEY
    }
    url = "https://geetest.takionapi.tech/v4"

    return get(url, params=params).json()

if __name__ == '__main__':
    for challenge in ["slide", "ai"]:
        print(f"Solving {challenge} challenge...")
        response = solve_geetest(
            "fcd636b4514bf7ac4143922550b3008b",
            challenge
        )
        print(f"Response: {response}")
```

{% endtab %}
{% endtabs %}


# Incapsula / Imperva

An Incapsula (now Imperva) bypass without a browser. Takion generates the reese84 and \_\_\_utmvc cookies that Imperva's wall demands, so your requests get through and stay through.

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## **What is Incapsula (now Imperva)?**

Incapsula is a Web Application Firewall (WAF) that shields websites from attacks like DDoS, bot traffic, and other threats by scrutinizing web traffic and determining whether it is human or automated. It often requires specific cookies, such as `reese84` or `___utmvc`, to grant access to the website.

## Detecting an Incapsula site <a href="#detecting-an-incapsula-site" id="detecting-an-incapsula-site"></a>

Websites protected by Incapsula typically use these cookies to validate user sessions:

* **reese84**: Required on many ticketing websites; generated via a valid encrypted payload.
* **\_\_\_utmvc**: A cookie that checks browser information and is often seen on sites that use Incapsula.

You can detect Incapsula protection by observing the presence of these cookies in the network requests. If the website serves an interstitial block or requires interaction with these cookies, it is an indicator that the site uses Incapsula for security.

When accessing an Incapsula-protected website, your request may be intercepted by the WAF. The site checks for the presence of the required cookies (`reese84`, `___utmvc`). Without these, you will either be blocked or challenged. For example:

* **reese84 WAF**: Requires both the `reese84` cookie and solving a captcha (such as GeeTest) to navigate the site.
* **\_\_\_utmvc WAF**: A solved GeeTest captcha provides the necessary cookies to continue browsing.

## **Incapsula Cookies and Challenges**

Incapsula uses two cookies to track users and allow access:

* **reese84 Cookie**: This is generated using a valid payload. Without it, many websites will block your session.
* **\_\_\_utmvc Cookie**: This cookie validates browser-specific information .

If you encounter them on a website, it is protected by Incapsula / Imperva.

### **Incapsula WAF Challenges**

Incapsula recently introduced a new WAF for reese84 websites (which currently get a direct block), with a different type based on the [GeeTest captcha](https://www.geetest.com/). It is present only on some websites, together with either the `___utmvc` or `reese84` cookie, for example the SmythsToys website.

<img src="https://github.com/Takion-API-Services/TakionAPI-Examples/raw/main/incapsula/media/waf__utmvc.png" alt="___utmvc WAF" width="375">

**reese84 WAF**

In the case of a reese84 WAF, the website will require a new valid reese84 cookie and a solved GeeTest captcha.

**\_\_\_utmvc WAF**

Unlike the other challenges, it requires only the GeeTest captcha token and will set some `incap_sh_xxx` cookies.

### Some sites using Incapsula <a href="#some-sites-using-incapsula" id="some-sites-using-incapsula"></a>

Many high-traffic and ticketing websites use Incapsula for security. These sites typically rely on `reese84` or `___utmvc` cookies. A few examples:

| Website                                                                      | reese84 | \_\_\_utmvc | WAF |
| ---------------------------------------------------------------------------- | ------- | ----------- | --- |
| [ticketmaster.com](https://www.ticketmaster.com/) (and other US domains)     | ✅       |             |     |
| [ticketmaster.co.uk](https://www.ticketmaster.co.uk/) (and other EU domains) | ✅       |             | ✅\* |
| [tickets.rolandgarros.com](https://tickets.rolandgarros.com/)                |         | ✅           |     |
| [smythstoys.com](https://www.smythstoys.com/)                                | ✅       | ✅           | ✅   |
| [eticketing.co.uk](https://www.eticketing.co.uk/)                            | ✅       |             |     |

\**Only some Ticketmaster EU websites use a reese84 WAF.*


# reese84 Bypass Solution

The reese84 cookie is the core of an Incapsula bypass on ticketing sites. Load the challenge script, send it to Takion, and post the payload we return to retrieve a valid reese84 cookie.

## How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass Incapsula's (Imperva's) protection, follow these steps:

1. **Load the script content.**
2. **Generate the challenge payload** (using our API).
3. **Post the payload** to retrieve the Incapsula cookie.

#### How to identify the script URL <a href="#how-to-identify-the-script-url" id="how-to-identify-the-script-url"></a>

After visiting the target website, open your browser inspector tools and click on the network tab. The browser should have sent a request to a URL like `https://whatever.com/anoy-route?d=www.yourtargetwebsite.com`.

This is the script tag. All the responses should have returned a JSON body with `token` as one of the keys.

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the Castle subdomain:

```
https://incapsula.takionapi.tech/reese84
```

## Generate the reese84 payload

> Send the reese84 challenge script (fetched from the target's \`?d=\<domain>\` route) and get back the challenge payload. Post that payload to the site's reese84 endpoint; the response carries the \`token\` to set as the \`reese84\` cookie.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — Incapsula / Imperva","version":"1.0.0"},"servers":[{"url":"https://incapsula.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"Reese84Request":{"type":"object","required":["script"],"properties":{"script":{"type":"string","description":"The response text of the reese84 challenge script fetched from the target site (the `?d=<domain>` route whose JSON body contains `token`).\n"}},"additionalProperties":true},"Reese84Response":{"type":"object","properties":{"payload":{"type":"string","description":"The challenge payload. Post it to the site's reese84 endpoint; the response contains the `token` to set as the `reese84` cookie.\n"}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors are returned with this same shape — always check for `error`.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/reese84":{"post":{"operationId":"generateReese84","summary":"Generate the reese84 payload","description":"Send the reese84 challenge script (fetched from the target's `?d=<domain>` route) and get back the challenge payload. Post that payload to the site's reese84 endpoint; the response carries the `token` to set as the `reese84` cookie.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reese84Request"}}}},"responses":{"200":{"description":"The challenge payload. On a bad request an `error` field is returned instead — check for `error` before reading `payload`.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Reese84Response"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# \_\_\_utmvc Bypass Solution

The \_\_\_utmvc cookie is the second path through an Incapsula bypass. Find the \_Incapsula\_Resource script, send its content to Takion, and we return the \_\_\_utmvc cookie to set on your session.

### How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass Incapsula's (Imperva's) protection, follow these steps:

1. **Find the \_\_\_utmvc script URL.**
2. **Load the script content.**
3. **Generate the cookie based on it** (using our API).

### How to identify the script URL <a href="#how-to-identify-the-script-url" id="how-to-identify-the-script-url"></a>

After visiting the target website, you can easily search for the following regex inside the HTML content. It will find and extract the needed URL.

`src="(/_Incapsula_Resource?[^"]+)"`

### Endpoint <a href="#endpoint" id="endpoint"></a>

The endpoint lives on the Castle subdomain:

```
https://incapsula.takionapi.tech/utmvc
```

## Generate the \_\_\_utmvc cookie

> Send the \`\_Incapsula\_Resource\` script content plus your current session cookies and get back the \`\_\_\_utmvc\` cookie to set before retrying the original request.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — Incapsula / Imperva","version":"1.0.0"},"servers":[{"url":"https://incapsula.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"UtmvcRequest":{"type":"object","required":["content","cookies"],"properties":{"content":{"type":"string","description":"The response text of the `_Incapsula_Resource` challenge script fetched from the target site.\n"},"cookies":{"type":"array","description":"The current session cookies as `[name, value]` pairs.","items":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":2}}},"additionalProperties":true},"UtmvcResponse":{"type":"object","properties":{"___utmvc":{"type":"string","description":"The `___utmvc` cookie value to set on your session."}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors are returned with this same shape — always check for `error`.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/utmvc":{"post":{"operationId":"generateUtmvc","summary":"Generate the ___utmvc cookie","description":"Send the `_Incapsula_Resource` script content plus your current session cookies and get back the `___utmvc` cookie to set before retrying the original request.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UtmvcRequest"}}}},"responses":{"200":{"description":"The `___utmvc` cookie. On a bad request an `error` field is returned instead — check for `error` first.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UtmvcResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="reese84" %}

```python
from requests import post
from tls_client import Session

API_KEY = "TAKION_API_XXX" # Fill it with your api key

if __name__ == "__main__":
    session = Session(client_identifier="chrome_111")
    response = session.get("https://www.ticketmaster.es/epsf/eps-d", headers={
        "accept": "application/json; charset=utf-8",
        "accept-language": "en-GB,en;q=0.9",
        "content-type": "text/plain; charset=utf-8",
        "origin": "null",
        "priority": "u=1, i",
        "sec-ch-ua": '"Chromium";v="125", "Google Chrome";v="125", "Not-A.Brand";v="99"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"macOS\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "cross-site",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
    })

    challenge_payload = post(
        "https://incapsula.takionapi.tech/reese84", 
        json={
            "script": response.text
        },
        headers={
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
            "x-api-key": API_KEY
        }
    ).json()['payload']

    response = session.post(
        "https://epsf.ticketmaster.es/eps-d", 
        headers={
            "accept": "application/json; charset=utf-8",
            "accept-language": "en-GB,en;q=0.9",
            "content-type": "text/plain; charset=utf-8",
            "origin": "null",
            "priority": "u=1, i",
            "sec-ch-ua": '"Chromium";v="125", "Google Chrome";v="125", "Not-A.Brand";v="99"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"macOS\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "cross-site",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
        }, 
        data=challenge_payload,
        params={"d":"www.ticketmaster.es"}
    )
    response = response.json()
    
    # Set cookie
    session.cookies.set("reese84", response['token'])

    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'accept-language': 'en-GB,en;q=0.9',
        'cache-control': 'max-age=0',
        'priority': 'u=0, i',
        'referer': 'https://availability.ticketmaster.es/api/v2/TM_NL/availability/299807?subChannelId=1',
        'sec-ch-ua': '"Chromium";v="125", "Google Chrome";v="125", "Not-A.Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'document',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'same-origin',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
    }
    params = (
        ('subChannelId', '1'),
    )

    response = session.get('https://availability.ticketmaster.es/api/v2/TM_ES/availability/39185', headers=headers, params=params)
    print(response.text)
```

{% endtab %}

{% tab title="\_\_\_utmvc" %}

```python
from requests import Session, post
from re import search

def is_challenge(response):
    pattern = r'src="(/_Incapsula_Resource\?[^"]+)"'
    match = search(pattern, response.text)
    return f"https://{response.url.split('/')[2]}/{match.group(1)}" if match else False

if __name__ == "__main__":
    API_KEY = "TAKION_API_XXX" # Your api key here

    session = Session()
    url = "https://tickets.rolandgarros.com/fr/"
    headers = {
        'Host': 'tickets.rolandgarros.com',
        'cache-control': 'max-age=0',
        'sec-ch-ua': '"Google Chrome";v="112", "Chromium";v="112", "Not?A_Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'sec-fetch-site': 'none',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-user': '?1',
        'sec-fetch-dest': 'document',
        'accept-language': 'en-GB,en;q=0.9',
    }
    response = session.get(url, headers=headers)
    if not (challenge_url := is_challenge(response)):
        print("Page loaded successfully")
        exit(0)

    print(f"Found challenge, solving...")

    # Load challenge
    challenge = session.get(challenge_url, headers={
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
    })

    # Solve the challenge
    takion_response = post(
        f"https://incapsula.takionapi.tech/utmvc?api_key={API_KEY}",
        json={
            "content": challenge.text,
            "cookies": [[name, value] for name, value in session.cookies.items()]
        },
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
        }
    ).json()
    if (error := takion_response.get("error")):
        print(f"Error: {error}")
        exit(1)
    
    # Set the utmvc cookie
    utmvc = takion_response["___utmvc"]
    session.cookies.set("___utmvc", utmvc)
    print(f"Got cookie: {utmvc[:15]}...{utmvc[-15:]}")
    # Now we send the original request again
    response = session.get(url, headers=headers)
    print(f"Challenge {'' if is_challenge(response) else 'not '}found using cookie")
```

{% endtab %}
{% endtabs %}


# Common Errors & Troubleshooting

## **What User-Agent Should I Pass when solving the challenges?**

It is required to pass the same User-Agent you are using during your whole session interactions to our APIs.

## **Even with a reese84 cookie I'm unable to access the website**

This error is probably due an either invalid proxy or bad TLS details. If you are experiencing it feel free to contact us after double checking both your flow and pool of proxies.


# AWS Cognito

An AWS Cognito bypass without a browser. Takion generates the cognitoAsfData token from the browser signals and the email you are logging in with, so your login request clears Cognito.

{% hint style="info" %}
Check our example bundles in order to validate your implementation against our validate ones, with correct headers order, TLS and flow from our [**Github repo**](https://takionapi.tech/examples)
{% endhint %}

## What is AWS Cognito? <a href="#what-is-aws-cognito" id="what-is-aws-cognito"></a>

AWS Cognito is used by some platforms for secure authentication based on browser details. Its advanced security feature (ASF) inspects the device and browser fingerprint of whoever is signing in and expects a matching token to be sent alongside the username and password. Without that token, or with one that does not match the request, the login is rejected.

### Some sites using AWS Cognito <a href="#some-sites-using-aws-cognito" id="some-sites-using-aws-cognito"></a>

| Website                                     |
| ------------------------------------------- |
| [Ticketmaster SG](https://ticketmaster.sg/) |


# Bypass Solution

The AWS Cognito bypass endpoint takes the website domain and the email you are signing in with and returns a JSON payload containing the cognitoAsfData token.

### How the solution works <a href="#how-the-solution-works" id="how-the-solution-works"></a>

To bypass AWS Cognito:

1. Send our endpoint the website domain and email.
2. Parse the response and use it as `cognitoAsfData`.

### Endpoint <a href="#endpoint" id="endpoint"></a>

```
GET https://cognito.takionapi.tech/generate
```

## Generate cognitoAsfData

> Returns the \`cognitoAsfData\` token for the given site and username. Send your session's \`User-Agent\`, \`Sec-Ch-Ua\`, and \`Accept-Language\` headers for a more accurate token. Attach the returned token to your Cognito login request as \`cognitoAsfData\`.<br>

```json
{"openapi":"3.0.3","info":{"title":"Takion API — AWS Cognito","version":"1.0.0"},"servers":[{"url":"https://cognito.takionapi.tech"}],"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"GenerateResponse":{"type":"object","description":"The token payload. The endpoint page documents the token under `response`; the examples page reads it as `result` — confirm the exact key against the live service. Either way, the value is the `cognitoAsfData` token.\n","properties":{"response":{"type":"string","description":"The `cognitoAsfData` token to attach to your login request."}},"additionalProperties":true},"Error":{"type":"object","required":["error"],"description":"Every error is a JSON object with a single `error` string. Auth/quota problems return HTTP 401 and unexpected failures 500; input-validation errors are returned with this same shape — always check for `error`.\n","properties":{"error":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Authentication or quota failure — HTTP 401 with an `error` message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServerError":{"description":"Unexpected server error (HTTP 500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/generate":{"get":{"operationId":"generateCognitoAsfData","summary":"Generate cognitoAsfData","description":"Returns the `cognitoAsfData` token for the given site and username. Send your session's `User-Agent`, `Sec-Ch-Ua`, and `Accept-Language` headers for a more accurate token. Attach the returned token to your Cognito login request as `cognitoAsfData`.\n","parameters":[{"name":"website","in":"query","required":true,"description":"The target website domain.","schema":{"type":"string"}},{"name":"username","in":"query","required":true,"description":"The username / email you are authenticating with.","schema":{"type":"string"}}],"responses":{"200":{"description":"The token payload. On a bad request an `error` field is returned instead — check for `error` first.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/GenerateResponse"},{"$ref":"#/components/schemas/Error"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}}}}}
```


# Example Implementations

{% tabs %}
{% tab title="Ticketmaster SG Login" %}

```python
from tls_client import Session
from requests import get, post
from bs4 import BeautifulSoup

if __name__ == "__main__":
    API_KEY = "TAKION_API_XXX" # Fill it with your api key
    MAIL = "email" # Your TM SG Mail
    PASSWORD = "pw" # Your TM SG Password

    session = Session("chrome_112")
    headers = {
        'Host': 'ticketmaster.sg',
        'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'sec-fetch-site': 'same-origin',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-user': '?1',
        'sec-fetch-dest': 'document',
        'referer': 'https://ticketmaster.sg/',
        'accept-language': 'en-GB,en;q=0.9',
    }

    # ------------------------- Generate reese84 ------------------------- #
    response = session.get("https://epsf.ticketmaster.sg/eps-d", headers={
        "accept": "application/json; charset=utf-8",
        "accept-language": "en-GB,en;q=0.9",
        "content-type": "text/plain; charset=utf-8",
        "origin": "null",
        "priority": "u=1, i",
        "sec-ch-ua": '"Chromium";v="125", "Google Chrome";v="125", "Not-A.Brand";v="99"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"macOS\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "cross-site",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
    })

    challenge_payload = post(
        "https://incapsula.takionapi.tech/reese84", 
        json={
            "script": response.text
        },
        headers={
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
            "x-api-key": API_KEY
        }
    ).json()['payload']

    response = session.post(
        "https://epsf.ticketmaster.sg/eps-d", 
        headers={
            "accept": "application/json; charset=utf-8",
            "accept-language": "en-GB,en;q=0.9",
            "content-type": "text/plain; charset=utf-8",
            "origin": "null",
            "priority": "u=1, i",
            "sec-ch-ua": '"Chromium";v="125", "Google Chrome";v="125", "Not-A.Brand";v="99"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"macOS\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "cross-site",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
        }, 
        data=challenge_payload,
        params={"d":"www.ticketmaster.sg"}
    )
    response = response.json()
    
    # Set cookie
    session.cookies.set("reese84", response['token'])

    print("Starting...")
    
    # ------------------------- Load CSRF Token  ------------------------- #
    response = session.get('https://ticketmaster.sg/login', headers=headers)

    if (redirect := response.headers.get("Location")):
        response = session.get(redirect, headers=headers)

    headers = {
        'Host': 'main.login.ticketmaster.sg',
        'cache-control': 'max-age=0',
        'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'upgrade-insecure-requests': '1',
        'origin': 'https://main.login.ticketmaster.sg',
        'content-type': 'application/x-www-form-urlencoded',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'sec-fetch-site': 'same-origin',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-user': '?1',
        'sec-fetch-dest': 'document',
        'referer': 'https://main.login.ticketmaster.sg/login?client_id=6vdm5j83n4tc6i0ul4nm9ms6dm&redirect_uri=https%3A%2F%2Fticketmaster.sg%2Flogin&response_type=code&scope=phone+email+openid+aws.cognito.signin.user.admin',
        'accept-language': 'en-GB,en;q=0.9',
    }

    # ------------------------- Generate cognito ------------------------- #
    response = get(
        "https://cognito.takionapi.tech/generate",
        params={
            "api_key": API_KEY,
            "website": "www.ticketmaster.sg",
            "username": MAIL
        },
        headers={
            "User-Agent": headers["user-agent"],
            "sec-ch-ua": headers["sec-ch-ua"]
        }
    ).json()["result"]

    # ------------------------- Login into acc.  ------------------------- #
    response = session.post(
        'https://main.login.ticketmaster.sg/login', 
        params={
            'client_id': '6vdm5j83n4tc6i0ul4nm9ms6dm',
            'redirect_uri': 'https://ticketmaster.sg/login',
            'response_type': 'code',
            'scope': 'phone email openid aws.cognito.signin.user.admin',
        },  
        headers=headers, 
        data={
            '_csrf': session.cookies.get_dict()["XSRF-TOKEN"],
            'username': MAIL,
            'password': PASSWORD,
            'cognitoAsfData': response,
            'signInSubmitButton': 'Sign in',
        }
    )
    if (redirect := response.headers.get("Location")):
        response = session.get(redirect, headers=headers)
    if (redirect := response.headers.get("Location")):
        response = session.get(redirect, headers=headers)
    
    soup = BeautifulSoup(response.text, "html.parser")
    if not (account_data := soup.find("div", {"id": "accountFunc"})):
        print(soup.find("p", {"id": "loginErrorMessage"}).text)
        exit(0)

    print("Logged in as " + account_data.find("div").text)
```

{% endtab %}
{% endtabs %}


# Other solutions

If the wall you are facing is not documented here, that almost always means it is available on request, not that we cannot do it.

### Also supported <a href="#also-supported" id="also-supported"></a>

Beyond the documented endpoints, we work with vendors such as:

* **Akamai** Bot Manager (sensor data, `_abck`, `bm_sz`)
* **Cloudflare** (Turnstile, Managed Challenge, `cf_clearance`)
* **reCAPTCHA** (v2 / v3 / Enterprise)
* **Arkose Labs** / FunCaptcha
* **hCaptcha, GeeTest** and other captcha vendors
* …and more

Some of these have public endpoints elsewhere in these docs. Others we run privately for specific customers and flows.

{% hint style="info" %}
Facing a wall we do not document, or want a vendor added? Bring your specific use case [contact us](https://takionapi.tech/contact) or reach out on [Discord](https://takionapi.tech/discord). We will tell you what is already possible and what we can build.
{% endhint %}

### New walls on request <a href="#new-walls-on-request" id="new-walls-on-request"></a>

Hitting something that is not on any list? That is the normal case for us, not the exception. Tell us the target, the flow, and the challenge you are seeing, and we will scope adding support — as a public API, a private endpoint, or a [custom module](/modules).

We ship new vendor support regularly, driven directly by user requests.


# Frameworks & Modules

Takion is more than the bypass APIs. We take on custom solutions, custom development, and ship ready-to-drop-in modules. So when a wall, flow, or captcha is not in the public catalog, we build it.

Here is what a "module" looks like at Takion, with three examples you can build on today.

## Queue-IT

A versatile Queue-it module compatible with any queue / virtual-waiting-room setup — the queue challenge, the Softblock page, proof-of-work, and the enqueue token, handled end to end.

{% content-ref url="/pages/lBczMgujwuV4Ee7KUUrs" %}
[Queue-IT Module](/modules/queueit)
{% endcontent-ref %}

### Adyen and riskData <a href="#adyen-riskdata" id="adyen-riskdata"></a>

Client-side payment encryption and the `riskData` blob, generated for any version of the target so your checkout and payment calls go through. Drop-in module, no browser.

{% content-ref url="/pages/5M00hfPRjxOsbYKmbXmj" %}
[Adyen and riskData](/modules/adyen)
{% endcontent-ref %}

### Image-to-text captcha (we train a model for you) <a href="#image-to-text-captcha--we-train-a-model-for-you" id="image-to-text-captcha--we-train-a-model-for-you"></a>

We train a custom OCR model on your specific challenge and hand you an endpoint that returns the answer with a nearly 100% sucess rate. Open to hand you the model as well.&#x20;

{% content-ref url="/pages/1F4ZbNppJHWFy6oTFdpK" %}
[Image-to-Text Captchas / OCR](/modules/ocr)
{% endcontent-ref %}

### More custom work <a href="#more-custom-work" id="more-custom-work"></a>

These three are just examples. We also ship and build:

* A full suite of tools for **Ticketmaster**, across all subdomains (`.com`, `.co.uk`, `.sg`, …).
* Frameworks and bots for a range of sites (Arsenal, Tottenham, BVB, Liverpool, and more).
* **Website automation**, such as **antibot solutions**, and custom **encryption / signing** methods.
* **Source code** for our services, we are open to discussing offers.

If you can describe it, we can probably build it.

<a href="https://takionapi.tech/contact" class="button primary">Contact us</a>


# Adyen and riskData

Adyen bypass for any website version. Takion works around Adyen's client-side payment encryption and its riskData layer with either an API or source code, so your checkout automation keeps running.

## What is Adyen? <a href="#what-is-adyen" id="what-is-adyen"></a>

Adyen is a client-side payment encryption method widely used by websites to protect checkout-related actions from automated scripts. It implements a robust encryption system designed to prevent bots and scripts from performing fraudulent transactions. Adyen often incorporates **riskData**, a supplementary protection layer aimed at identifying and blocking automated browsers and scripts from interacting with the website.

### Our solutions <a href="#our-solutions" id="our-solutions"></a>

We offer both **APIs** and **source code** tailored to work with **any version** of any website using Adyen. Whether you are a developer looking to integrate or modify the Adyen encryption for custom use, or you simply need a ready-to-use package, we have flexible options to fit your needs.

Our services ensure that you can seamlessly work around Adyen's encryption methods and riskData implementations while maintaining the integrity and security of the checkout process.

### What we provide <a href="#what-we-provide" id="what-we-provide"></a>

* **APIs** for direct integration with websites using Adyen.
* **Source code** for developers or companies looking to implement custom solutions.
* **Ready-to-go modules** for quick deployment.

If you need further customization, riskData handling, or any additional information, contact us on [Discord](https://takionapi.tech/discord). We are here to help with any unique requirements you may have.

### Example videos <a href="#example-videos" id="example-videos"></a>

{% embed url="<https://youtu.be/F6uPN34Y_oo>" %}

{% embed url="<https://youtu.be/aLEHcGAZACU>" %}


# Queue-IT Module

A Queue-IT bypass module in Python that handles every part of Queue-It queues, including the queue challenges, the Softblock page, and in-house OCR. We offer it both via APIs and as source code.

## About the module <a href="#about-the-module" id="about-the-module"></a>

The module comes with detailed README files and docstrings for everything, providing clear instructions and explanations. We also offer support and include improvements and updates.

### Easy translation <a href="#easy-translation" id="easy-translation"></a>

Our Python module is designed with simplicity in mind and can be easily translated into other languages.

### Access to Git repositories <a href="#access-to-git-repositories" id="access-to-git-repositories"></a>

When you purchase our Python module, we provide access to the Git repositories that contain the module. This gives you the ability to explore the code, understand how it works, and make any modifications if necessary, as well as access to all future updates.

### **Recent updates**

We recently added an improvement that handles the login for Ticketmaster with OTP handling and queue URL generation.

### Demonstration videos <a href="#demonstration-videos" id="demonstration-videos"></a>

Here are a couple of videos demonstrating the module in action:

* OTP confirmation and Queue URL generation: [Watch Video](https://youtu.be/tgg6Uli_RX8)
* Softblock and Queue-IT (Proof of Work): [Watch Video](https://youtu.be/6TTTDIlCVYE)

We support any type of challenge, enqueue token, and any type of options on the queue. For more detailed information or to purchase it, [join our Discord server](https://takionapi.tech/discord) and contact us.

{% embed url="<https://youtu.be/tgg6Uli_RX8>" %}

{% embed url="<https://www.youtube.com/watch?ab_channel=glizzy&v=6TTTDIlCVYE>" %}


# Image-to-Text Captchas / OCR

We train a model on the exact captcha you're fighting.

## Why a custom model wins <a href="#why-a-custom-model-wins" id="why-a-custom-model-wins"></a>

An OCR model is only as good as what it was trained on. The public solvers see a huge generic mix and do fine on the average captcha. Your target isn't the average captcha.

Train on the specific font, warp, colors, and noise of one challenge and the accuracy jumps. It's not magic, it's just the right training set. A model that only has to read one style of captcha beats a model that has to read everything.

Other than that, using a big vision model that will use unecessary usage and memory on production for a small task, is never a good choice.

#### We ensure

* A near 100% pass rate
* A fraction of milliseconds for the resolution
* An almost inexistent resources usage

### **Example of Captchas**

Our OCR model accepts a wide range of images for solving and is optimized for specific captchas. We can also implement new captchas based on client requests with near-perfect accuracy.

{% hint style="info" %}
Facing those or other custom-website's captchas? [Contact us](https://takionapi.tech/contact) for finding the best solution for your use case
{% endhint %}

#### **Queue-IT's BotDetect**

Queue-IT and SoftBlock provide image-to-text challenges known as BotDetect, which our API can solve efficiently.

<figure><img src="/files/ZPbQxLtZMX4Nu9HiCs20" alt="" width="375"><figcaption></figcaption></figure>

#### **TicketMaster SG's Captchas (ATC & Checkout)**

Our API quickly and accurately handles TicketMaster SG's image-to-text captchas during ATC and Checkout processes, using advanced pre- and post-processing of images.

<figure><img src="/files/579vqIPHkcmxorIvhCWV" alt=""><figcaption></figcaption></figure>


# Bypass Solution

Our solution automates the solving of an Image-To-Text captcha

## **How the Solution Works**

1. Pass us the image as a base64
2. Retrieve the response.

{% hint style="info" %}
In order to access any of our endpoint you'll need **a valid API Key,** either [join our discord](https://takionapi.tech/discord) for a trial or [puchase a plan](https://takionapi.tech/buy)
{% endhint %}

{% openapi src="/files/AQRKb9xZfCwrdVHA0uk5" path="/ocr" method="post" %}
[ocr.yaml](https://2720813823-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn0x4RrnIfxXvmfh6rJHh%2Fuploads%2FnrkxXRuInsnQ2YSOCBxw%2Focr.yaml?alt=media\&token=634e051d-f9bc-4ee5-9f47-3b0fa3464bfe)
{% endopenapi %}


# Example Implementations

{% hint style="info" %}
Like any captcha, it is normal to have some unolvable captchas sometimes, just load and solve a new one
{% endhint %}

{% tabs %}
{% tab title="Queue IT" %}

```python
from requests import post
from base64 import b64decode

def load_captcha():
    url = "https://footlocker.queue-it.net/challengeapi/queueitcaptcha/challenge/en-us"
    headers = { 
        "Host": "footlocker.queue-it.net",
        "sec-ch-ua": '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
        "sec-ch-ua-mobile": "?0",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
        "sec-ch-ua-platform": '"macOS',
        "accept": "*/*",
        "origin": "https://footlocker.queue-it.net",
        "sec-fetch-site": "same-origin",
        "sec-fetch-mode": "cors",
        "sec-fetch-dest": "empty",
        "referer": "https://footlocker.queue-it.net/",
        "accept-language": "en-GB,en;q=0.9",
        "x-queueit-challange-customerid": "footlocker",
        "x-queueit-challange-eventid": "cxcdtest02",
        "x-queueit-challange-hash": "sg7R/eOE9jBw1RMb1iI7d1M8uKgf6sErktuA3Q69hgw=",
        "x-queueit-challange-reason": "1"
    }
    return post(url, headers=headers).json()['imageBase64']


if __name__ == "__main__":
    API_KEY = "TAKION_API_XXX" # Fill it with your api key
    
    b64image = load_captcha()
    result = post(
        "https://ocr.takionapi.tech/read",
        json={
            "image": b64image
        },
        headers={
            "x-api-key": API_KEY
        }
    ).json()
    if (error := result.get("error")):
        print(error)
        exit(0)
    print(f"Solved! {result['result']}")

    # Save image for debugging
    with open("queueit.png", "wb") as fh:
        fh.write(b64decode(b64image))
```

{% endtab %}

{% tab title="Ticketmaster SG" %}

```python
from requests import post
from base64 import b64decode

if __name__ == "__main__":
    API_KEY = "TAKION_API_XXX" # Fill it with your api key

    # Since on ticketmaster sg a captcha is assigned to your
    # session only after some actions are taken (like adding to cart)
    # we are going to set the value as fixed, in a real case scenario
    # you wanna convert the image to base64 and then send to the API
    b64image = "iVBORw0KGgoAAAANSUhEUgAAAHgAAABkCAIAAADCEmNlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAMo0lEQVR4nO2cfVhT1x3HD3m9JCEkAUJIEJA3kTcRkdKK6LRF265TOx/quq6PtdandT61z9Z1dc+6PnV9bNdXa7d2j1vVru1mW2ad9bVlVStahqiogMibECGEBBIICYGQ3OyP213TkHvOvTdwdfR+/kpyfzn3l+8993d+53fOTQQofx7wTD2Cm+3A9wVeaI7gheYIXmiO4IXmCF5ojuCF5gheaI7gheYIXmiO4IXmCF5ojuCF5gheaI7gheYIXmiO4IXmCFE4Xy5I1T20NL8wIwGTiLqtjq/qr/2t6uLI2PhkOTediGC3lKWUSXc+dd8Di3KDPu+zOzds//xAzdXJ8G1aIQRpi5l+R4FJjr+69q7CtBCHIiUVi3LaTLbLnZZJ8G4awSZGv/H4snkZeqqjQoFg51P3pcSrwvBqGsJY6KS46LXlBXAbOSZ5pmIBW5emJ4yF/mFJplgoRJqtXpjNyp9pC+OsIzspjo5ZXLQ8Vinrd4wwd4kSlRzLT40vnmVQKbDf7vlqElvmgLDSu6mgJCuxLC8Z9/slIqEME6vkmFYlT4xTpsSrEjRRhM2xc20310kWMBa6pWeAjpnd6WbXnUVCwR/W3wW3wXE/i5ZvLoxj9MGaFh+OI80O17ay8gdUNxoHUFdIJPz/m9Ay9rjDbP/kZCPcZtzne+WT02xdAl/VX4MbYJJbLuIhYdM1nnznSHuvDWLw7HtVl671sXUJLbQiUsK68ZsFG6H7HSOLn95zqqFr4iHXqOeJHQff+Oc34fj09eUQLQeiwL4jdP7M+L8/++N0vSack041LO/B7n5H2S93r7wj68Ef5BWk6WSY2DQwXHW+453Pz3b3O8L0qclotQ654qLlVAZKmRQAkJuivWd+xsoFWbfPngEA2PrRyTDPO6UwE7o0Jwn3+2ube7w4DgDYf6Z5/5nmqXCr9mrPvcWZVEc1ysiO9zfP1KkDP7zFR0hmQqfrNbufXuka9dS1mOpaTPUd5qYua5vJ5hgZY+3BmsW5mqjITvOgZdDl8fqID7utsNtCLBQGqQwA0KkVDbdwJYuZ0G0mGwBAjkkW5acsyk8hP7c73Wabs98x4nR7cL9/+76aqgsdNNtUybE/bbqXkRsh0cdEhd/I1MFMaKo5iFoRqVZEkm837jhEv03k0EeTW3wwZBbXnG4P0qa1Z8BoHaLfZpPRane6GbkRktwULeTotkeWrls2VxMVCbGZUpgJ7fWh54TILHgikxJbCzMSIEcVkZL3frHC8smvat5a/+LaJcuL0onUZSLpek1Bqi58f4JgFjpwP7rIUN1ohBsoMMk9xRmluUkFaTp9TJRSJo2Uihm5EZJkrSpVp+4w20MetQy6AABCgeC2rMTbshKJD1t7Bho6Lc3X+zt67d39DrPNWd9h1qrkp998tL3XdrCm5WhdW3WD0TmKvo+RMBSaRjWn5ko31aGsGbHPVCxYszg3UhKuso1dlt+9f1wgiBAJBTKpOEkbXZCmK5mdSCV0yHsxwxCTYYgh3358smHNtkrbsBsAkJag2byqZPOqknGfr77dXNdiutTR13y9v7Nv0DLoYrEAzUxoiQhR8rc73URmEgQmFm1bt3TTimI6iwYAAL/fbxoYNsQqqQwUkZJ9p6/QaYpAEBGBtNnzRT2YcEnEQuH8TMP8TEPgh1t2Vb38cTX9swPGQosRMl3qCFHiSNWpD2z9SU4ybLAKIiIiQquWe3041TQkMVYpEQnJvBsJsjzSM+D44lw7oFexQpbVJsJsMEQ6MXFYy58Zf2b7o4xUJhALhePUOgoFgszEGKqjE1EpMLjB3uMNxAikkiMsL7T3UgUoCMyEphqpSZqM1sC3qTr1Fy/9LF6tYOoWAXyQzJoRS7+pJG003GDviQbiBfKS7D/NpuowyUIH9mhMLNr3/AOsVUbCTOg4mNCtPQN1rSbidaxSBm/q4H9a6J+XhJnQyEjX1nNjJHz50TvnoBLSAcfIodqWC+29jNwgmMQeHTiualWUVUMAgHXIdb6NjbfMBkN4/Bob95psw8TrwvSETSuK4a395ci5p949SqRKH/76/p8uyWfkDH2hlTJpNNTzwGig08BuwarzdGs4QTDr0fCrbbTcmHlvW7dUKIA1/o/jlzds/5xMSEMmhY6RUUgL9AfDTAPM0u50117tId8mUueUIIzKDDOhY6Nh8auzb5B4UZShXzYvHWLZM+DY+PaNwpNKjj1855yJZtUNsElmVKQUHnlJ4JfkxMXOwBlvakJwATYQjoSGF2XItZX1dxfC23l5b/Wg69veWjzL8PXrj0ysLwMA3j1Y5/bA5mBFmZRbAAOB15uCagYQoQccI0FpFX2YxWh4zZeoJ4gEgjWLg7fzBoFJRI/fW5Sbol08J4Uqxb5itB6ubTXbnCGvAUFRpp7O/DA7Gba76kzjdfK1So4F1nuDLZuuUx1Cwkxo+NjdPzQCACjNTYKPPACAVx8rhxv4cHz9mwdwv99sRwgNb4cA0qOJUgb5Fj7A1rWY6JwuJMxCB3wzLtGj7yxMZe0NgQ/HN759iOg+RJtUFKbDSqMECkwCcbvZ2D867iXfwqM5u8SOgIHQOrVCjsHyaKJHF88yQGyQ9NqGK178dOfhc8Rbs80JMY5RypAbsQszEiD5T9AON3iPDuz7TGEQOpBrRUSBkU4vC8nla317TzRs/6wmsAgJ79EAgKJMPZnthKTkf9XnkHT0fqdqUZBGOcOyDrnC2UnBQGhk3urx+lRyLAY1hX3109MnLnYmximVMqlIKBj1eI2WodqrPSF/BlLosrzkylNNEAN4HCfuQhJIL2nqYplvEDAQGjkTG/V46TxRYRl0HT6L2AJJ7q0ms0AqyvKS4QaJcbAJSGAGnZ0UB6nMNF/vh58IDoMYDc9GAQAer0+jRK9+0gni5JMZyOXg3BQtPLuHz/QCC7/wpxRYZ9AEDITOT42HG4x6vAroaEnwo9tnwTv++uWFDy7JI14jhRYKBEsKZkIM4LWLO7JnEC8wsWjd8rkQy3BGQkBfaL0myhAD6xoAAK8Pp7NMLhWLKp+roOqGqxdm7/j53WStks4Gh+VFlNN9iUgIXzwrn5f25MrbSnOS9r+wJllLefnHfb5wkmhAP0bTmRpIREKaC8bzMvQNOze+Vnnmw39fIoY7lRwry0tet3zuituzAi3pNLh8PqXQyAsvFAjeeuJu5CnqWkxhPhFMV+jiLHRgxSSiTjMs0wokQRP1+oZlr29YZh1ySUTCoMnkuO/bRSw6PdoQoyzJSqxpDrH6jvv9Q65R5EwVyYFvwn0WmG7oKM1JQtrIpGKjdcg6hEjIgoiLlk8Ugpyn0Hxc5f7S2VSHAou3rNlXzWDFPSS0hFbKpHfkzECaESM4sZYcJmRAFAjQ2wQAAA8uyaPaUBDOvJng+MVrNB+RgkBL6PJ5aXT2Y8gwMQDgaN0kPJvGdF+ZIUZ5T3FGyEP097VSsX1fTZgtAJoxmuo3BEEUUfdVX3ntMWc4a7Jj417yVg3ZT3043mayNXVZW3oGOs2DRsuQ2e6kChEHvrnq9oyz3ht1rtU0KX/WgBYaE4vuX0AZAQMhsuORsfFte0/RGcqp2HXsArn2SIaOPruzutF4pul6zZXu+nYz/RzAMTK289C5zatKWHjiw/En3znC4osTQQv98F1zaI7aZLX6zwfr1pYXzE1jU13qszu3fnjjaRSn27NlV9XRs231HeznC1s/Orm6LBs5D5jIH/9VG06xPxD0H6P8Zs1CrUpObL4SCQXEpkKlTKqUS7UquVYl16kVRB3yy/Pt5Vs+IL6l10TV7Fg/g96aHokPx8u3fMBi4y+S0pyko9segpd5gzh+8Vr5sx94aTy9SgeW/0ATiEQkTNJGZxpitCr5ni/ryc8zDTGVz1XkzURM3EncnvGHX/kMXooLh7K85MrnKiAPewVy5GxrxYufTsqGXQI2/0AThA/324bdrSZb0N09MOzefaw+Wi4tSNMhH5lq7LKseuHjL9numqBDl2Vo97H6eLU8JyUOshTgGvX8/qOTT+w4NEZ7ByUdJqFHI9GpFZtWFK9emD0rMbjQ6sPx2qs9u45e2HXsAp1d7pOCXhO1trxgScHMktmJZDDx4XhDp6XyVNNfj5w322HLOuzgQmgSnVpRlKnXquQqBeZwjXX3O+rbzVPxq+ijlEm1Krln3Nfd75jSK82p0N9nbumnTacTvNAcwQvNEbzQHMELzRG80BzBC80RvNAcwQvNEbzQHMELzRG80BzBC80RvNAcwQvNEbzQHMELzRG80BzBC80RvNAcwQvNEbzQHMELzRG80BzBC80RvNAc8V9gk2zAF8W3XAAAAABJRU5ErkJggg=="
    result = post(
        "https://ocr.takionapi.tech/read",
        json={
            "image": b64image
        },
        headers={
            "x-api-key": API_KEY
        }
    ).json()
    if (error := result.get("error")):
        print(error)
        exit(0)
    print(f"Solved! {result['result']}")

    # Save image for debugging
    with open("tmsg.png", "wb") as fh:
        fh.write(b64decode(b64image))
```

{% endtab %}
{% endtabs %}


