How to Use AdsPower with Playwright: Full Setup Guide
Take a Quick Look
Learn how to connect AdsPower anti-detect browser profiles to Playwright via the Local API and CDP for resilient multi-account automation and scraping.
🔥 Limited-Time Offer! Save extra 10% off on your first monthly plan with code: Anitdetect10
Sign upHow to Use AdsPower with Playwright: Full Setup Guide
AdsPower gives you isolated, fingerprint-protected browser profiles; Playwright gives you a fast, reliable automation framework. When you connect the two, you get a workflow that can manage dozens of accounts, scrape protected pages, and run end-to-end tests inside realistic browser environments without triggering anti-bot defenses. This guide walks through the entire setup, from enabling the AdsPower Local API to writing Python and Node.js scripts that drive profiles through Playwright's CDP connection.
Why Combine AdsPower and Playwright?

Playwright product interface.
Playwright is built for modern web automation. It has auto-waiting, web-first assertions, resilient locators, and native support for connecting to existing browser instances over the Chrome DevTools Protocol (CDP). AdsPower exposes exactly that: a local WebSocket endpoint for every launched profile. By connecting Playwright to that endpoint, you control a fully isolated, fingerprint-spoofed browser session as if it were a normal Chromium instance.
This combination solves a specific set of problems:
- Multi-account safety at scale. Each AdsPower profile has its own cookies, cache, Canvas/WebGL fingerprint, and proxy. Playwright drives them without cross-contamination.
- Fewer blocks during scraping. Anti-detect fingerprints plus Playwright's realistic interaction patterns reduce the chance a target site flags your automation.
- One codebase, many identities. You can loop over profile IDs and run the same Playwright script against hundreds of isolated sessions.
- No custom browser patches. Playwright talks to AdsPower's existing Chromium kernel through CDP, so you keep AdsPower's fingerprint technology intact.
If you are still comparing anti-detect browsers before committing, see AdsPower vs Maskfog vs Incogniton: How to Choose in 2026? for a feature-by-feature breakdown.
Prerequisites

Playwright product interface.
Before writing any code, make sure you have:
- AdsPower installed and running on Windows, macOS, or Linux.
- At least one browser profile created in the AdsPower client. Note the profile ID shown in the profile list.
- Python 3.8+ or Node.js 16+ installed, depending on your language preference.
- Playwright installed in your project:
pip install playwright httpx
# or
npm install playwright axios
- AdsPower Local API enabled. In the AdsPower client, go to Settings > Local API and confirm the service is running on port
50325. If you use API key verification, copy your key; otherwise you can disable verification for local development only.
Understanding the AdsPower Local API
The Local API is a local HTTP service that AdsPower runs on http://127.0.0.1:50325. It lets you start and stop browser profiles programmatically. The key endpoints are:
GET /api/v1/browser/start?user_id={profile_id}— launches a profile and returns connection details.GET /api/v1/browser/stop?user_id={profile_id}— closes a profile.POST /api/v2/browser-profile/start— newer v2 endpoint with additional options likelast_opened_tabsandproxy_detection.
When you start a profile, the response contains a data.ws.puppeteer field. That is the CDP WebSocket endpoint Playwright needs. The response also includes data.webdriver, which is the path to AdsPower's bundled Chrome driver — useful for Selenium but not required for Playwright.
Step 1: Start an AdsPower Profile via the Local API
The first script step is always to launch the profile and capture the CDP endpoint. Here is a minimal Python example using httpx:
import httpx
LOCAL_API_BASE = "http://127.0.0.1:50325"
PROFILE_ID = "your_profile_id_here"
API_KEY = "your_api_key_here" # optional if API verification is disabled
headers = {"Authorization": f"Bearer {API_KEY}"}
response = httpx.post(
f"{LOCAL_API_BASE}/api/v2/browser-profile/start",
headers=headers,
json={
"profile_id": PROFILE_ID,
"last_opened_tabs": "0",
"proxy_detection": "0",
},
)
if response.status_code != 200:
raise RuntimeError(f"Failed to start profile: {response.text}")
data = response.json()
cdp_endpoint = data["data"]["ws"]["puppeteer"]
print(f"CDP endpoint: {cdp_endpoint}")
The last_opened_tabs option controls whether AdsPower restores tabs from the previous session. Setting it to "0" gives you a clean start, which is usually what you want for automation.
Step 2: Connect Playwright to the Profile

Playwright product interface.
Once you have the CDP endpoint, use Playwright's connect_over_cdp to attach to the running browser:
from playwright.sync_api import sync_playwright
with sync_playwright() as playwright:
browser = playwright.chromium.connect_over_cdp(cdp_endpoint)
default_context = browser.contexts[0]
page = default_context.pages[0] if default_context.pages else default_context.new_page()
page.goto("https://www.browserscan.net")
print(page.title())
page.wait_for_timeout(10000)
browser.close()
For Node.js, the pattern is nearly identical:
const axios = require('axios');
const { chromium } = require('playwright');
const PROFILE_ID = 'your_profile_id_here';
const API_KEY = 'your_api_key_here';
axios.get(`http://127.0.0.1:50325/api/v1/browser/start?user_id=${PROFILE_ID}`, {
headers: { Authorization: `Bearer ${API_KEY}` }
}).then(async (res) => {
const cdpEndpoint = res.data.data.ws.puppeteer;
const browser = await chromium.connectOverCDP(cdpEndpoint);
const defaultContext = browser.contexts()[0];
const page = await defaultContext.newPage();
await page.goto('https://www.browserscan.net');
console.log(await page.title());
await browser.close();
}).catch((err) => {
console.error(err.message);
});
Important: Use the Existing Context
When you connect over CDP, Playwright creates a wrapper around the browser AdsPower already launched. Do not call browser.newContext() — that would create a fresh context without AdsPower's fingerprint configuration. Always use browser.contexts[0], which represents the profile's real browsing context with its proxy, cookies, and fingerprint intact.
Step 3: Close the Profile Cleanly
After your automation finishes, close the browser and stop the profile through the API. This frees resources and ensures AdsPower saves the session state correctly:
browser.close()
httpx.get(
f"{LOCAL_API_BASE}/api/v1/browser/stop?user_id={PROFILE_ID}",
headers=headers,
)
In Node.js:
await browser.close();
await axios.get(`http://127.0.0.1:50325/api/v1/browser/stop?user_id=${PROFILE_ID}`, {
headers: { Authorization: `Bearer ${API_KEY}` }
});
Complete Python Example
Here is a full script that starts a profile, navigates to a fingerprint-checking site, prints the page title, and shuts everything down:
import httpx
from playwright.sync_api import sync_playwright
LOCAL_API_BASE = "http://127.0.0.1:50325"
PROFILE_ID = "your_profile_id_here"
API_KEY = "your_api_key_here"
headers = {"Authorization": f"Bearer {API_KEY}"}
# 1. Start the AdsPower profile
resp = httpx.post(
f"{LOCAL_API_BASE}/api/v2/browser-profile/start",
headers=headers,
json={"profile_id": PROFILE_ID, "last_opened_tabs": "0", "proxy_detection": "0"},
)
if resp.status_code != 200:
raise RuntimeError(f"Start failed: {resp.text}")
cdp_endpoint = resp.json()["data"]["ws"]["puppeteer"]
# 2. Connect Playwright
with sync_playwright() as playwright:
browser = playwright.chromium.connect_over_cdp(cdp_endpoint)
context = browser.contexts[0]
page = context.pages[0] if context.pages else context.new_page()
page.goto("https://www.browserscan.net")
print(f"Page title: {page.title()}")
page.wait_for_timeout(8000)
browser.close()
# 3. Stop the profile
httpx.get(f"{LOCAL_API_BASE}/api/v1/browser/stop?user_id={PROFILE_ID}", headers=headers)
Scaling Across Multiple Profiles
One of the biggest advantages of this setup is looping over many profiles. Keep a list of profile IDs and run the same workflow against each one sequentially or in parallel:
profile_ids = ["profile_a", "profile_b", "profile_c"]
for pid in profile_ids:
resp = httpx.post(
f"{LOCAL_API_BASE}/api/v2/browser-profile/start",
headers=headers,
json={"profile_id": pid, "last_opened_tabs": "0", "proxy_detection": "0"},
)
cdp_endpoint = resp.json()["data"]["ws"]["puppeteer"]
with sync_playwright() as playwright:
browser = playwright.chromium.connect_over_cdp(cdp_endpoint)
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
# Your per-profile logic here
browser.close()
httpx.get(f"{LOCAL_API_BASE}/api/v1/browser/stop?user_id={pid}", headers=headers)
For high-volume scraping, pair this loop with AdsPower's batch profile creation and proxy rotation. If you are building a larger data pipeline, the scraping automation guide covers browser-based vs. API-based approaches and how to avoid blocks at scale.
Practical Use Cases
Multi-Account Social Media Management
Run the same posting or engagement script against separate AdsPower profiles, each with its own proxy and fingerprint. Playwright handles the interaction logic; AdsPower keeps the identities isolated.
E-Commerce Price Monitoring
Launch profiles configured for different regions, navigate to retailer sites, and extract pricing data. Fingerprint diversity plus residential proxies reduces the chance of IP-based blocks.
Ad Verification and Landing Page Testing
Open campaigns from the perspective of different user profiles and geolocations. Playwright's screenshot and assertion features let you verify that ads render correctly for each audience segment.
CAPTCHA-Heavy Workflows
When a target site presents a CAPTCHA, you can integrate a solver into the same Playwright script. For a complete walkthrough, see How to Use AdsPower with CapSolver.
Troubleshooting Common Issues
Connection Refused on Port 50325
Make sure AdsPower is running and the Local API is enabled in Settings. On some systems, a firewall may block localhost traffic — allow port 50325 for local connections.
connect_over_cdp Times Out
Confirm the CDP endpoint is reachable. Print the endpoint and test it in a browser or with curl. If AdsPower launched the profile but the WebSocket is not responding, restart the profile and try again.
Blank Page or No Context
If browser.contexts[0] has no pages, create one with context.new_page(). Avoid calling browser.newContext() because it bypasses AdsPower's fingerprint setup.
API Returns an Error Code
Check that the profile ID is correct and that the profile is not already running. The v1 start endpoint returns code: 0 on success; any other value indicates a problem, often an invalid ID or an already-active profile.
Playwright Version Mismatch
Use a recent Playwright release. The connect_over_cdp method has been stable across modern versions, but older releases may lack full CDP support for Chromium's newer protocol features.
AdsPower + Playwright vs. Selenium and Puppeteer

Playwright product interface.
AdsPower's Local API returns connection details for all three major automation tools. Why choose Playwright?
| Feature | Playwright | Selenium | Puppeteer |
|---|---|---|---|
| Auto-waiting | Built-in | Manual waits | Partial |
| Web-first assertions | Yes | No | No |
| Resilient locators | Yes | Limited | Limited |
| CDP connection | connect_over_cdp |
debuggerAddress |
puppeteer.connect |
| Parallel test isolation | Native contexts | Manual | Partial |
| Multi-language support | Python, Node.js, Java, .NET | Many | Node.js only |
Playwright's auto-waiting removes most flaky-test headaches, and its assertion library makes verification cleaner. For long-running scraping jobs where you need maximum control over the browser session, Puppeteer is a solid alternative; for teams already standardized on Selenium, AdsPower supports that too. But for new automation projects, Playwright offers the best balance of reliability and developer experience.
Security Considerations
- Keep API verification enabled in production. Disabling it means any local process can control your profiles.
- Store API keys in environment variables, not in source code.
- Use dedicated proxies for each profile. AdsPower supports HTTP, SOCKS5, and SSH proxies — configure them at the profile level so Playwright inherits them automatically.
- Validate profile trust. Only start profiles you created yourself, especially when running third-party scripts.
If you want to verify that your proxy and fingerprint are working correctly before running automation at scale, the AdsPower + Whoer.net setup guide shows how to check for IP and fingerprint leaks.
Related reading
- Incogniton Tutorial: Set Up Profiles, Proxies & Automation - Learn Incogniton step by step: create your first browser profile, add proxies, manage fingerprints, and use the API for automation workflows.
Sources and further reading
- Code Samples - Code samples to automate AdsPower with Python, Javascript and Java.Chrome code samplesPython Selenium The demo passed the test in selenium version 3.141.0 import requests,time from selenium import webdriver fro
- r/Playwright on Reddit: Has anybody controlled AdsPower browser ... - Oct 7, 2024 ... Has anybody controlled AdsPower browser using Python's Playwright? ... Hello. I looked at AdsPower's official documentation and there's no mention ...
- AdsPower LocalAPI MCP Server: Smarter Browser Automation with AI - Discover how the AdsPower LocalAPI MCP Server connects AI tools like Claude to automate browser profile creation, management, and control — start testing today.
Frequently Asked Questions
Does AdsPower officially support Playwright?
Yes. AdsPower's official Local API documentation includes Python and JavaScript Playwright examples that use connect_over_cdp with the ws.puppeteer endpoint returned by the start API.
Can I use Playwright's async API with AdsPower?
Yes. Replace sync_playwright() with async_playwright() and use await playwright.chromium.connect_over_cdp(cdp_endpoint). The connection logic is identical; only the syntax differs.
Do I need to install a separate Chromium for Playwright?
No. When you connect over CDP, Playwright controls the Chromium instance AdsPower already launched. You do not need Playwright's bundled browser binaries for this workflow.
Can I run multiple AdsPower profiles in parallel with Playwright?
Yes. Start multiple profiles through the Local API, collect their CDP endpoints, and connect to each one. For Python, use asyncio with async_playwright(); for Node.js, use Promise.all.
Does Playwright work with AdsPower's Firefox-based profiles?
AdsPower's Firefox support requires a specific patch version and Firefox 123 or newer. The CDP connection pattern is designed for Chromium profiles, so stick with Chromium-based profiles for Playwright automation.
What is the difference between the v1 and v2 start endpoints?
The v2 endpoint (/api/v2/browser-profile/start) accepts a JSON body with extra options like last_opened_tabs and proxy_detection. The v1 endpoint uses query parameters. Both return the same connection data structure.
Conclusion
Connecting AdsPower to Playwright is a straightforward three-step pattern: start a profile through the Local API, attach Playwright via connect_over_cdp, and stop the profile when done. That simple loop unlocks a powerful combination — Playwright's reliable automation primitives running inside AdsPower's isolated, fingerprint-protected browser environments. Whether you are managing dozens of social accounts, scraping competitor pricing, or verifying ads across regions, this integration gives you the control and safety to scale without triggering anti-bot systems.
Start with one profile, verify your script against a fingerprint-checking site like BrowserScan, then expand to multi-profile loops with proxies. Once the pattern is in place, you can apply it to nearly any web automation workflow that requires realistic, isolated browser identities.
