[cdpfleet](https://cdpfleet.com/) / Proxies

Every session

# Your exit, *your rules*.

A cdpfleet browser never browses from our servers' own IPs. Send your own proxy, a pool, or different proxies for different hosts; change the exit of a running browser without restarting it; or use the cdpfleet residential proxy by tier, country and sticky session. Leave `proxy` out and the free Community proxy is used.

[Proxy docs](https://cdpfleet.com/docs/proxies)[Build the code](https://cdpfleet.com/docs/builder)

-   **SOCKS5**with auth, on every browser
-   **$0.50–$5**per GB, residential
-   **0**second IPs leaked over WebRTC

## Bring your own

-   **Formats:** `http://user:pass@host:8080`, `https://…`, `socks5://user:pass@host:1080`, a bare `host:8080` (taken as HTTP), or an object `{ "server", "username", "password" }`. Authenticated SOCKS5 works on every browser.
-   **Pools:** pass a list and requests are spread across it round-robin.
-   **Per-host rules:** `proxy_rules` sends hosts you name (with `*` wildcards) through their own proxy or pool; everything else uses `proxy`. One SOCKS5 host, one pool and residential for the rest, in one browser ([case 07](https://cdpfleet.com/docs/cases/per-host-proxy-rules)).
-   **Your proxies are free** on every plan; only the cdpfleet residential proxy is billed, by the GB.

```json
{
  "proxy": [
    "http://u:p@res1.example:8080",
    "socks5://u:p@res2.example:1080"
  ],
  "proxy_rules": [
    {
      "hosts": [
        "*.cloudfront.net",
        "static.*"
      ],
      "proxy": "http://u:p@dc.example:4444"
    }
  ]
}
```

## Change the exit while the browser runs

-   **One API call** to the host of your `wsUrl` changes a running session's proxy and rules; the browser, its cookies and its login stay ([case 06](https://cdpfleet.com/docs/cases/live-proxy-swap)). Every session can be swapped; no launch option is needed.
-   **New connections use the new exit at once; open ones finish on the old one.** Keep-alive connections are the trap: move them over by carrying `storageState` into a fresh context ([case 06](https://cdpfleet.com/docs/cases/live-proxy-swap)).
-   **The update replaces the whole route:** send `proxy` and the complete `proxy_rules` you want.
-   **When a site pushes back:** wait out `Retry-After`, then move the session to another exit — the crawler that did got 8 of 8 pages with its login intact; the one that retried at once got 3–4 ([case 53](https://cdpfleet.com/docs/cases/soft-block-backoff)).

## No proxy of your own: the cdpfleet residential proxy

Send a `cdpfleet-resi` token as `proxy` and pick the price tier (Tier 1 $5, Tier 2 $2.50, Tier 3 $1, Tier 4 $0.50 per GB), the exit country, the device OS of the IP (Tier 1 and 2 only) and whether the IP stays the same (`-session-ID`, `-lifetime-MIN`). One prepaid USD balance pays for every tier; every account starts with $5 free credit ([case 25](https://cdpfleet.com/docs/cases/residential-without-a-proxy)).

**Mix tiers per host:** the page on Tier 1, its image hosts on Tier 4 with `proxy_rules` — the bytes billed per tier matched what the browser counted, and a gallery load cost well under half ([case 51](https://cdpfleet.com/docs/cases/resi-tiers-mix)). Details and pricing: [residential proxy](https://cdpfleet.com/residential-proxy).

The same US residential IP for up to 30 minutes

 

```node
// npm install playwright@1.60.0
// Browsers run on cdpfleet, so no `npx playwright install` is needed.
import { chromium } from 'playwright';

const KEY = process.env.CDPFLEET_API_KEY;

// 1. Launch the browser
const res = await fetch('https://starter.cdpfleet.com/chromium/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({
    proxy: 'cdpfleet-resi-country-us-session-cart1-lifetime-30',
    headless: 'new',
  }),
});
if (!res.ok) throw new Error(`launch failed: ${res.status} ${await res.text()}`);
const { wsUrl } = await res.json();

// 2. Connect and drive it
const browser = await chromium.connect(wsUrl, { headers: { 'x-api-key': KEY } });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close(); // ends the session and stops billing
```

```python
# pip install playwright==1.60.0 requests
# Browsers run on cdpfleet, so no `playwright install` is needed.
import os
import requests
from playwright.sync_api import sync_playwright

KEY = os.environ["CDPFLEET_API_KEY"]

# 1. Launch the browser
res = requests.post(
    "https://starter.cdpfleet.com/chromium/session",
    headers={"x-api-key": KEY},
    json={
        "proxy": "cdpfleet-resi-country-us-session-cart1-lifetime-30",
        "headless": "new",
    },
    timeout=60,
)
res.raise_for_status()
ws_url = res.json()["wsUrl"]

# 2. Connect and drive it
with sync_playwright() as p:
    browser = p.chromium.connect(ws_url, headers={"x-api-key": KEY})
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()  # ends the session and stops billing
```

```java
// Maven: com.microsoft.playwright:playwright:1.60.0  and  com.google.code.gson:gson:2.11.0
// Run with PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1: browsers run on cdpfleet.
import com.google.gson.JsonParser;
import com.microsoft.playwright.*;
import java.net.URI;
import java.net.http.*;
import java.util.Map;

public class Example {
  public static void main(String[] args) throws Exception {
    String key = System.getenv("CDPFLEET_API_KEY");

    // 1. Launch the browser
    String body = """
        {
          "proxy": "cdpfleet-resi-country-us-session-cart1-lifetime-30",
          "headless": "new"
        }
        """;
    HttpResponse<String> res = HttpClient.newHttpClient().send(
        HttpRequest.newBuilder(URI.create("https://starter.cdpfleet.com/chromium/session"))
            .header("x-api-key", key)
            .header("content-type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build(),
        HttpResponse.BodyHandlers.ofString());
    if (res.statusCode() != 200) {
      throw new RuntimeException("launch failed: " + res.statusCode() + " " + res.body());
    }
    String wsUrl = JsonParser.parseString(res.body()).getAsJsonObject().get("wsUrl").getAsString();

    // 2. Connect and drive it
    try (Playwright playwright = Playwright.create()) {
      Browser browser = playwright.chromium().connect(wsUrl,
          new BrowserType.ConnectOptions().setHeaders(Map.of("x-api-key", key)));
      Page page = browser.newPage();
      page.navigate("https://example.com");
      System.out.println(page.title());
      browser.close(); // ends the session and stops billing
    }
  }
}
```

```csharp
// dotnet add package Microsoft.Playwright --version 1.60.0
// Browsers run on cdpfleet, so no `playwright install` is needed.
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using Microsoft.Playwright;

var key = Environment.GetEnvironmentVariable("CDPFLEET_API_KEY")!;

// 1. Launch the browser
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", key);
var body = """
    {
      "proxy": "cdpfleet-resi-country-us-session-cart1-lifetime-30",
      "headless": "new"
    }
    """;
var res = await http.PostAsync("https://starter.cdpfleet.com/chromium/session",
    new StringContent(body, Encoding.UTF8, "application/json"));
if (!res.IsSuccessStatusCode)
    throw new Exception($"launch failed: {(int)res.StatusCode} {await res.Content.ReadAsStringAsync()}");
var wsUrl = (await res.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("wsUrl").GetString()!;

// 2. Connect and drive it
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.ConnectAsync(wsUrl, new BrowserTypeConnectOptions
{
    Headers = new Dictionary<string, string> { ["x-api-key"] = key },
});
var page = await browser.NewPageAsync();
await page.GotoAsync("https://example.com");
Console.WriteLine(await page.TitleAsync());
await browser.CloseAsync(); // ends the session and stops billing
```

```go
// go get github.com/playwright-community/playwright-go@v0.6000.0
//
// One-time driver setup (needs Node.js 18+): playwright-go can no longer download the
// 1.60.0 driver itself, so build it from npm and point PLAYWRIGHT_DRIVER_PATH at it:
//   mkdir -p ~/.cache/pw-driver-1.60.0 && cd ~/.cache/pw-driver-1.60.0 &&
//     curl -sL https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz | tar xz &&
//     ln -sf "$(command -v node)" node
//   export PLAYWRIGHT_DRIVER_PATH=~/.cache/pw-driver-1.60.0
// Browsers run on cdpfleet, so no browsers are downloaded (SkipInstallBrowsers).
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/playwright-community/playwright-go"
)

func main() {
	key := os.Getenv("CDPFLEET_API_KEY")

	// 1. Launch the browser
	body := `{
	  "proxy": "cdpfleet-resi-country-us-session-cart1-lifetime-30",
	  "headless": "new"
	}`
	req, _ := http.NewRequest("POST", "https://starter.cdpfleet.com/chromium/session", strings.NewReader(body))
	req.Header.Set("x-api-key", key)
	req.Header.Set("content-type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		msg, _ := io.ReadAll(res.Body)
		log.Fatalf("launch failed: %s %s", res.Status, msg)
	}
	var session struct {
		WsURL string `json:"wsUrl"`
	}
	if err := json.NewDecoder(res.Body).Decode(&session); err != nil {
		log.Fatal(err)
	}

	// 2. Connect and drive it (Install fetches only the Playwright driver, once)
	opts := &playwright.RunOptions{SkipInstallBrowsers: true}
	if err := playwright.Install(opts); err != nil {
		log.Fatal(err)
	}
	pw, err := playwright.Run(opts)
	if err != nil {
		log.Fatal(err)
	}
	defer pw.Stop()
	browser, err := pw.Chromium.Connect(session.WsURL, playwright.BrowserTypeConnectOptions{
		Headers: map[string]string{"x-api-key": key},
	})
	if err != nil {
		log.Fatal(err)
	}
	page, err := browser.NewPage()
	if err != nil {
		log.Fatal(err)
	}
	if _, err := page.Goto("https://example.com"); err != nil {
		log.Fatal(err)
	}
	title, _ := page.Title()
	fmt.Println(title)
	browser.Close() // ends the session and stops billing
}
```

## UDP, WebRTC and your own VPN

-   **A proxy carries TCP only:** behind one, no setup exposed a second public IP over WebRTC — Chromium, Chrome and Firefox show an anonymous mDNS name, Camoufox the exit, and `block_webrtc` removes the API ([case 54](https://cdpfleet.com/docs/cases/webrtc-ip-leak)).
-   **VPN Tunnel** (`"vpn_tunnel": true`, a Tier 1 or 2 residential token, or your own proxy on dedicated plans) gives the browser UDP through the same exit: WebRTC shows exactly the exit IP and HTTP/3 works ([case 69](https://cdpfleet.com/docs/cases/vpn-tunnel-vs-proxy)). Keep the token sticky, and don't combine it with `proxy_rules`: UDP can then leave through a rule's proxy.
-   **Your own VPN** (dedicated plans): `vpn` with a WireGuard, AmneziaWG, OpenVPN or sing-box config — or the name of one saved in the dashboard — sends everything, UDP and DNS included, through your VPN server. Private and internal addresses are refused as VPN servers.

## The free Community proxy

-   **Leave `proxy` out** and the session uses the Community proxy, free on every plan; a `cdpfleet-plan` token picks a country or a sticky exit.
-   **Free, so not guaranteed:** it's shared and slower, and launches with it can be refused with `503 community_capacity_full` when it's busy. Use it to try things out; bring your own or the residential proxy for work that matters.

## What a proxy costs in speed

-   **Every hop adds time:** connection setup, first byte and full load through three proxies, measured by the browser itself ([case 14](https://cdpfleet.com/docs/cases/proxy-speed)).
-   **WebSockets work through every proxy type,** but each message pays the full proxy path, and the proxy's location decides how much ([case 13](https://cdpfleet.com/docs/cases/websockets-through-proxies)).
-   **Private addresses are refused:** a proxy, a rule's proxy or a VPN server on loopback, private or internal ranges gets `400 invalid_proxy` (or `invalid_vpn_config`) at launch.

## Related

Cases, recipes, posts and comparisons about this — updated as new ones are published.

### Reference docs

The details, options and errors.

-   [Proxies](https://cdpfleet.com/docs/proxies)Formats, pools, rules, live swap, residential, VPN, errors.
-   [Residential proxy](https://cdpfleet.com/residential-proxy)Tiers, targeting and pricing.
-   [Recipe: pool](https://cdpfleet.com/docs/examples#proxy-pool)A round-robin pool.
-   [Recipe: SOCKS5](https://cdpfleet.com/docs/examples#socks5-proxy)An authenticated SOCKS5 proxy.
-   [Recipe: live swap](https://cdpfleet.com/docs/examples#live-proxy-swap)Change the exit mid-session.
-   [Recipe: sticky residential](https://cdpfleet.com/docs/examples#resi-sticky)One residential IP for a whole flow.
-   [Recipe: residential for one host](https://cdpfleet.com/docs/examples#resi-for-one-host)Your proxy by default, residential for one site.
-   [Recipe: VPN Tunnel](https://cdpfleet.com/docs/examples#resi-vpn-tunnel)WebRTC and HTTP/3 on the same exit.
-   [Recipe: Community proxy](https://cdpfleet.com/docs/examples#community-quickstart)No proxy at all.

### Cases 9

Real problems solved end to end, run on production in five languages.

-   [Case 68: CAPTCHA demo pages: what reCAPTCHA v3 scores and hCaptcha show seven browsers, and why a demo can't rank them](https://cdpfleet.com/docs/cases/captcha-scores-by-browser)Google's public reCAPTCHA v3 score demo and hCaptcha's demo widget, loaded once per cell by seven browser setups through your own proxy and a sticky cdpfleet-resi…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/68-captcha-scores-by-browser)
-   [Case 69: VPN Tunnel vs a plain residential proxy: WebRTC, HTTP/3 and two bot-protection pages](https://cdpfleet.com/docs/cases/vpn-tunnel-vs-proxy)The same sticky residential exit with and without `vpn_tunnel`, on headful Chrome and Camoufox: which public IP WebRTC shows, whether HTTP/3 (QUIC) gets used, and…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/69-vpn-tunnel-vs-proxy)
-   [Case 59: Block analytics and beacons, keep the page: what telemetry a scraper sends without knowing](https://cdpfleet.com/docs/cases/intercept-and-block-telemetry)Load three real sites with and without a telemetry block list (analytics, measurement and real-user-monitoring hosts, plus beacons). Count what each page reports…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/59-intercept-and-block-telemetry)
-   [Case 51: Cut residential spend: the page on Tier 1, the images on Tier 4, in one session](https://cdpfleet.com/docs/cases/resi-tiers-mix)The cdpfleet residential proxy has four price tiers, from $5 to $0.50 per GB. Send a gallery page through Tier 1 and its image hosts through Tier 4 with…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/51-resi-tiers-mix)
-   [Case 53: Surviving a soft block: honour Retry-After, then move to another exit without losing the login](https://cdpfleet.com/docs/cases/soft-block-backoff)Two crawlers against the same rate-limited site. The one that retries a 429 straight away is challenged and gets 3 of 8 pages. The one that waits as told and moves…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/53-soft-block-backoff)
-   [Case 54: The WebRTC IP leak test behind a proxy: what Chromium, Chrome, Firefox and Camoufox reveal](https://cdpfleet.com/docs/cases/webrtc-ip-leak)Run the leak test fingerprinting sites use — ICE candidates against a public STUN server — on five setups behind sticky residential exits. No setup exposes a second…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/54-webrtc-ip-leak)
-   [Case 6: Swap a proxy mid-session without losing the login — and the keep-alive trap](https://cdpfleet.com/docs/cases/live-proxy-swap)One API call changes the exit IP of a running browser. Open connections don't follow; storageState moves everything over.[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/06-live-proxy-swap)
-   [Case 7: Different sites, different proxies, one browser: proxy\_rules](https://cdpfleet.com/docs/cases/per-host-proxy-rules)Route one host through a SOCKS5 proxy, another through a round-robin pool and everything else through residential — and the IP-lookup hosts only Camoufox keeps on…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/07-per-host-proxy-rules)

[All cases →](https://cdpfleet.com/docs/cases) 9 match this topic

### Recipes 2

Complete programs for one setup each.

-   [Proxy pool with per-host rules](https://cdpfleet.com/docs/examples#proxy-pool)Spread traffic over two residential exits and send CDN assets through a datacenter pool. See [Proxies](https://cdpfleet.com/docs/proxies).
-   [Residential IPs for one strict host, your own proxy for the rest](https://cdpfleet.com/docs/examples#resi-for-one-host)Keep your own proxy for everything, and send only the host that blocks it through the cdpfleet residential proxy, from the country you need. You then pay residential…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/resi-for-one-host)

## Read next

[Residential proxy →](https://cdpfleet.com/residential-proxy)[Geo testing →](https://cdpfleet.com/geo-testing)[Web scraping →](https://cdpfleet.com/web-scraping)[Bot protection →](https://cdpfleet.com/bot-protection)[Pricing →](https://cdpfleet.com/pricing)

---
Source: https://cdpfleet.com/proxies · Markdown: https://cdpfleet.com/proxies.md · All docs for AI tools: https://cdpfleet.com/llms.txt
