A Playwright proxy is an object with server, username and password, passed either to launch() for the whole browser or to new_context() for one context. Per-context proxies are how you run several IPs from one browser process.

browser = p.chromium.launch(proxy={"server": "http://HOST:PORT", "username": "USERNAME", "password": "PASSWORD"})

The snippets on this page ran on 2026-09-29 with Playwright 1.63 for Python and for Node.js, driving Chrome, against two local authenticating HTTP proxies and a SOCKS5 proxy that enforces credentials.

Before you start: copy your proxy details

  1. Open your order in the dashboard at https://app.proxyhive.io.
  2. Copy HOST, PORT, USERNAME and PASSWORD. Each ISP or datacenter IP is its own endpoint, with its own HTTP, HTTPS and SOCKS5 ports listed on the order. With Playwright, use the HTTP port unless you have allowlisted your IP (see SOCKS5 below).
  3. Export them:
export PROXY_SERVER="http://HOST:PORT" PROXY_USER=USERNAME PROXY_PASS=PASSWORD

Browser automation against logged-in or session-heavy sites is where static ISP proxies earn their keep: the address stays the same for the whole term.

Playwright Python proxy: launch-level

import os

from playwright.sync_api import sync_playwright

proxy = {
    "server": os.environ["PROXY_SERVER"],
    "username": os.environ["PROXY_USER"],
    "password": os.environ["PROXY_PASS"],
}

with sync_playwright() as p:
    browser = p.chromium.launch(proxy=proxy)
    page = browser.new_page()
    page.goto("https://api.ipify.org?format=json")
    print(page.inner_text("body"))
    browser.close()

The fields match the Playwright network docs: server is required, username and password are optional, and bypass takes a comma-separated list of hosts that should skip the proxy, such as "localhost,.internal.example".

Playwright Node.js proxy

The same object in JavaScript:

import { chromium } from 'playwright';

const browser = await chromium.launch({
  proxy: {
    server: process.env.PROXY_SERVER,
    username: process.env.PROXY_USER,
    password: process.env.PROXY_PASS,
  },
});
const page = await browser.newPage();
await page.goto('https://api.ipify.org?format=json');
console.log(await page.textContent('body'));
await browser.close();

Keep credentials in username and password, not in the server URL. Playwright answers the proxy's 407 challenge with them for you, which is the part Puppeteer and Selenium make you handle yourself.

Playwright per-context proxy for rotation

A context is an isolated browser profile: its own cookies, storage and, if you give it one, its own proxy. One browser process can hold many.

import os

from playwright.sync_api import sync_playwright

servers = os.environ["PROXY_SERVERS"].split(",")

with sync_playwright() as p:
    browser = p.chromium.launch()
    for server in servers:
        context = browser.new_context(proxy={
            "server": server,
            "username": os.environ["PROXY_USER"],
            "password": os.environ["PROXY_PASS"],
        })
        page = context.new_page()
        page.goto("https://api.ipify.org?format=json")
        print(server, page.inner_text("body"))
        context.close()
    browser.close()

In Node it is browser.newContext({ proxy: { server, username, password } }), and our run showed the two contexts leaving through their two proxies from one browser. If your IPs have different credentials, keep server, username and password together per IP in whatever list you load.

Rotation here means one IP per context, not per request. That is the right shape for browsers: a site that sees one session hop between addresses mid-login is more suspicious than one that sees a stable address. The trade-offs are laid out in rotating vs static proxies.

Proxy authentication with an IP allowlist

If your automation runs on a server with a fixed address, switch the IP to allowlist authentication on the order in the dashboard and add that server's public IP. Then proxy={"server": "http://HOST:PORT"} is all Playwright needs. It also unlocks SOCKS5, below.

Playwright SOCKS5 proxy: no authentication

Playwright accepts socks5://HOST:PORT as a server. It does not accept SOCKS5 with credentials: set a username or password and launch() throws Browser does not support socks5 proxy authentication. That check lives in Playwright's proxy normalisation, so it applied to both Chromium and Firefox in our run. Your options:

  1. Use the HTTP port with username and password (simplest; the page traffic is still encrypted end to end inside the tunnel).
  2. Allowlist your IP and use socks5://HOST:SOCKS5_PORT with no credentials.

HTTP vs SOCKS5 proxies explains why option 1 costs a browser nothing.

Verify the exit IP

The snippets above print the proxied address from https://api.ipify.org?format=json. Compare it with the IP on your order, and with the address the same code prints without the proxy option. If both match, the proxy is being ignored: check that you passed it to the browser or context that opened the page.

Timeouts and retries

Proxied page loads are slower than direct ones, especially the first request of a context, which pays for the CONNECT and the TLS handshake. Set timeouts on the context and retry navigations that fail:

context.set_default_navigation_timeout(45_000)

for attempt in range(3):
    try:
        page.goto(url, wait_until="domcontentloaded")
        break
    except Exception:
        if attempt == 2:
            raise

wait_until="domcontentloaded" avoids waiting on third-party trackers that never settle and whose traffic you pay for.

Common Playwright proxy errors

ErrorCauseFix
Browser does not support socks5 proxy authenticationsocks5:// server plus username or passwordHTTP port, or allowlist and drop credentials
net::ERR_HTTP_RESPONSE_CODE_FAILURE on gotoThe proxy answered 407 to the credentialsRe-copy username and password
net::ERR_PROXY_CONNECTION_FAILEDWrong host or portCheck the port for the protocol in server
Timeout 30000ms exceededSlow first load, or a heavy pageRaise the navigation timeout; use domcontentloaded

Status codes from the target itself are covered in proxy error codes.

Next steps