How to Reuse Browser Sessions Instead of Logging In Every Time
One of the most repetitive parts of browser automation is authentication.
A typical script starts like this:
open browser
open login page
enter credentials
handle redirects
close popups
restore settings
start the actual task
If the script runs once, that's fine.
If it runs every hour, every day, or for multiple accounts, you're spending a lot of time rebuilding the same session over and over again.
A simpler approach is to reuse a browser profile and preload it with cookies.
With 2Captcha Browser API, you can keep a profile for repeated use and import existing cookies before connecting to it with Playwright or Puppeteer.
The result is a much cleaner flow:
import cookies
connect to profile
open the site
continue from the existing session
Browser profiles are the useful part here
A browser session and a browser profile are not the same thing.
The session is the browser instance you're currently connected to.
The profile is what you reuse between sessions.
So instead of launching a completely fresh environment every time, you connect your automation to the same profile again.
According to the current Browser API limits, a profile can be stored for up to 90 days, while an individual browser session can run for up to 30 minutes.
That means you don't need to keep one browser running forever. You can disconnect and reconnect later using the same profile.
Importing cookies into a profile
2Captcha provides a separate endpoint for importing cookies:
POST https://cb-api.2captcha.com/cookies/import-cookies
The easiest option is to pass the same connectionUri you use to connect to Browser API.
For example:
{
"connectionUri": "YOUR_CDP_CONNECTION_URI",
"cookies": [
{
"name": "session",
"value": "YOUR_SESSION_COOKIE",
"domain": ".example.com",
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "Lax"
}
]
}
There is one important detail.
The cookies are not pushed into a browser that is already running. They are staged for the profile and applied the next time you connect to that profile.
So the correct order is:
1. Import cookies
2. Connect to Browser API
3. Open the target website
Using it with Playwright
Install Playwright:
npm install playwright
Set the Browser API connection URL and your session cookie:
export TWOCAPTCHA_BROWSER_CDP_URL='YOUR_CDP_CONNECTION_URI'
export SESSION_COOKIE_VALUE='YOUR_SESSION_COOKIE'
Then create a small script:
import { chromium } from "playwright";
const connectionUri = process.env.TWOCAPTCHA_BROWSER_CDP_URL;
const sessionCookie = process.env.SESSION_COOKIE_VALUE;
if (!connectionUri) {
throw new Error("TWOCAPTCHA_BROWSER_CDP_URL is required");
}
if (!sessionCookie) {
throw new Error("SESSION_COOKIE_VALUE is required");
}
async function importCookies() {
const response = await fetch(
"https://cb-api.2captcha.com/cookies/import-cookies",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
connectionUri,
cookies: [
{
name: "session",
value: sessionCookie,
domain: ".example.com",
path: "/",
secure: true,
httpOnly: true,
sameSite: "Lax",
},
],
}),
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(
`${data.error || "Cookie import failed"}${
data.detail ? `: ${data.detail}` : ""
}`
);
}
console.log(`Imported cookies: ${data.cookiesStaged}`);
}
async function run() {
await importCookies();
const browser = await chromium.connectOverCDP(connectionUri);
try {
const context = browser.contexts()[0];
const page =
context.pages()[0] || (await context.newPage());
await page.goto("https://example.com", {
waitUntil: "domcontentloaded",
});
console.log("Page title:", await page.title());
} finally {
await browser.close();
}
}
run().catch((error) => {
console.error(error);
process.exit(1);
});
Replace example.com and the cookie values with the site you're actually automating.
You usually need more than one cookie
Real login sessions rarely depend on a single cookie.
You may have several:
const cookies = [
{
name: "session",
value: "SESSION_VALUE",
domain: ".example.com",
path: "/",
secure: true,
httpOnly: true,
sameSite: "Lax",
},
{
name: "preferences",
value: "lang=en",
domain: ".example.com",
path: "/",
secure: true,
httpOnly: false,
sameSite: "Lax",
},
];
You don't necessarily have to convert everything by hand either.
The Cookie Import API supports several common formats, including JSON exports and Netscape-style cookies.txt.
The full list is available in the Cookie Import API documentation.
Why this is better than logging in every time
The main benefit is reliability.
Login flows tend to be one of the most fragile parts of browser automation.
They often include:
- redirects;
- captcha challenges;
- email verification;
- consent dialogs;
- security checks;
- rate limits;
- anti-bot protection.
If you already have a valid session, repeating the entire login flow on every run just adds more places where the automation can fail.
With a reusable profile, the workflow becomes much shorter:
before:
login
verify
redirect
restore settings
navigate
run task
after:
connect
run task
One profile should not be shared by parallel workers
There is one thing to keep in mind when scaling this.
A Browser API profile can only have one active CDP connection at a time.
If another process is already using the profile, you'll get:
profile_locked
The same can happen if you try to import cookies while the profile is busy.
For parallel jobs, use separate profiles:
worker-1 -> profile-1
worker-2 -> profile-2
worker-3 -> profile-3
That keeps sessions isolated and avoids lock conflicts.
Cookies do not reproduce the entire browser state
Cookie import is useful, but it is not the same as cloning a browser.
Some sites also rely on:
- local storage;
- IndexedDB;
- server-side session state;
- device checks;
- IP consistency;
- expiring tokens;
- additional security rules.
So importing cookies does not guarantee that every website will immediately treat the session as authenticated.
But for websites where the session is primarily cookie-based, it can remove a lot of unnecessary login logic.
A practical way to structure recurring automation
Instead of organizing automation around temporary browser instances, it often makes more sense to organize it around profiles.
For example:
account_1 -> profile_A
account_2 -> profile_B
scraper_us -> profile_C
scraper_de -> profile_D
When a job starts:
load profile
import fresh cookies if needed
connect through CDP
run automation
disconnect
The next run reconnects to the same profile instead of rebuilding everything from scratch.
For recurring authenticated browser automation, this is usually a much cleaner model.
Browser API documentation:
https://2captcha.com/scraper/browser-api/api
Cookie Import API:
https://2captcha.com/scraper/browser-api/api#cookie_import_api
Top comments (0)