# Slider CAPTCHA

## Datadome Captcha Workflow

This workflow guides you through solving **Datadome captcha challenges** using our API. Captcha blocks are typically encountered on high-security endpoints and require strict browser emulation.

> ⚠️ **Before proceeding:**\
> Ensure you are using a **Chrome TLS client**, and your requests **perfectly match** Chrome browser behavior. Any deviations — in headers, TLS fingerprint, or request flow — may invalidate the resulting `datadome` cookie.

***

### 🧱 Step 1: Detect a Captcha Block

Send a **GET request** to a protected page. If you’re blocked by a captcha, the HTML response will include:

* A script reference to `https://ct.captcha-delivery.com/c.js`
* A `<script>` element with a JavaScript object like this:

```html
<script>
  var dd = {
    'rt': 'c',
    'cid': 'AHrlqAAAAAMASuDzOQlFQzIALvhm3g==',
    'hsh': 'EC3B9FB6F2A31D3AF16C270E6531D2',
    't': 'fe',
    's': 43337,
    'e': '16fbe80bb40a1dfb31c417e8849d8d22...',
    'host': 'geo.captcha-delivery.com'
  };
</script>
```

***

### 🔗 Step 2: Construct the Captcha Link

Using the `dd` object, build a captcha URL with the following query parameters:

* `initialCid`
* `hash`
* `cid` (your session/client identifier)
* `t`
* `referer` (URL-encoded original page)
* `s`
* `e`
* `dm`

#### Example URL:

<pre class="language-html"><code class="lang-html"><strong>https://geo.captcha-delivery.com/captcha/?
</strong>initialCid=AHrlqAAAAAMASuDzOQlFQzIALvhm3g%3d%3d
&#x26;hash=&#x3C;datadome_site_key>
&#x26;cid=&#x3C;initial_datadome_cookie>
&#x26;t=fe
&#x26;referer=&#x3C;referer>
&#x26;s=&#x3C;s_value_from_dd_json>
&#x26;e=&#x3C;e_value_from_dd_json>
&#x26;dm=cd
</code></pre>

> 🛑 If the value of `t` is `bv`, your proxy is banned. **Rotate your proxy** and retry the request until you receive a `t=fe` response.

Also, **remove any old `datadome` cookies** before retrying or you may get stuck in a loop.

Here is a Golang implementation for constructing the CAPTCHA link:

```go
type DDCaptcha struct {
	Rt   string `json:"rt"`
	Cid  string `json:"cid"`
	Hash string `json:"hsh"`
	T    string `json:"t"`
	S    int64  `json:"s"`
	E    string `json:"e"`
	Host string `json:"host"`
}

func parseSliderCaptcha(body []byte) (map[string]interface{}, error) {
	re := regexp.MustCompile(`(?s)sliderCaptcha\((.*?)\)`)

	matches := re.FindSubmatch(body)

	if len(matches) > 1 {
		ddJson := string(matches[1])
		ddJson = strings.Replace(ddJson, "'", "\"", -1)

		keyPattern := regexp.MustCompile(`(?m)^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:`)
		jsonContent := keyPattern.ReplaceAllString(ddJson, `"$1":`)

		var dd map[string]interface{}
		if err := json.Unmarshal([]byte(jsonContent), &dd); err != nil {
			return nil, fmt.Errorf("error parsing JSON: %v", err)
		}
		return dd, nil
	}
	return nil, fmt.Errorf("unable to parse sliderCaptcha JSON")
}

func buildCaptchaLink(initialCookie, referer string, ddObject *DDCaptcha) (string, error) {
	initialCid := ddObject.Cid
	referer = url.QueryEscape(referer)
	s := ddObject.S
	e := ddObject.E
	t := ddObject.T
	siteKey := ddObject.Hash

	baseURL := "https://geo.captcha-delivery.com/captcha/"

	params := []struct {
		key, value string
	}{
		{"initialCid", url.QueryEscape(initialCid)},
		{"hash", siteKey},
		{"cid", initialCookie},
		{"t", t},
		{"referer", referer},
		{"s", strconv.FormatInt(s, 10)},
		{"e", e},
		{"dm", "cd"},
	}

	var queryParts []string
	for _, param := range params {
		queryParts = append(queryParts, param.key+"="+param.value)
	}

	finalURL := baseURL + "?" + strings.Join(queryParts, "&")

	return finalURL, nil
}
```

***

### 🖼️ Step 3: Retrieve Captcha Images

Make a **GET request** to the captcha link.

Ensure the HTML response contains:

* `var captcha = sliderCaptcha({...})`
* The Datadome comment: `/** DataDome is a cybersecurity solution...`

#### Extract Image Paths:

1. Parse the `captchaChallengePath` value to get the **main background image** (ends in `.jpg`)
2. Replace `.jpg` with `.frag.png` to get the **fragment (slider) image**

Download both images and **base64-encode** the raw binary data of each.

Here is a Golang implementation to parse the `captchaObject` to get the image/fragment paths:

```go
func parseSliderCaptcha(body []byte) (map[string]interface{}, error) {
	re := regexp.MustCompile(`(?s)sliderCaptcha\((.*?)\)`)

	matches := re.FindSubmatch(body)

	if len(matches) > 1 {
		ddJson := string(matches[1])
		ddJson = strings.Replace(ddJson, "'", "\"", -1)

		keyPattern := regexp.MustCompile(`(?m)^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:`)
		jsonContent := keyPattern.ReplaceAllString(ddJson, `"$1":`)

		var dd map[string]interface{}
		if err := json.Unmarshal([]byte(jsonContent), &dd); err != nil {
			return nil, fmt.Errorf("error parsing JSON: %v", err)
		}
		return dd, nil
	}
	return nil, fmt.Errorf("unable to parse sliderCaptcha JSON")
}

captchaObject, err := parseSliderCaptcha(captchaPage) 
if err != nil { 	
	return nil, errors.New("unable to parse slider captcha parameters")
} 
backgroundImageUrl := captchaObject["captchaChallengePath"].(string)
fragmentImageUrl := strings.TrimSuffix(backgroundImageUrl, ".jpg") + ".frag.png"

```

***

### 🔧 Step 4: Solve Using Our API

See [API Reference](/datadome/api-reference.md#post-captcha)

The response will contain a `captchaSubmitUrl` field. This is the fully constructed URL for submitting the solution.

***

### 📤 Step 5: Submit Captcha Solution

Make a **GET request** to the `captchaSubmitUrl` returned by our API.

Ensure that your headers **match Chrome browser behavior exactly**, especially:

* `user-agent`
* `sec-ch-ua` and related client hints
* `referer` matching the captcha page
* Proper header ordering

***

### 🍪 Step 6: Handle the Response

If the captcha is accepted, the response will include:

```json
{
  "cookie": "datadome=...; Max-Age=31536000; Domain=.example.com; Path=/; Secure; SameSite=Lax"
}
```

Extract and store this `datadome` cookie in your cookie jar for future requests to the target domain.

***

### 🔁 Step 7: Retry Original Request

Retry the original request **using the solve cookie**.

* If it works: 🎉 You’re in!
* If still blocked:
  * Retry up to **3 times**
  * If unsuccessful, **rotate your proxy**
  * **Clear any old cookies** and restart the entire workflow from Step 1


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://api-docs.yoghurtbot.net/datadome/slider-captcha.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
