# curl-impersonate-service v1.7.0

HTTP requests that look like a real browser (TLS/HTTP2 fingerprints), as a REST API.

Base URL: https://curl-impersonate.16bit.cloud

## Authentication

All API endpoints except `/health` require an API token, as a header or a query parameter:

    Authorization: Bearer <token>
    ?token=<token>

Tokens are issued by the service administrator.

## Endpoints

- `GET /health`: liveness, no auth. Returns `{"status":"ok","version":"…"}`.
- `GET /browsers`: available browser profiles, aliases and default.
- `GET /metrics`: request counts, success/failure, average duration, per-browser usage.
- `POST /impersonate`: performs an HTTP request impersonating a browser.

### POST /impersonate

JSON body:

| Field | Type | Default | Description |
|---|---|---|---|
| `url` | string | (required) | Target URL |
| `browser` | string | `chrome152` | Profile or alias |
| `method` | string | `GET` | HTTP method |
| `headers` | object | | Custom request headers |
| `query_params` | object | | Query params merged into the URL |
| `body` | string | | Request body (text) |
| `body_base64` | string | | Request body (base64, for binary) |
| `follow_redirects` | bool | `true` | Follow redirects |
| `insecure` | bool | `false` | Skip TLS verification |
| `timeout` | int | `30` | Timeout in seconds |

Example:

    curl -X POST https://curl-impersonate.16bit.cloud/impersonate \
      -H "Authorization: Bearer <token>" \
      -H "Content-Type: application/json" \
      -d '{"browser":"chrome152","url":"https://example.com"}'

The response is always HTTP 200 with a JSON envelope: `success`, `status_code`,
`headers`, `body`, `timing`, … When the request could not be made,
`success` is false and `error_type` is one of `network`, `dns`,
`timeout`, `ssl` or `size`. Bad input returns HTTP 400 with `error_type: validation`,
a missing or wrong token HTTP 401 with `error_type: auth`.

## Browsers

Default: `chrome152`. Aliases:

- `chrome-latest` → `chrome152`
- `edge-latest` → `edge101`
- `firefox-latest` → `firefox155`
- `safari-latest` → `safari270`
- `tor-latest` → `tor145`

All profiles: `chrome100`, `chrome101`, `chrome104`, `chrome107`, `chrome110`, `chrome116`, `chrome119`, `chrome120`, `chrome123`, `chrome124`, `chrome131`, `chrome131_android`, `chrome133a`, `chrome136`, `chrome142`, `chrome145`, `chrome146`, `chrome150`, `chrome151`, `chrome151_macos`, `chrome152`, `chrome152_macos`, `chrome99`, `chrome99_android`, `edge101`, `edge99`, `firefox133`, `firefox135`, `firefox144`, `firefox147`, `firefox153`, `firefox154`, `firefox155`, `safari153`, `safari155`, `safari170`, `safari172_ios`, `safari180`, `safari180_ios`, `safari184`, `safari184_ios`, `safari260`, `safari2601`, `safari260_ios`, `safari270`, `safari270_ios`, `tor145`
