Antidetect browser automation with Playwright and Selenium (2026)
You're paying for antidetect browser profiles with carefully spoofed fingerprints. You connect Playwright, run your first script, and the target flags you anyway. The automation framework just leaked everything the antidetect browser was hiding. Here's how to connect properly.
Hire a Clawd is our own service.
Every major antidetect browser ships a local API now. Multilogin, AdsPower, GoLogin, Dolphin Anty, Kameleo. They all expose some variant of Chrome DevTools Protocol that Playwright or Selenium can connect to. The documentation is scattered (half of it outdated, the rest incomplete), and none of it warns you about the fingerprint leaks that happen the moment you attach an automation framework to a profile that was built to look human.
I spent a couple weeks connecting Playwright and Selenium to all five, running them against fingerprint-detection services, and cataloging which combinations actually hold up. Below is what works, what quietly fails, and the exact code to get each one automated without burning the fingerprint you're paying for.
How antidetect browser APIs work
The pattern is the same everywhere. The antidetect app runs locally (or on a VPS), manages a pool of browser profiles with unique fingerprints, and exposes a REST API on a local port. You hit the API to start a profile. It launches a Chromium instance with that profile's fingerprint loaded. You get back either a WebSocket URL for Playwright's CDP connection or a debugging port number for Selenium.
The important thing: the antidetect browser handles the fingerprint. Your automation framework just drives the already-configured browser. You're not injecting stealth patches or spoofing canvas from your script. The browser shipped with those spoofs baked in at a level that (in theory) detection can't tell apart from native behavior.
In practice, "in theory" is doing a lot of heavy lifting there. Connecting an automation tool can undo half that work if you're not careful. More on that in the leaks section.
Multilogin with Playwright
Multilogin X runs a local agent on port 35000. You authenticate with an API token, start a profile, get back a WebSocket endpoint, and connect Playwright over CDP.
import requests
from playwright.sync_api import sync_playwright
PROFILE_ID = "your-profile-id"
MLX_BASE = "http://127.0.0.1:35000/api/v2"
TOKEN = "your-api-token"
headers = {"Authorization": f"Bearer {TOKEN}"}
resp = requests.post(
f"{MLX_BASE}/profile/{PROFILE_ID}/start",
headers=headers,
)
ws_endpoint = resp.json()["data"]["wsEndpoint"]
with sync_playwright() as pw:
browser = pw.chromium.connect_over_cdp(ws_endpoint)
page = browser.contexts[0].pages[0] # grab the existing context, don't create a new one
page.goto("https://example.com")
print(page.title())
browser.close()
A few things that tripped me up. That connect_over_cdp call grabs the existing
browser context, the one Multilogin already fingerprinted. If you call
browser.new_context() instead, you get a vanilla Chromium context with zero spoofing
applied. That's the single most common mistake I see on forums, and it completely defeats the
purpose of running an antidetect browser in the first place.
The other thing: Multilogin's agent process needs to be running before you hit the API. Obvious, but on a Linux VPS without a desktop, that means running under Xvfb or their headless agent mode (which they added late 2025). On your dev machine the desktop app handles it, but production servers need the headless setup or a virtual display.
AdsPower and GoLogin
AdsPower exposes its API on port 50325 by default. Same flow, slightly different response shape.
import requests
from playwright.sync_api import sync_playwright
ADS_BASE = "http://local.adspower.net:50325"
PROFILE_ID = "your-profile-id"
resp = requests.get(
f"{ADS_BASE}/api/v1/browser/start",
params={"user_id": PROFILE_ID},
)
data = resp.json()["data"]
ws_url = data["ws"]["puppeteer"]
with sync_playwright() as pw:
browser = pw.chromium.connect_over_cdp(ws_url)
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
print(page.title())
# always stop the profile when done
requests.get(
f"{ADS_BASE}/api/v1/browser/stop",
params={"user_id": PROFILE_ID},
)
That stop call matters. AdsPower doesn't clean up orphaned browser processes on its own, and if your script crashes without stopping the profile, it stays locked until you kill it manually. I found out the hard way after leaving 30+ zombie Chromium instances chewing through RAM on a VPS overnight. Debugging that at 2 AM was not my best hour.
GoLogin follows the same pattern with different endpoints and an auth token requirement:
import requests
from playwright.sync_api import sync_playwright
GL_BASE = "http://localhost:36912"
PROFILE_ID = "your-profile-id"
TOKEN = "your-api-token"
headers = {"Authorization": f"Bearer {TOKEN}"}
resp = requests.post(
f"{GL_BASE}/browser/start-profile",
json={"profileId": PROFILE_ID, "sync": True},
headers=headers,
)
ws_url = resp.json()["wsUrl"]
with sync_playwright() as pw:
browser = pw.chromium.connect_over_cdp(ws_url)
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
print(page.title())
GoLogin also ships an official Node.js SDK that wraps all of this. If you're working in JavaScript, it's cleaner than raw HTTP calls. From Python, the REST API works fine.
Dolphin Anty and Kameleo
Dolphin Anty takes a slightly different approach. Instead of handing you a WebSocket URL, it gives you a remote debugging port. That maps naturally to Selenium.
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
DOLPHIN_BASE = "http://localhost:3001/v1.0"
PROFILE_ID = "your-profile-id"
resp = requests.get(
f"{DOLPHIN_BASE}/browser_profiles/{PROFILE_ID}/start",
params={"automation": 1},
)
port = resp.json()["automation"]["port"]
options = Options()
options.debugger_address = f"127.0.0.1:{port}"
driver = webdriver.Chrome(options=options)
driver.get("https://example.com")
print(driver.title)
The automation=1 query parameter is the thing people miss. Without it, the browser
launches but there's no debugging port exposed, and Selenium just hangs on connect. The Dolphin
Anty docs bury this in a footnote.
Kameleo is the outlier in this group. It supports both Chromium and Firefox profiles with managed fingerprints, and runs its API on port 5050. If you need automated Firefox with spoofed fingerprints (maybe the target flags Chromium automation specifically), Kameleo is basically the only commercial option that does it.
import requests
from playwright.sync_api import sync_playwright
KAMELEO_BASE = "http://localhost:5050"
PROFILE_ID = "your-profile-id"
requests.post(f"{KAMELEO_BASE}/profiles/{PROFILE_ID}/start")
resp = requests.get(f"{KAMELEO_BASE}/profiles/{PROFILE_ID}")
port = resp.json()["externalSpoofingEnginePort"]
with sync_playwright() as pw:
browser = pw.chromium.connect_over_cdp(f"ws://localhost:{port}")
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
print(page.title())
Pick an antidetect browser that fits your profile count
All five tools above support API-driven automation. The differences come down to pricing per profile, team sync features, and whether you need Firefox support. If you're running more than a handful of persistent identities, the managed fingerprints pay for themselves in hours you don't spend debugging detection failures.
Persistent sessions and profile syncing
The whole reason you're paying for an antidetect browser (instead of spinning up disposable stealth instances) is that profiles persist. Cookies, localStorage, IndexedDB, login state. When your script reconnects tomorrow, it picks up where it left off, and the target sees a returning visitor instead of a fresh session every time.
But syncing is where things get fragile.
Multilogin and GoLogin sync profiles to their cloud by default. AdsPower stores them locally (optional cloud sync). Dolphin Anty syncs to their servers. The practical problem: if your script crashes mid-session, the profile state might not save. Most of these tools only flush to disk when you properly stop the profile via the API. Kill the process and you lose everything since the last sync point.
So: always wrap your automation in a try/finally that calls the stop endpoint.
profile_started = False
try:
resp = start_profile(profile_id)
profile_started = True
# ... your automation work here ...
finally:
if profile_started:
stop_profile(profile_id)
Concurrency is the other trap. Two scripts starting the same profile simultaneously gives you corrupted fingerprint state (Multilogin), a lock error (AdsPower), or silent data loss (GoLogin). One profile, one session, always. If you need parallel automation, create separate profiles. The per-profile cost is usually small compared to the cost of debugging corrupted state at scale.
A lot of moving parts to keep running
Profile APIs, proxy geo matching, session persistence, fingerprint leak testing, and all of it drifts as vendors update their browsers and targets update their detection. Hire a Clawd runs your browser automation around the clock, manages the profiles, and delivers the data. You skip the plumbing.
See plans from $49/mo →Fingerprint leaks that break your cover
This is the part nobody's marketing page mentions. You paid for a carefully crafted fingerprint, connected Playwright or Selenium, and then the automation framework injected artifacts that any decent detection script catches on the first page load.
The ones I keep running into:
navigator.webdriver. Both Playwright and Selenium set this to true
when they attach. Some antidetect browsers (Multilogin, AdsPower) patch it back to
false after connection. Others don't. Test yours. Run
page.evaluate("navigator.webdriver") immediately after connecting and verify it
returns false. If it doesn't, your expensive fingerprint is wasted.
CDP artifacts. Connecting via Chrome DevTools Protocol can leave behind internal
variables like document.$cdc_ (the classic ChromeDriver signature) or
Runtime.enable side effects that detection scripts look for. Multilogin and AdsPower
scrub most of these. Dolphin Anty is spottier. If you're using Selenium, verify that
ChromeDriver's fingerprints aren't leaking through.
WebRTC IP leaks. If the profile doesn't disable or proxy WebRTC, your server's real IP leaks through STUN requests even with a proxy configured. Every antidetect browser has a per-profile WebRTC setting. Set it to "disable non-proxied UDP" or turn it off entirely. Don't assume the default is safe, because on most of these tools it isn't.
Timezone and locale mismatches. Profile says Berlin, proxy exits in Tokyo. Same coherence problem that trips up regular stealth browsers (covered in the bot detection checklist). Antidetect browsers don't fix this automatically. You have to set the profile's timezone and locale to match your proxy's exit location, and if you're rotating proxies across geos, you need a profile per region.
Test every profile against CreepJS or BrowserLeaks before you route production traffic through it. Five minutes of checking saves you from burning a profile that took twenty minutes to configure.
Proxies that match your profile's geo
Your antidetect profile's timezone and locale need to line up with the proxy exit IP. A residential pool with per-country or per-city targeting lets you match each profile to a believable location instead of hoping the defaults don't clash.
Antidetect browsers vs open-source stealth
The honest question: when do you actually need a paid antidetect browser instead of something free like Camoufox or a patched Playwright setup?
Use an antidetect browser when:
- You're managing dozens (or hundreds) of persistent identities and need each one to look like a unique, returning human over weeks or months.
- Your team shares profiles across machines, and nobody wants to hand-configure fingerprint settings from scratch every time.
- The target ties login sessions to browser fingerprints, and a fresh fingerprint on every login triggers re-verification or locks the account.
Use open-source stealth when:
- You're scraping public pages without login. Disposable sessions work fine. No profile needs to survive past the script.
- You're running at scale where per-profile licensing ($10-30/month per 100 profiles, depending on tier) makes the math worse than spinning up Camoufox instances with residential proxies.
- You want Firefox-level stealth without vendor lock-in. Camoufox patches at the binary level (harder to detect than Chromium extension injection), and you control the whole stack.
The risk/reward framing: antidetect browsers are an ongoing cost you pay for managed fingerprints and lower maintenance. If your use case doesn't need persistent identity across sessions, you're paying for convenience, not for detection resistance you couldn't get with open-source tools. A well-configured Camoufox setup with clean proxies passes the same checks for a fraction of the recurring cost. But if you need 200 accounts to look human for three months, building that from scratch in Camoufox is a project, and paying Multilogin $50/month to manage the fingerprints starts looking like the right trade.
Skip the setup
The Anti-Detect Scraping Starter Kit
A ready-to-run Camoufox + residential proxy Python template with humanized behavior, fingerprint-leak checks, and a pre-flight walkthrough that covers every layer on this page. Wired up so your first scrape doesn't get you insta-flagged.
$19 one-time
Get the kit →FAQ
Do antidetect browsers work in headless mode on a server?
Most of them need a display to render (the fingerprint depends on canvas and WebGL output that
requires an actual render path). On a VPS, run the antidetect app under Xvfb or a virtual
display. Multilogin added a headless agent mode in late 2025, but the others still need a display
server. Wrapping the launch command with xvfb-run is the standard workaround for
Linux boxes without a desktop.
Can I connect Playwright to any antidetect browser?
If the browser exposes a Chrome DevTools Protocol endpoint (WebSocket URL or debugging port),
Playwright can attach with connect_over_cdp(). All five tools here do this. The
differences are in response shape, authentication, port defaults, and how well they clean up
automation artifacts after you connect. Always grab the existing context instead of creating a new
one, or you lose the fingerprint.
How many profiles can I automate in parallel?
Depends on hardware and your subscription tier. Each profile runs a full Chromium process (figure 300-500 MB of RAM per profile, more with heavy pages). On a 16 GB VPS, you can realistically run 20-30 concurrent profiles. RAM is usually the bottleneck, not CPU. Both Multilogin and AdsPower cap concurrent profiles by plan, so check your tier's limits before you architect around 50 parallel sessions.
Is it legal to use antidetect browsers for scraping?
The browsers themselves are legal software (used widely for ad verification, QA testing, and multi-account management). Whether your specific scraping is legal depends on what data you're collecting, the site's terms of service, rate limits, and applicable privacy law. Pulling public data at a reasonable pace is broadly fine in most jurisdictions. If you're doing something high-stakes or touching personal data, talk to a lawyer. We're not one. More background in our legality overview.