How to Use AdsPower with Selenium: Setup and Examples
Take a Quick Look
Connect AdsPower to Selenium via the Local API, launch isolated anti-detect profiles, and automate multi-account workflows with Python code examples.
🔥 Limited-Time Offer! Save extra 10% off on your first monthly plan with code: Anitdetect10
Sign upHow to Use AdsPower with Selenium: Setup and Examples
AdsPower gives each browser profile an isolated fingerprint, and Selenium gives you code that drives a browser. Put them together and you can automate dozens of accounts that each look like a separate real device. This guide explains how the two tools connect, walks through the setup step by step, and shows working Python examples you can adapt.
Why combine AdsPower with Selenium

Selenium product interface.
Selenium on its own launches a normal browser. Every session shares the same cookies, canvas fingerprint, WebGL renderer, and user agent, so platforms can link your accounts together. AdsPower solves that by creating isolated browser environments with unique fingerprints (Canvas, WebGL, User Agent, IP, and more) and proxy assignment per profile.
The combination gives you:
- Fingerprint isolation per automation run. Each Selenium session attaches to a different AdsPower profile, so no two runs look like the same device.
- Proxy control. Traffic leaves through the proxy bound to that profile, not your local IP.
- Scale without rewriting scripts. The same Selenium code works across hundreds of profiles by changing one ID.
- State that persists. Cookies and logins stay inside the profile, so you authenticate once and reuse the session.
This is the pattern behind multi-account e-commerce operations, social media marketing at scale, affiliate work, and web scraping where each request should look like a distinct visitor.
How the connection actually works

Selenium product interface.
AdsPower runs a local service on your machine. Selenium does not launch Chrome itself; instead, it asks AdsPower to start a profile and then attaches to the already-running browser through a debug interface.
The flow is:
- Your script calls the AdsPower Local API to start a profile.
- AdsPower launches that profile's browser with its fingerprint and proxy.
- The API returns a WebDriver path and a debugger address (the
seleniumvalue insidews). - Selenium connects to that address using
debuggerAddress. - Your script drives the page normally.
- When finished, you quit the driver and call the stop endpoint.
Two details matter here. First, the WebDriver returned by the API must match the browser core version of that profile, which is why you should use the path AdsPower gives you rather than a driver you downloaded separately. Second, the Local API listens on http://local.adspower.net:50325 (or http://127.0.0.1:50325), so nothing needs to be exposed to the internet.
Prerequisites
Before writing code, confirm you have:
- AdsPower installed and at least one profile created. Note its profile ID (also called
user_id). - The Local API enabled in AdsPower settings.
- Python 3.8 or newer with
pip. - The Selenium package installed.
- An API key if your AdsPower version requires authorization headers.
Install the dependencies:
pip install selenium requests
Step 1: Start a profile with the Local API
The start endpoint is a GET request:
GET http://local.adspower.net:50325/api/v1/browser/start?user_id=<PROFILE_ID>
Useful optional parameters include headless=1 for background runs, open_tabs=1 to skip restoring previous tabs, ip_tab=0 to suppress the IP detection page, and launch_args to pass Chrome flags such as --disable-notifications. A successful response looks like this:
{
"code": 0,
"data": {
"ws": {
"selenium": "127.0.0.1:xxxx",
"puppeteer": "ws://127.0.0.1:xxxx/devtools/browser/xxxxxx"
},
"debug_port": "xxxx",
"webdriver": "C:\\xxxx\\chromedriver.exe"
},
"msg": "success"
}
If code is not 0, the profile did not launch. The msg field usually tells you whether the profile ID is wrong or the Local API is not running.
Step 2: Attach Selenium to the running browser

Selenium product interface.
With Selenium 4.18 and newer, pass the returned WebDriver path to a Service object and set debuggerAddress to the selenium value:
import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import sys
ads_id = "your_profile_id"
api_key = "your_api_key_here"
open_url = f"http://local.adspower.net:50325/api/v1/browser/start?user_id={ads_id}"
close_url = f"http://local.adspower.net:50325/api/v1/browser/stop?user_id={ads_id}"
headers = {"Authorization": f"Bearer {api_key}"}
resp = requests.get(open_url, headers=headers).json()
if resp["code"] != 0:
print(resp["msg"])
sys.exit("Check the profile ID and Local API status")
chrome_driver = resp["data"]["webdriver"]
service = Service(executable_path=chrome_driver)
options = Options()
options.add_experimental_option("debuggerAddress", resp["data"]["ws"]["selenium"])
driver = webdriver.Chrome(service=service, options=options)
print(driver.title)
driver.get("https://www.browserscan.net/")
time.sleep(5)
driver.quit()
requests.get(close_url, headers=headers)
On older Selenium 3.x builds the same idea applies, but you pass the driver path positionally instead of through Service. If you are still on 3.x, upgrading is the simpler fix.
Opening a fingerprint test page first is a good habit. It confirms the profile is presenting the fingerprint and IP you configured before you run any real task.
Step 3: Build a reusable helper
Hardcoding this in every script gets messy. Wrap it in a context manager so profiles open and close cleanly, even when a task fails:
from contextlib import contextmanager
BASE = "http://local.adspower.net:50325"
@contextmanager
def adspower_profile(profile_id, api_key=""):
headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}
start = requests.get(
f"{BASE}/api/v1/browser/start",
params={"user_id": profile_id, "open_tabs": 1, "ip_tab": 0},
headers=headers,
).json()
if start["code"] != 0:
raise RuntimeError(start["msg"])
data = start["data"]
options = Options()
options.add_experimental_option("debuggerAddress", data["ws"]["selenium"])
driver = webdriver.Chrome(
service=Service(executable_path=data["webdriver"]), options=options
)
try:
yield driver
finally:
driver.quit()
requests.get(
f"{BASE}/api/v1/browser/stop",
params={"user_id": profile_id},
headers=headers,
)
Now any task becomes three lines:
with adspower_profile("profile_id_here", api_key) as driver:
driver.get("https://example.com/dashboard")
print(driver.title)
Practical example: checking accounts across profiles
A common task is verifying that a batch of accounts still logs in correctly. Loop over profile IDs, attach Selenium to each, and record the result:
profiles = ["id_001", "id_002", "id_003"]
results = {}
for pid in profiles:
try:
with adspower_profile(pid, api_key) as driver:
driver.get("https://example.com/login")
driver.find_element("id", "email").send_keys("user@example.com")
driver.find_element("id", "password").send_keys("secret")
driver.find_element("css selector", "button[type=submit]").click()
results[pid] = "ok" if "dashboard" in driver.current_url else "check"
except Exception as exc:
results[pid] = f"error: {exc}"
print(results)
Because each profile keeps its own cookies, a profile that logged in yesterday is still logged in today, and you can skip the login step entirely.
If your work is scraping rather than account management, the same helper applies, but pair it with a scraping API or rotating proxy setup. For a related pattern, see How to Use AdsPower with Scrapestack: Setup & Workflow.
Practical example: running profiles in parallel
Sequential runs are slow when you have many profiles. Since each profile is an independent browser, you can run several at once with threads:
from concurrent.futures import ThreadPoolExecutor
def scrape(pid):
with adspower_profile(pid, api_key) as driver:
driver.get("https://example.com/data")
return pid, driver.title
with ThreadPoolExecutor(max_workers=4) as pool:
for pid, title in pool.map(scrape, profiles):
print(pid, title)
Keep the worker count modest. Each running profile consumes real memory, and heavy parallelism on one machine will slow everything down or trigger timeouts. Four to eight concurrent profiles is a reasonable starting range on a typical workstation.
Common problems and fixes
The profile starts but Selenium cannot connect. The debuggerAddress value must be the selenium field, not the puppeteer WebSocket URL. They are different interfaces.
Session not created or driver version mismatch. Use the webdriver path returned by the API. It is matched to that profile's browser core. A manually downloaded driver often is not.
The API returns a non-zero code. Check that the profile ID is exact, that the profile is not already open, and that the Local API is enabled in AdsPower settings.
The browser opens but the page shows the wrong location. The proxy is attached to the profile, not to your Selenium code. Fix it in the profile's proxy settings and confirm with a fingerprint or IP check page.
Scripts hang on quit. Always call driver.quit() and then the stop endpoint. Leaving profiles open blocks the next run for that same profile.
Headless mode behaves differently. Some sites detect headless browsers. If a task fails only in headless mode, test it with a visible window first to isolate the cause.
AdsPower versus plain Selenium: when each fits

Selenium product interface.
| Scenario | Plain Selenium | AdsPower + Selenium |
|---|---|---|
| Testing your own web app | Good fit | Unnecessary overhead |
| One account, one machine | Good fit | Optional |
| Many accounts on one device | Fingerprints collide | Isolated profiles per account |
| Proxy per account | Manual configuration | Bound to the profile |
| Persistent logins across runs | Fragile | Stored inside the profile |
| Team access to the same profiles | Not supported | Shared workspace |
If your automation only ever touches one account, plain Selenium is simpler. The moment account association becomes a risk, the anti-detect layer earns its place. If you are comparing anti-detect options before committing, this AdsPower vs Incogniton vs BitBrowser comparison covers fingerprint handling, automation support, and pricing.
Scaling beyond one machine
When a single workstation is not enough, Selenium Grid distributes sessions across multiple machines. The same idea works here: each Grid node runs its own AdsPower instance with its own set of profiles, and your script routes work to the right node. Keep profile-to-node mapping explicit so a profile is never opened twice at the same time.
The AdsPower Local API documentation covers the full parameter list for the start endpoint, including headless mode, launch arguments, and cache clearing. The official code samples page includes Python, JavaScript, and Java versions for both Chrome and Firefox, and the open browser endpoint reference documents every query parameter and return field.
Related reading
- Instagram Privacy Settings: Complete 2026 Guide - Master Instagram privacy settings in 2026: lock down your account, control data sharing, stop ad tracking, and secure multi-account setups with anti-detect browsers.
- AdsPower vs Linken Sphere vs Indigo: Antidetect Browser Comparison - We compare AdsPower, Linken Sphere, and Indigo: fingerprints, automation, teams, pricing, and use cases. Find out which antidetect browser to choose in 2026.
Sources and further reading
- Proxy-Seller × AdsPower: Web Scraping Tutorial - In this tutorial, we pair AdsPower (an anti-detect browser) with Proxy-Seller (a clean, dedicated IP per profile), connect them to the AdsPower Local API and...
FAQ
Does AdsPower work with Selenium 4?
Yes. Selenium 4.18 and newer work with the Service object shown above. Selenium 3.141 also works with a slightly different driver setup.
Do I need an API key? Some AdsPower versions require a Bearer token in the request headers. If your Local API accepts unauthenticated requests, you can omit the header.
Can I run AdsPower profiles headless with Selenium?
Yes, pass headless=1 to the start endpoint. Test carefully, because some sites treat headless browsers differently.
How many profiles can run at once? It depends on your machine's memory and CPU. Each profile is a full browser instance. Start with four concurrent profiles and increase gradually.
Does Selenium see the profile's proxy? Yes. The proxy is configured on the profile, so all traffic from that browser session exits through it without any Selenium-side proxy settings.
Can I use Firefox instead of Chrome? AdsPower supports Firefox profiles with Selenium, but it requires a recent AdsPower patch and Firefox 123 or newer. Chrome is the more common and better-documented path.
What about Puppeteer or Playwright?
The same start endpoint returns a puppeteer WebSocket URL that Playwright and Puppeteer can connect to over CDP. If your stack is JavaScript-based, that route works equally well.
Conclusion
AdsPower and Selenium split the work cleanly: AdsPower handles identity, fingerprints, and proxies, while Selenium handles the actions your script performs. The integration comes down to one pattern, start the profile through the Local API, read the returned WebDriver path and debugger address, and attach Selenium to the running browser.
Once that helper function exists, scaling is just a loop or a thread pool. Add profile-level isolation, keep your worker count sane, and always close profiles when a task finishes. If you also manage storefronts or social accounts manually alongside your automation, a guide like How to Use AdsPower with Shopify: Multi-Store Setup Guide shows how the same profile structure supports day-to-day operations.
