> ## Documentation Index
> Fetch the complete documentation index at: https://docs.55-tech.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scraping API Error Handling

> Scraping API error codes, block detection, and retry strategies.

## Error response format

All API errors return JSON:

```json theme={null}
{
  "detail": "Invalid or missing API key"
}
```

## HTTP status codes

| Status | Description                                                                               |
| ------ | ----------------------------------------------------------------------------------------- |
| `200`  | Success — target response proxied (check `meta.blocked` for block detection)              |
| `401`  | Unauthorized — missing API key                                                            |
| `403`  | Forbidden — invalid API key                                                               |
| `429`  | Rate limited. Headers include `Retry-After`, `X-RateLimit-Limit`, `X-RateLimit-Remaining` |
| `502`  | Bad gateway — no healthy agent available for this domain                                  |
| `504`  | Gateway timeout — target did not respond within timeout (default 30s)                     |

## Block detection

Every fetch response includes a `meta.blocked` field:

```json theme={null}
{
  "meta": {
    "status": 403,
    "blocked": true,
    "agent": { "id": "scraping-de5" }
  },
  "raw": "<html>Access Denied...</html>"
}
```

When `meta.blocked` is `true`:

* The agent that got blocked is automatically excluded for this domain
* Your next request will be routed to a different agent
* The response still contains the full target body for your inspection

You can check per-agent health for a domain:

```bash theme={null}
curl -H "X-API-Key: YOUR_API_KEY" \
  https://scraping-api.55-tech.com/network/health/example.com
```

The health endpoint returns three states: `available`, `limited` (temporary), and `unavailable` (longer exclusion). Agents recover automatically.

## Retry strategies

### Rate limit (429)

Use exponential backoff: wait 1s, 2s, 4s, etc. Check `GET /usage` for your current rate limit status.

### Blocked (meta.blocked = true)

No client-side retry needed. The API automatically routes your next request to a different, healthy agent. Just keep making requests normally.

### Browser validation failure (502)

If you use `expectSelector` or `expectContains` on `/browser` and the rendered page doesn't match, the API automatically retries on a different node before returning the error. No client-side retry needed for the first failure.

### Timeout (504)

* Increase the `timeout` field in your POST body (default: 30 seconds)
* For `/browser`, note that browser startup adds \~2-5 seconds — set `timeout` accordingly
* Use `X-Geo` to pick agents geographically closer to the target
* Use `GET /debug/pick?url=...` to preview which agent would be selected

### No agents available (502)

All agents for this domain are temporarily excluded. Wait a moment and retry, or use `GET /network/health/{domain}` to check recovery status.

## WebSocket errors

| Error                    | Cause                                          | Close code |
| ------------------------ | ---------------------------------------------- | ---------- |
| Invalid API key          | Missing or unrecognized key in connect message | `1008`     |
| Rate limit exceeded      | Too many concurrent connections                | `1008`     |
| Connect timeout          | No JSON connect message within 10 seconds      | `1008`     |
| Target connection failed | Agent could not connect to target WS           | `1011`     |
| Agent unavailable        | No agent available for the request             | `1011`     |

## AMQP errors

AMQP errors are delivered as SSE events:

```
event: error
data: {"message": "agent error: connection refused", "code": 1011}
```

After an error event, the SSE stream closes.

## Common errors

### Missing target URL

```bash theme={null}
# Wrong: no URL specified
curl -H "X-API-Key: YOUR_KEY" https://scraping-api.55-tech.com/fetch

# Right: URL in header
curl -H "X-API-Key: YOUR_KEY" \
  -H "X-Target-URL: https://example.com" \
  https://scraping-api.55-tech.com/fetch
```

### Invalid geo code

```bash theme={null}
# Wrong: full country name
-H "X-Geo: Germany"

# Right: ISO 2-char code
-H "X-Geo: DE"
```

### WebSocket connect timeout

The first JSON message with `apiKey` and `url` must be sent within **10 seconds** of opening the WebSocket connection, or it will be closed with code `1008`.
