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

# API overview

> Authenticate REST requests, read response formats, and find session, profile, and browser protocol endpoints.

Use the REST API to start and stop browsers, manage saved profiles, and configure proxies and extensions. A start request returns the WebSocket URL used by your automation framework.

For a first working script, follow the [quickstart](/quickstart). The endpoint pages in this tab document request fields and responses.

## Base URL

Use the API base URL assigned to your account in the [Surfsky dashboard](https://app.surfsky.io). `https://YOUR_API_HOST` is a placeholder for that URL. Calling a host that does not serve your account returns `403 namespace_not_allowed`.

The shell examples use `SURFSKY_API_BASE_URL` and `SURFSKY_API_TOKEN`; set them as shown in [credentials](/quickstart#credentials). In the API playground, enter your full API base URL in `baseUrl`.

## Authentication

Send the API token with REST management requests:

```bash theme={null}
curl "$SURFSKY_API_BASE_URL/profiles/active" \
  -H "X-Cloud-Api-Token: $SURFSKY_API_TOKEN"
```

Use `Content-Type: application/json` for JSON request bodies. Extension uploads use multipart form data.

Keep tokens in server-side environment variables or your secret store. Live CDP, DevTools, ChromeDriver, and screencast URLs carry access through the session identifier; keep those URLs private too.

<span id="authentication-error-401-unauthorized" />

<span id="error-responses-14" />

<span id="errors" />

<span id="invalid-parameters-error-400-bad-request" />

<span id="no-subscription-error" />

<span id="not-found-error-404" />

<span id="profile-active-error" />

<span id="rate-limit-error-429-too-many-requests" />

## Response shape

Read the schema for the endpoint you are calling. The API has several success formats:

| Operation                              | Payload location                                             |
| -------------------------------------- | ------------------------------------------------------------ |
| Start a one-time or persistent browser | `internal_uuid`, `ws_url`, and `inspector` at the top level. |
| Create a persistent profile            | The new UUID in `data.uuid`; HTTP `201`.                     |
| List persistent profiles               | A JSON array at the top level.                               |
| List active sessions                   | An array in `data`.                                          |
| Scrape one page                        | Page result in `data`. A batch returns an array in `data`.   |
| Many management and lookup calls       | A `success` flag and `data`, sometimes with `msg`.           |

For example, a start response looks like this:

```json theme={null}
{
  "internal_uuid": "a8fb62f90611456aa75422b01c385a62",
  "ws_url": "wss://YOUR_API_HOST/proxy/a8fb62f90611456aa75422b01c385a62",
  "inspector": {
    "list": "https://YOUR_API_HOST/proxy/a8fb62f90611456aa75422b01c385a62/inspector",
    "pages": [],
    "screencast": "wss://YOUR_API_HOST/screencast/a8fb62f90611456aa75422b01c385a62/devtools/page/PAGE_ID"
  },
  "success": true
}
```

The IDs and URLs above are illustrative. Use the values returned by your request. Errors commonly include `success: false`, `msg`, `data`, and `code`, but forwarded errors can differ. See [errors](/errors).

<span id="parameters-2" />

<span id="shared-cache" />

## Starting a browser

A one-time session starts without a saved profile. Its profile state is discarded when it stops. A persistent profile saves the storage types you enable and can be started again.

```bash theme={null}
curl -X POST "$SURFSKY_API_BASE_URL/profiles/one_time" \
  -H "X-Cloud-Api-Token: $SURFSKY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The empty body uses a proxy pool available to your account. Supply your own connection if no pool is available.

`profile_uuid` identifies a saved profile. Use the returned `internal_uuid` for stop, scrape, and live browser connections. These values may be equal; do not assume a new or different internal ID on every start. See [session lifecycle](/sessions).

<span id="body-parameters" />

<span id="error-responses" />

<span id="example-request" />

<span id="headers" />

<span id="mobile-example" />

<span id="response" />

<span id="start" />

<span id="start-one-time-profile-browser" />

<span id="success-200-ok" />

<span id="terms" />

### Start one-time session

[POST /profiles/one\_time](/api-reference/profiles/start-one-time-session) starts and returns a running browser. Configure fingerprints, proxies, [Human actions](/human_emulation), and CAPTCHA solving for the work you need.

<span id="example-request-1" />

<span id="example-request-6" />

<span id="headers-1" />

<span id="headers-5" />

<span id="response-1" />

<span id="response-4" />

<span id="stop" />

<span id="stop-1" />

### Stop session

[POST /profiles/\{internal\_uuid}/stop](/api-reference/profiles/stop-session) releases a running browser. Put this call in cleanup code so it also runs after failed navigation or framework connection.

<span id="active" />

<span id="active-1" />

<span id="error-responses-1" />

<span id="error-responses-6" />

<span id="error-responses-7" />

<span id="example-request-12" />

<span id="example-request-13" />

<span id="example-request-2" />

<span id="example-request-3" />

<span id="example-response" />

<span id="example-response-2" />

<span id="headers-11" />

<span id="headers-12" />

<span id="headers-2" />

<span id="response-9" />

<span id="response-fields" />

<span id="response-fields-1" />

<span id="response-fields-2" />

<span id="stop-all" />

<span id="stop-all-1" />

<span id="success-200-ok-1" />

### Active sessions

[GET /profiles/active](/api-reference/profiles/list-active-sessions) lists one-time and persistent browsers currently running. Use `one_time` to distinguish them.

[POST /profiles/stop](/api-reference/profiles/stop-all-sessions) stops all browsers on the account. Check its `failed` list; use individual stop calls when other workers share the account.

<span id="body-parameters-1" />

<span id="body-parameters-2" />

<span id="create" />

<span id="delete" />

<span id="delete-batch" />

<span id="error-responses-2" />

<span id="error-responses-3" />

<span id="error-responses-4" />

<span id="error-responses-5" />

<span id="example-request-10" />

<span id="example-request-11" />

<span id="example-request-4" />

<span id="example-request-5" />

<span id="example-request-7" />

<span id="example-request-8" />

<span id="example-request-9" />

<span id="example-response-1" />

<span id="get" />

<span id="headers-10" />

<span id="headers-3" />

<span id="headers-4" />

<span id="headers-6" />

<span id="headers-7" />

<span id="headers-8" />

<span id="headers-9" />

<span id="list" />

<span id="mobile-example-1" />

<span id="parameters" />

<span id="partial-success-response-200-ok" />

<span id="path-parameters" />

<span id="path-parameters-1" />

<span id="query-parameters" />

<span id="request-body-parameters" />

<span id="request-body-parameters-1" />

<span id="response-2" />

<span id="response-3" />

<span id="response-5" />

<span id="response-6" />

<span id="response-7" />

<span id="response-8" />

<span id="start-1" />

<span id="success-response-200-ok" />

<span id="success-response-200-ok-1" />

<span id="update" />

## Persistent profiles

| Task           | Endpoint                                                                       |
| -------------- | ------------------------------------------------------------------------------ |
| Create         | [POST /profiles](/api-reference/profiles/create-profile)                       |
| List           | [GET /profiles](/api-reference/profiles/list-profiles)                         |
| Read settings  | [GET /profiles/\{profile\_uuid}](/api-reference/profiles/get-profile)          |
| Update         | [PATCH /profiles/\{profile\_uuid}](/api-reference/profiles/update-profile)     |
| Start          | [POST /profiles/\{profile\_uuid}/start](/api-reference/profiles/start-profile) |
| Delete one     | [DELETE /profiles/\{profile\_uuid}](/api-reference/profiles/delete-profile)    |
| Delete several | [DELETE /profiles](/api-reference/profiles/delete-profiles)                    |

Create with a title and a fingerprint containing `os`. Stop a profile before editing or deleting it. Starting an already running profile can return the existing session.

<span id="error-responses-8" />

<span id="example-request-14" />

<span id="example-request-15" />

<span id="example-response-3" />

<span id="example-response-4" />

<span id="export-cookies" />

<span id="headers-13" />

<span id="headers-14" />

<span id="import-cookies" />

<span id="query-parameters-1" />

<span id="request-body-parameters-2" />

### Cookies

Use [export cookies](/api-reference/profiles/export-cookies) and [import cookies](/api-reference/profiles/import-cookies) on a stopped persistent profile. See the [cookie guide](/cookies) for JSON and Netscape formats and login-state requirements.

<span id="body-parameters-3" />

<span id="error-responses-9" />

<span id="example-request-16" />

<span id="headers-15" />

<span id="path-parameters-2" />

<span id="response-10" />

<span id="scrape-page" />

<span id="scraping-api" />

## Scraping

[POST /profiles/\{internal\_uuid}/scrape](/api-reference/profiles/scrape-page) returns rendered HTML, cookies, and an optional screenshot from a running browser. Read [Scraping API](/quickstart/scraping_api) for a full lifecycle example and batch behavior.

<span id="domain-matching-rules" />

<span id="domain-routing" />

<span id="error-response-403-forbidden" />

<span id="example-request-17" />

<span id="example-request-18" />

<span id="example-request-19" />

<span id="example-request-20" />

<span id="example-request-21" />

<span id="example-request-22" />

<span id="example-request-23" />

<span id="example-request-24" />

<span id="example-request-25" />

<span id="example-request-26" />

<span id="example-response-10" />

<span id="example-response-11" />

<span id="example-response-12" />

<span id="example-response-13" />

<span id="example-response-14" />

<span id="example-response-5" />

<span id="example-response-6" />

<span id="example-response-7" />

<span id="example-response-8" />

<span id="example-response-9" />

<span id="example-route-google-through-different-proxy" />

<span id="example-with-a-carrier-asn" />

<span id="example-with-an-explicit-tier" />

<span id="example-with-coordinates" />

<span id="example-with-country-and-region" />

<span id="example-with-country-only" />

<span id="example-with-country-region-and-city" />

<span id="get-premium-proxy-asns" />

<span id="get-premium-proxy-cities" />

<span id="get-premium-proxy-countries" />

<span id="get-premium-proxy-pools" />

<span id="get-premium-proxy-regions" />

<span id="get-premium-quota" />

<span id="get-premium-traffic-stats" />

<span id="get-shared-proxy-countries" />

<span id="get-shared-traffic-quota" />

<span id="get-shared-traffic-stats" />

<span id="headers-16" />

<span id="headers-17" />

<span id="headers-18" />

<span id="headers-19" />

<span id="headers-20" />

<span id="headers-21" />

<span id="parameters-3" />

<span id="parameters-4" />

<span id="path-parameters-3" />

<span id="path-parameters-4" />

<span id="path-parameters-5" />

<span id="pattern-format" />

<span id="proxies" />

<span id="proxy-blacklist" />

<span id="proxy-geolocation-parameters" />

<span id="proxy-session-parameters" />

<span id="response-fields-3" />

<span id="using-proxy-geolocation" />

## Proxy reference

Use the [proxy guide](/proxies) to choose a tier, target a location, provide a VPN, block domains, or route domains through different connections.

Location lookup starts with [countries](/api-reference/proxies/list-premium-countries) or [geographic pools](/api-reference/proxies/list-proxy-pools). Shared proxies have their own [country list](/api-reference/proxies/list-shared-countries).

`GET /proxies/quota` is a legacy alias for [premium quota](/api-reference/proxies/get-premium-quota), not a combined quota for both tiers. Check [shared quota](/api-reference/proxies/get-shared-quota) separately. [Premium](/api-reference/proxies/get-premium-traffic-stats) and [shared](/api-reference/proxies/get-shared-traffic-stats) traffic statistics report time windows.

<span id="error-responses-10" />

<span id="example-request-27" />

<span id="example-request-28" />

<span id="example-request-29" />

<span id="example-response-15" />

<span id="example-response-16" />

<span id="example-response-17" />

<span id="fingerprint" />

<span id="get-device-models" />

<span id="get-renderers" />

<span id="get-screens" />

<span id="headers-22" />

<span id="headers-23" />

<span id="headers-24" />

<span id="query-parameters-2" />

<span id="query-parameters-3" />

<span id="query-parameters-4" />

## Fingerprint reference

Look up [renderers](/api-reference/fingerprints/list-renderers), [screens](/api-reference/fingerprints/list-screens), and [device models](/api-reference/fingerprints/list-device-models). Leave fields generated unless your workload needs a specific value; see [fingerprints](/fingerprints).

<span id="body-parameters-4" />

<span id="delete-extension" />

<span id="example-request-30" />

<span id="example-request-31" />

<span id="example-request-32" />

<span id="example-request-33" />

<span id="example-request-34" />

<span id="form-parameters" />

<span id="get-extension" />

<span id="headers-25" />

<span id="headers-26" />

<span id="headers-27" />

<span id="headers-28" />

<span id="headers-29" />

<span id="list-extensions" />

<span id="path-parameters-6" />

<span id="path-parameters-7" />

<span id="path-parameters-8" />

<span id="response-11" />

<span id="response-12" />

<span id="response-13" />

<span id="response-14" />

<span id="response-15" />

<span id="update-extension" />

<span id="upload-extension" />

## Extensions

[Upload a ZIP](/api-reference/extensions/upload-extension) and use the returned UUID when starting a browser. The [extension guide](/extensions) covers packaging, loading, updating metadata, and deletion.

<span id="check-captcha-balance" />

<span id="enable-captcha-solving" />

<span id="example-request-35" />

<span id="headers-30" />

<span id="how-auto_captcha_types-works" />

<span id="one-time-profile-example" />

<span id="parameters-1" />

<span id="response-fields-4" />

<span id="success-response-200-ok-2" />

## CAPTCHA solving

Enable `anti_captcha` on the start request, then use the [CAPTCHA CDP commands](/captcha-solving). [GET /captcha/balance](/api-reference/captcha/get-solver-balance) reports configured solver balances.

## Endpoints that are not generated

The endpoints below forward live browser protocol traffic or expose account information outside the generated reference.

### CDP over WebSocket

```text theme={null}
wss://YOUR_API_HOST/proxy/{internal_uuid}
wss://YOUR_API_HOST/proxy/{internal_uuid}/{path}
```

Connect using the returned `ws_url`. See the [framework guides](/quickstart#choose-an-integration) for the exact connection and cleanup steps.

### DevTools HTTP

```text theme={null}
GET https://YOUR_API_HOST/proxy/{internal_uuid}/inspector
GET https://YOUR_API_HOST/proxy/{internal_uuid}/{path}
PUT https://YOUR_API_HOST/proxy/{internal_uuid}/{path}
```

The proxy exposes discovery endpoints such as `/json/list` and `/json/version`. See [debugging](/debugging) to open a page's inspector.

### ChromeDriver

```text theme={null}
GET|POST|PUT|DELETE https://YOUR_API_HOST/chromedriver/{internal_uuid}/{path}
```

Start with `enable_chromedriver: true`, then use this URL as Selenium's remote server. See the [Selenium quickstart](/quickstart/selenium).

### Screencast

```text theme={null}
wss://YOUR_API_HOST/screencast/{internal_uuid}/devtools/page/{page_id}
```

Use `inspector.screencast` from the start response to receive live JPEG frames. See [Screencast](/screencast) for a viewer example.

<span id="error-responses-11" />

<span id="error-responses-12" />

<span id="error-responses-13" />

<span id="example-request-36" />

<span id="example-request-37" />

<span id="example-request-38" />

<span id="example-response-18" />

<span id="example-response-19" />

<span id="get-browser-limits" />

<span id="get-plan" />

<span id="headers-31" />

<span id="headers-32" />

<span id="headers-33" />

<span id="response-fields-5" />

<span id="response-fields-6" />

<span id="response-fields-7" />

<span id="user-account" />

### Account limits

| Endpoint                    | Reports                                                                    |
| --------------------------- | -------------------------------------------------------------------------- |
| `GET /users/plan`           | Account plan and allowances.                                               |
| `GET /users/browser-limits` | Running browsers and capacity; `available` is present for capped accounts. |

See [limits](/limits) for response details and how each limit affects a job.

## Rate limits

Profile responses report minute and hour request limits in `X-Ratelimit-Limit`, `X-Ratelimit-Limit-Hour`, `X-Ratelimit-Remaining`, and `X-Ratelimit-Remaining-Hour`.

Exhausting either window returns `429 rate_limits_reached`. Other `429` codes represent browser or quota limits. Use the [error code](/errors#retrying) to decide what to do next.
