# Cloudflare challenge page

> Solve Cloudflare challenge page with the Noptcha API: type cloudflare.challenge, parameters, solution fields, compatibility names and runnable examples.

Source: https://noptcha.com/docs/task-types/cloudflare-challenge/

## Summary

| Property | Value |
| --- | --- |
| v1 type | `cloudflare.challenge` |
| Compatibility names | *none: native API (v1) only* |
| Proxy | required ([Proxies](https://noptcha.com/docs/proxies.md)) |
| Deadline | 120 seconds (starting value). A task not solved by then fails with `timeout` and is not charged. |

## Parameters

The `params` object of `POST /v1/tasks`. Unknown fields are rejected with `422 invalid_params`.

| Field | Type | Description |
| --- | --- | --- |
| `website_url`  required  | `string` |  Full URL of the page that shows the captcha (http or https).  format: uri · pattern: ^\[Hh\]\[Tt\]\[Tt\]\[Pp\]\[Ss\]?:// · min length 8 · max length 4,096  |
| `proxy`  required  | `object` |  Proxy the solver must use. login and password are used in memory only and are never stored or logged.  |
| `proxy.type`  required  | `enum` |  one of "http", "https", "socks4", "socks5"  |
| `proxy.host`  required  | `string` |  IP address or host name. Private and loopback addresses are rejected.  min length 1 · max length 253  |
| `proxy.port`  required  | `integer` |  ≥ 1 · ≤ 65535  |
| `proxy.login`  optional  | `string` |  max length 256  |
| `proxy.password`  optional  | `string` |  max length 256  |
| `user_agent`  optional  | `string` |  Usually omit it. The User-Agent actually used is returned in the solution.  min length 1 · max length 1,024  |
| `wait_load`  optional  | `boolean` |  Wait for the page's network activity to settle before returning.  |
| `required_cookies`  optional  | `array of string` |  Cookie names that must all be obtained for the task to succeed, e.g. \["cf\_clearance"\].  max items 32 · unique items  |
| `block_image`  optional  | `boolean` |  Do not load images of the target page (saves proxy traffic).  |
| `post_data`  optional  | `object` |  If set, submitted to website\_url as an HTML form POST.  max 64 keys  |
| `post_data.<any key>`  optional  | `string | number | boolean` |  |

## Solution

The `solution` object of a solved task.

| Field | Type | Description |
| --- | --- | --- |
| `cookies`  required  | `object` |  Cookies after passing the challenge, name to value; usually includes cf\_clearance.  |
| `cookies.<any key>`  optional  | `string` |  |
| `user_agent`  required  | `string` |  User-Agent the cookies are bound to; use it for every follow-up request.  min length 1 · max length 1,024  |
| `headers`  optional  | `object` |  Response headers of the target page.  |
| `headers.<any key>`  optional  | `string` |  |
| `request_headers`  optional  | `object` |  Request headers of the browser's last request to the target page.  |
| `request_headers.<any key>`  optional  | `string` |  |
| `content`  optional  | `string` |  HTML of the target page after passing the challenge.  |

## Example: native API (v1)

Runs as is with a test key (`nop_test_…`) in the [sandbox](https://noptcha.com/docs/sandbox.md); use a live key for real tasks.

POST /v1/tasks

```json
{
  "type": "cloudflare.challenge",
  "params": {
    "website_url": "https://example.com/",
    "proxy": {
      "type": "http",
      "host": "203.0.113.7",
      "port": 8080,
      "login": "proxyuser",
      "password": "proxypass"
    },
    "required_cookies": [
      "cf_clearance"
    ]
  }
}
```

**curl**

```bash
export NOPTCHA_KEY=nop_test_...  # your test or live key

# waits up to 60 s; 200 = finished (solved or failed), 202 = still processing
IDEMPOTENCY_KEY=$(uuidgen)  # one key per task you want; a retry of the same request reuses it
curl -s -X POST "https://api.noptcha.com/v1/tasks" \
  -H "Authorization: Bearer $NOPTCHA_KEY" \
  -H 'Prefer: wait=60' \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H 'Content-Type: application/json' \
  -d @- <<EOF
{
  "type": "cloudflare.challenge",
  "params": {
    "website_url": "https://example.com/",
    "proxy": {
      "type": "http",
      "host": "203.0.113.7",
      "port": 8080,
      "login": "proxyuser",
      "password": "proxypass"
    },
    "required_cookies": ["cf_clearance"]
  }
}
EOF

# on 202: long-poll with the "id" from the response
TASK_ID=...
curl -s "https://api.noptcha.com/v1/tasks/$TASK_ID?wait=60" \
  -H "Authorization: Bearer $NOPTCHA_KEY"
```


**Python**

```python
import os
import time
import uuid

import requests

API = "https://api.noptcha.com"
HEADERS = {"Authorization": f"Bearer {os.environ['NOPTCHA_KEY']}"}  # a nop_test_ key runs in the sandbox

# One Idempotency-Key per task you want. If you retry this request after a network error, send the same key and
# the same body bytes: you get the same task back, not a second one (see Idempotency on the Tasks page).
idempotency_key = str(uuid.uuid4())
r = requests.post(
    f"{API}/v1/tasks",
    headers={**HEADERS, "Prefer": "wait=60", "Idempotency-Key": idempotency_key},
    json={
        "type": "cloudflare.challenge",
        "params": {
            "website_url": "https://example.com/",
            "proxy": {
                "type": "http",
                "host": "203.0.113.7",
                "port": 8080,
                "login": "proxyuser",
                "password": "proxypass",
            },
            "required_cookies": ["cf_clearance"],
        },
    },
    timeout=100,
)
task = r.json()
if r.status_code >= 400:
    raise RuntimeError(f"{task['code']}: {task.get('detail', '')}")
while task["status"] == "processing":  # 202: not finished within the wait
    time.sleep(1)  # a long poll can return early (for example when wait slots are full)
    r = requests.get(f"{API}/v1/tasks/{task['id']}", params={"wait": 60}, headers=HEADERS, timeout=100)
    task = r.json()
    if r.status_code >= 400:
        raise RuntimeError(f"{task['code']}: {task.get('detail', '')}")

if task["status"] == "solved":
    print(task["solution"])
else:
    print("failed:", task["error"]["code"], task["error"]["message"])
```


**Node.js**

```js
import { randomUUID } from 'node:crypto';

const API = 'https://api.noptcha.com';
const HEADERS = { Authorization: `Bearer ${process.env.NOPTCHA_KEY}` }; // a nop_test_ key runs in the sandbox

async function v1(path, init = {}) {
  const res = await fetch(`${API}${path}`, { ...init, headers: { ...HEADERS, ...init.headers } });
  const data = await res.json();
  if (!res.ok) throw new Error(`${data.code}: ${data.detail ?? ''}`);
  return data;
}

// One Idempotency-Key per task you want. If you retry this request after a network error, send the same key and
// the same body bytes: you get the same task back, not a second one (see Idempotency on the Tasks page).
const idempotencyKey = randomUUID();
let task = await v1('/v1/tasks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Prefer: 'wait=60', 'Idempotency-Key': idempotencyKey },
  body: JSON.stringify({
    type: "cloudflare.challenge",
    params: {
      website_url: "https://example.com/",
      proxy: {
        type: "http",
        host: "203.0.113.7",
        port: 8080,
        login: "proxyuser",
        password: "proxypass",
      },
      required_cookies: ["cf_clearance"],
    },
  }),
});
while (task.status === 'processing') {
  await new Promise((r) => setTimeout(r, 1000)); // a long poll can return early (for example when wait slots are full)
  task = await v1(`/v1/tasks/${task.id}?wait=60`); // long poll
}
if (task.status === 'solved') console.log(task.solution);
else console.log('failed:', task.error.code, task.error.message);
```

In the sandbox the task is solved at once and `solution` is:

```json
{
  "cookies": {
    "cf_clearance": "NOPTCHA_TEST_TOKEN_7259140378796032"
  },
  "user_agent": "Mozilla/5.0 (Noptcha test)"
}
```

> **Note:** This type has no compatibility API name; use the native API (v1).
