Puppeteer Proxy Setup
Add rotating proxies to Puppeteer headless Chrome scraping.
Puppeteer controls headless Chrome for scraping JavaScript-heavy pages. Set the proxy at browser launch - all pages this browser instance opens will route through SotaProxy.
Setup guide
Install Puppeteer
npm install puppeteerPuppeteer installs a bundled version of Chromium automatically.
Launch with proxy
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=http://proxy.sotaproxy.com:10000'],
});
const page = await browser.newPage();
// Authenticate the proxy
await page.authenticate({
username: 'YOUR_USERNAME',
password: 'YOUR_PASSWORD',
});
await page.goto('https://httpbin.org/ip');
const content = await page.content();
console.log(content);
await browser.close();
})();Set --proxy-server in launch args and call page.authenticate() with your credentials. Puppeteer requires credentials to be set per-page, not per-browser.
Geo-targeting
const browser = await puppeteer.launch({
args: ['--proxy-server=http://proxy.sotaproxy.com:10000'],
});
const page = await browser.newPage();
await page.authenticate({
username: 'YOUR_USERNAME_c_FR', // French IP
password: 'YOUR_PASSWORD',
});Append _c_XX to the username in page.authenticate() to target a specific country.
Automate it with the SotaProxy API
Everything above works without opening the dashboard. With an API key, Puppeteer can pull fresh proxy credentials, buy new proxies, and renew expiring ones - straight from code.
const API = 'https://api.sotaproxy.com/api/v1'
const H = { Authorization: 'Bearer sk_live_your_key' }
// Every active proxy on your account - no copy-pasting credentials
const { proxies } = await (await fetch(`${API}/proxies`, { headers: H })).json()
const p = proxies[0]
const proxyUrl = `http://${p.login}:${p.password}@${p.ip}:${p.portHttp}`
// Buy more when you scale (price-check first with POST /quote)
await fetch(`${API}/orders`, {
method: 'POST',
headers: { ...H, 'Content-Type': 'application/json', 'Idempotency-Key': 'my-unique-order-id' },
body: JSON.stringify({ product: 'ipv4', countryId: 565, periodId: '1m', quantity: 5 }),
})Why Puppeteer needs two steps
Chromium takes the proxy from a launch flag, and that flag has no place for credentials. Authentication happens afterwards, per page:
The proxy is set for the whole browser process, so one browser equals one address. Run several browsers when you need several identities in parallel.
One browser per address
Launch with the endpoint, then call page.authenticate before the first navigation:
Node: browser per identity
const puppeteer = require('puppeteer');
async function browserFor(sessionId) {
const browser = await puppeteer.launch({
args: ['--proxy-server=http://proxy.sotaproxy.com:10000'],
});
const page = await browser.newPage();
await page.authenticate({
username: `login_c_US_s_${sessionId}_ttl_1h`,
password: 'password',
});
return { browser, page };
}
const { page } = await browserFor(7);
await page.goto('https://example.com', { timeout: 30000 });- Call authenticate on every new page, not once per browser. A page opened later starts unauthenticated and the first request comes back 407.
- Use a separate user data directory per browser. Otherwise profiles share cookies and the address separation buys you nothing.
- Close browsers you are done with. Each one holds an open connection to our endpoint, and a leak here looks like a rate limit later.
- For many parallel identities, Playwright contexts are cheaper than Puppeteer browsers. Consider it when the count passes about ten.
Puppeteer specifics
Credentials in the launch flag do nothing
--proxy-server accepts a host and port only. Anything before the @ is dropped silently and you get 407.
One proxy per browser process
There is no per-context proxy. Rotating means launching another browser, which is why heavy rotation belongs in Playwright.
authenticate applies per page
New tabs and popups need their own call, and OAuth flows that open a popup break without it.
Headless detection is a separate problem
The proxy fixes the address, not the fingerprint. Pair it with stealth measures or an antidetect browser for account work.
Notes & tips
- •Puppeteer requires page.authenticate() for each new page. Playwright handles authentication at the browser level (simpler for multi-page sessions).
- •Consider puppeteer-extra and puppeteer-extra-plugin-stealth to reduce fingerprinting detection.
- •For high-volume scraping, consider Playwright instead - it handles multi-context proxy configuration more cleanly.
FAQ
What is the difference between Puppeteer and Playwright for proxy use?
Playwright supports proxy configuration at the browser context level (cleaner for multi-session setups). Puppeteer requires per-page authentication. Both work with SotaProxy.
Can Puppeteer handle CAPTCHA challenges?
Puppeteer cannot solve CAPTCHAs natively. Residential proxies reduce CAPTCHA frequency. For remaining challenges, integrate a CAPTCHA solving service (2Captcha, Anti-Captcha).
Related integrations
Get your proxy credentials
Sign up, top up your balance, and copy your endpoint into Puppeteer. Takes under 5 minutes.
Get started