# Auto-Detect Protection

Source: https://docs.scrappey.com/docs/auto-detect

> Send a URL and get back the detected protection provider, the recommended proxy country, and a ready-to-use Scrappey request body — so you can configure each scrape automatically instead of guessing.

## What it does

Point this endpoint at any URL and it inspects the live response, identifies which bot-protection or CAPTCHA provider the site uses, infers the best proxy country from the site's location, and returns a complete Scrappey request body you can send straight to the [`request.get`](/docs/request-get) API. It's the programmatic equivalent of the Playground's "auto" setup: detect the target, pick the best method, and run.

This is most useful when you scrape many unpredictable domains (user-imported listings, mixed portals, unknown sites) and don't know the right settings up front.

## Request

```bash
GET https://detection.scrappey.com/api/detect?url=https%3A%2F%2Fexample.com
```

The `url` value must be **URL-encoded**. No API key is required for the detection call itself.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | Yes | Full URL to analyze. Must be URL-encoded and a valid HTTP or HTTPS URL. |

## Response

```json
{
  "success": true,
  "url": "https://example.com",
  "domain": "example.com",
  "statusCode": 200,
  "timestamp": "2026-06-25T10:00:00.000Z",
  "detection": {
    "providers": ["cloudflare"],
    "primaryProvider": "cloudflare",
    "confidence": { "cloudflare": 100 },
    "challenged": false,
    "details": [
      {
        "provider": "cloudflare",
        "type": "header",
        "pattern": "cf-ray",
        "description": "Ray ID response header",
        "confidence": 95
      }
    ]
  },
  "country": {
    "code": "US",
    "name": "United States",
    "proxyCountry": "UnitedStates",
    "detectedVia": "geoip"
  },
  "recommendation": {
    "explanation": "Detected cloudflare protection with 100% confidence. Browser mode with Chrome is recommended.",
    "tips": [
      "Use a real browser with JavaScript execution",
      "Residential proxies give the best results",
      "Use a session to persist challenge clearance cookies"
    ],
    "proxyCountry": "UnitedStates"
  },
  "scrappeySettings": {
    "recommended": { "...": "full recommended settings with notes" },
    "apiRequestBody": { "...": "minimal request body, ready to POST (shown below)" }
  }
}
```

The `scrappeySettings.apiRequestBody` field is abbreviated above — see [Use the result](#use-the-result) for the complete body it produces.

## Use the result

Take `scrappeySettings.apiRequestBody` from the response and POST it directly to the Scrappey API — it already includes the right `requestType`, `proxyCountry`, and session settings for the detected target. The body below is the kind of request `apiRequestBody` produces:

```json
{
  "cmd": "request.get",
  "url": "https://example.com",
  "requestType": "browser",
  "browser": "chrome",
  "websocket": true,
  "sessionTtl": 300,
  "proxyCountry": "UnitedStates"
}
```

The recommended flow is **detect → take `apiRequestBody` → send to Scrappey**. For repeated scrapes of the same site, cache the detection result per domain so you only call detect once per new domain.

## Response fields

### Top-level

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `success` | boolean | Yes | Whether detection completed successfully. |
| `url` | string | No | The URL that was analyzed. |
| `domain` | string | No | Extracted domain name. |
| `statusCode` | number | No | HTTP status code returned by the target site. |
| `timestamp` | string | No | ISO 8601 timestamp of the detection. |

### `detection`

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `providers` | string[] | No | All detected provider IDs. |
| `primaryProvider` | string | No | Provider with the highest confidence, or `"none"`. |
| `confidence` | object | No | Map of provider ID to confidence score (0-100). |
| `challenged` | boolean | No | Whether the site returned a challenge or block page (403, 503, CAPTCHA). |
| `details` | array | No | Individual pattern matches, each with `provider`, `type`, `pattern`, `description`, and `confidence`. |

### `country`

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `code` | string | No | ISO 3166-1 alpha-2 country code (e.g. `US`, `GR`). |
| `name` | string | No | Human-readable country name. |
| `proxyCountry` | string | No | Value to pass as Scrappey's [`proxyCountry`](/docs/proxy-country) (e.g. `UnitedStates`, `Greece`). |
| `detectedVia` | string | No | How the country was inferred: `geoip`, `language`, `tld`, or `none`. |

### `recommendation`

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `explanation` | string | No | Human-readable summary of the detection and recommendation. |
| `tips` | string[] | No | Suggestions for handling the detected protection. |
| `proxyCountry` | string | No | Recommended proxy country. |

### `scrappeySettings`

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `recommended` | object | No | Full recommended settings with explanatory notes. |
| `apiRequestBody` | object | No | Minimal request body, ready to POST to the Scrappey API. |

## How detection works

1. The endpoint makes an HTTP request to the target with a realistic browser User-Agent.
2. It collects the response headers, cookies, and HTML content.
3. It runs detector rule sets against that data, matching known patterns in cookies, headers, content, and script URLs.
4. Each match has a confidence score; the provider's overall confidence is the highest match plus a boost for multiple matches, capped at 100.
5. Country is inferred via IP geolocation first, falling back to the page's `lang` attribute or the domain's country TLD.

## Integration examples

### JavaScript / Node.js

```javascript
const target = "https://example.com";
const res = await fetch(
  "https://detection.scrappey.com/api/detect?url=" + encodeURIComponent(target)
);
const data = await res.json();

if (data.success) {
  // Send the ready-made body straight to Scrappey
  const body = data.scrappeySettings.apiRequestBody;
  await fetch("https://publisher.scrappey.com/api/v1?key=YOUR_API_KEY", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
}
```

### Python

```python
import requests
from urllib.parse import quote

target = "https://example.com"
data = requests.get(
    f"https://detection.scrappey.com/api/detect?url={quote(target, safe='')}"
).json()

if data["success"]:
    body = data["scrappeySettings"]["apiRequestBody"]
    requests.post(
        "https://publisher.scrappey.com/api/v1?key=YOUR_API_KEY", json=body
    )
```

### cURL

```bash
curl "https://detection.scrappey.com/api/detect?url=https%3A%2F%2Fexample.com"
```

## Error responses

A failed detection returns `success: false` with an `error` message. Common cases:

| Case | `error` message |
|------|-----------------|
| Missing `url` | `Missing required query parameter: url` |
| Invalid URL | `Invalid URL. Must be a valid HTTP or HTTPS URL.` |
| Target unreachable | `Failed to reach the target URL. The site may be down or blocking requests.` |
| Server error | `Detection failed: <details>` |

## Related concepts

- [`proxyCountry`](/docs/proxy-country) — the country values returned in `country.proxyCountry`.
- [`request.get`](/docs/request-get) — the API command you send the recommended body to.
- [Premium proxy](/docs/premium-proxy) — the residential proxy type recommended for protected sites.
