AdsPower
AdsPower is the main browser log uses for accounts that need one. Each account gets one AdsPower profile, which keeps its own fingerprint and cookies, and log opens it, checks it and drives it through Playwright. Read this when you set up AdsPower, link accounts to profiles, or wonder why a profile was given back.
The browser is a driver, so other browsers can be added the same way, and Camoufox stays as the fallback. How every browser is held to the same capabilities: Browsers. How it runs across servers: Deployment.
Why AdsPower
- It was picked after ranking 23 anti-detect browsers on the problems seen in real recorded runs, using each provider's docs, run captures and identity-leak tests. AdsPower won the final against BitBrowser (0.74 to 0.26); Camoufox placed 21st of 23.
- An earlier production setup ran on AdsPower, with one window per account held open for hours. Its AdsPower client was ported into log.
The pieces
| Path | What it is |
|---|---|
src/browser/driver/ | The browser-agnostic session machine (XState v5) and the capability list every browser fills |
src/browser/adsPower/client.ts | The Local API client (v2 endpoints, Authorization: Bearer <ADSPOWER_API_KEY>, "Too many request" retried twice, catalog errors), syncProfiles, and adsPowerDriver |
src/browser/adsPower/helpers/ | profileRequest (the create body) and planSync (release, create, relink, linked or skip, per account) |
src/browser/adsPower/types.ts | Its types, and adsPowerCapabilities, its row of the parity table |
python/browser/adsPowerBrowser.py | The same Local API from Python: set the profile's proxy, start, stop |
python/browser/browserDriver.py | open_ads_power: gate, proxy on, start a visible window, connect_over_cdp, the profile's context, session HAR, self-check; at the end, stop and proxy off |
src/cli/adsPower/ | log adsPower status, log adsPower profiles, log adsPower sync [--apply] [--homes <US,IE>] |
Twenty gets two fields, both additions:
adsPowerProfileId: the profile linked to the account.browserDriver:adsPowerorcamoufox. When it is empty, an account with a linked profile opens on AdsPower, and one without opens on Camoufox.
What a profile holds
Each profile is set up with:
- Name: the account's
accountName, with a remarklog-cli twenty:<id>so a lost link can be found again. - Group:
logCli. - Browser: Windows Chrome (
random_uaWindows 10/11). - Language: pinned from the home country (
HOME_COUNTRIES). - Timezone and geolocation: from the exit IP.
- Fingerprint noise: AdsPower's own per-profile noise on canvas, WebGL
image, audio, client rects and media devices; WebRTC set to
forward.
It holds no proxy, password or 2FA key:
- The proxy is put on the profile only to open it, after the gate, and taken off at close.
- The profile keeps its own cookies. The saved session from Twenty is carried in once, only into a profile with no Facebook login.
Giving a profile back
Your AdsPower plan limits how many profiles you can hold, so a profile is only held by an account that will use it:
- DEACTIVATED accounts:
log facebook account status <a> DEACTIVATEDdeletes the account's profile from AdsPower, clearsadsPowerProfileId, then runs the sync so an account waiting for a profile gets the freed slot. An account set to DEACTIVATED directly in Twenty gives its profile back at the nextlog adsPower sync --apply. - Home countries:
LOG_ADSPOWER_HOMESin.env.local(for exampleUS), or--homeson the sync, names the home countries that hold profiles. An account whose home is elsewhere gives its profile back the same way and gets none. An account on a platform that runs without a proxy (Reddit) needs no home.
The sync releases profiles first, then makes and links new ones. The account's Twenty row, cookies and status stay as they are.
Opening an account on AdsPower
- Link the account's profile (
log adsPower sync --apply). WithsocialAccounts.browserDriverempty oradsPower, the account then opens on AdsPower. An account set toadsPowerwith no profile is refused (adsPowerProfileMissing). log inspect start --account <a>,log flow run,log facebook warmup stages runandlog facebook host startthen open its AdsPower profile throughpython/browser/browserDriver.py. The gate, self-check, session HAR, human mouse and scrolling are the same as on Camoufox.
Next
- #43 moves the older sessions onto AdsPower:
publishSession,connectSessionandprofileSessionstill launch Camoufox. - #44 opens one machine at a time: a
cloud-activecheck before opening, so two machines never open the same profile (Deployment).
Setup
-
The app: AdsPower runs on the same machine as log. The Local API defaults to
http://local.adspower.net:50325. -
.env.local:ADSPOWER_HOSTandADSPOWER_API_KEY. The key is never printed. -
AdsPower's MCP server (
local-api-mcp-typescript), added at local scope so the key stays out of git:claude mcp add adspower-local-api --scope local -e PORT=50325 -e API_KEY=<key> -- npx -y local-api-mcp-typescript -
AdsPower's skill:
npx skills add https://github.com/adspower/adspower-browser --skill adspower-browser. It installs into.agents/with the vendor's kebab-case names, so it is git-ignored. Seeskills/adsPower/SKILL.md.
Choosing a plan
AdsPower's plans are priced by the number of profiles (in October 2026 the Professional plan was $12 a month for 20 profiles, $21 for 50). You need one profile per account that uses a browser, plus a couple for testing.
What the AdsPower code must do, requirement by requirement: docs/specs/adsPower.md.