Export and Import Cookies Through the Local API for QA Sessions

8 min read

Every QA team hits the same wall. Someone spends ten minutes logging in, accepting consent banners and clicking through onboarding to reach the screen worth testing. Then the next tester, or the next CI run, has to do it all again.

A cookie export solves that. You log in once in a profile, save the session, and load it into another profile that should start from the same place. This tutorial builds that with the JustBrowser local API and plain Playwright.

It is meant for accounts you or your team are allowed to use: your own test accounts, a staging environment, a client account you have been given access to. Cookie files are credentials, so handle them that way.

What We're Building

A short Python script that:

  1. Starts a JustBrowser profile through the local REST API
  2. Connects Playwright to it over CDP
  3. Exports the profile's cookies to a JSON file
  4. Starts a second profile and imports that file
  5. Stops both profiles cleanly

JustBrowser is a multi-account browser for teams. Each profile is its own browser with its own cookies, storage and proxy, which is why moving a session from one profile to another is an explicit step you control rather than something that happens by accident.

Prerequisites

  • Python 3.9+ with requests and playwright installed
  • JustBrowser at $9.99/month or $99.99/year, with a 7-day free trial that requires a card. The REST API is available on a subscription or during the trial.
  • An API token from the AI page in the app
  • Two profiles: one with the session you want to save, one to receive it
  • The desktop app running on a Windows x64 or macOS (Apple Silicon) machine

The API is local only. It is bound to 127.0.0.1 on port 36542 by default, and the port is configurable in the app. There is no hosted endpoint. The full reference lives at justbrowser.app/docs, including the endpoints for starting a profile and fetching its Selenium connection details. If you have not connected automation to a profile before, the Playwright and Puppeteer integration guide covers the connection basics.

Step 1: Start and Stop Profiles

The start endpoint returns a cdp_url. One detail trips people up: POST /profiles/{id}/start starts the profile headless unless the body says otherwise. Send {"headless": false} when you want a visible window, for example to log in by hand.

import json
import requests
from playwright.sync_api import sync_playwright

API_BASE = "http://127.0.0.1:36542/api/v1"
HEADERS = {"Authorization": "Bearer <token from the app's AI page>"}


def start_profile(profile_id: str, headless: bool = True) -> str:
    """Start a profile and return its CDP URL."""
    response = requests.post(
        f"{API_BASE}/profiles/{profile_id}/start",
        json={"headless": headless},
        headers=HEADERS,
    )
    response.raise_for_status()
    return response.json()["data"]["cdp_url"]


def stop_profile(profile_id: str) -> None:
    """End the session. browser.close() only disconnects."""
    requests.post(f"{API_BASE}/profiles/{profile_id}/stop", headers=HEADERS)

Errors come back in an envelope with an error.code field. Branch on the code, not on the message text.

Step 2: Export the Cookies

Connect to the running profile and read the cookies from its existing context. Use contexts[0] rather than creating a new context, because a new context would sit outside the profile and have none of its cookies.

def export_cookies(profile_id: str, out_path: str) -> int:
    cdp_url = start_profile(profile_id, headless=True)
    try:
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(cdp_url)
            context = browser.contexts[0]
            cookies = context.cookies()
            with open(out_path, "w") as f:
                json.dump(cookies, f, indent=2)
            browser.close()  # disconnects only
        return len(cookies)
    finally:
        stop_profile(profile_id)

If the session you want does not exist yet, start the profile with headless=False, sign in to your test account by hand, then run the export.

Step 3: Import Into Another Profile

The import mirrors the export. Load the file and add the cookies to the target profile's context.

def import_cookies(profile_id: str, in_path: str, check_url: str) -> None:
    with open(in_path) as f:
        cookies = json.load(f)

    cdp_url = start_profile(profile_id, headless=False)
    try:
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(cdp_url)
            context = browser.contexts[0]
            context.add_cookies(cookies)
            page = context.pages[0] if context.pages else context.new_page()
            page.goto(check_url)
            browser.close()
    finally:
        stop_profile(profile_id)


if __name__ == "__main__":
    count = export_cookies("profile-source", "session.json")
    print(f"Exported {count} cookies")
    import_cookies("profile-target", "session.json", "https://staging.example.com/dashboard")

Open the dashboard page you chose and confirm you are signed in. If you land on a login screen, the session expired or the site ties it to something the new profile does not share, such as a different region or a different proxy. Sites can also look below the IP address, at the connection itself; our TLS fingerprinting explainer covers that layer.

Step 4: Keep the Two Profiles Consistent

A cookie from one environment loaded into a profile configured very differently can produce confusing results in QA. A session created from a German proxy and a Berlin timezone, opened from a profile set to a US proxy and a US timezone, may trigger extra verification on your own staging app. Match the proxy region, timezone and locale of the source profile when you want the same behaviour. The ISP proxy setup guide covers the proxy side of that.

Step 5: Sharing Sessions With a Teammate

There are two ways to hand a session to a teammate:

  • Share the profile. Team members can run profiles the owner shares with them, with view-only or launch permission. The session stays in the profile and no credential file travels.
  • Hand over an export. Use the script above when the teammate needs the session in a profile of their own. Delete the file afterwards.

Team seats are free, but a seat can only run shared profiles. It has no REST API access, so a seat holder cannot run this script. Whoever owns the subscription runs the export and shares the result.

The app also has its own cookie import and export, which is the simplest route for a one-off. The API route earns its place when you want the step in a test setup or a CI job. For tracking conversions across separate profiles without cookies, see the JustAnalytics attribution setup. If these profiles also run your own ad campaigns, understanding click fraud patterns matters as much as the session setup.

Common Errors and Fixes

The profile starts but I cannot see a window

The start endpoint is headless by default. Send {"headless": false} in the JSON body.

Cookies are not there after import

Confirm you used contexts[0] and not a new context, and call stop_profile() after disconnecting. browser.close() only disconnects; the profile keeps running until you stop it.

The session redirects to login

Cookies expire. Export again after a fresh login, and match the proxy region and timezone of the source profile.

Selenium instead of Playwright

Use GET /profiles/{id}/selenium for the connection details. Pin ChromeDriver to the major version of the profile's core, otherwise Selenium Manager may fetch a driver for the machine's own Chrome and the attach will fail. Read the current core major in the app rather than hard-coding it in scripts.

Next Steps

  • Keep exported files out of git and rotate the test accounts they belong to.
  • For many profiles at once, bulk creation takes up to 100 profiles per call from a naming pattern. There is no CSV importer.
  • Encrypted profile export is available in the app for backups. Take one before a long break.

FAQ

Treat it like a password. A cookie file for a logged-in session lets whoever holds it act as that account. Only export sessions for accounts you or your team are entitled to use, store the file somewhere access-controlled, and delete it when the test is done. For ongoing access, sharing the profile itself is cleaner than passing files around.

Can I run the export headless?

Yes. The local API starts a profile headless unless you send headless false in the start request. For an export you do not need a window. If you need to log in by hand first, start the profile with headless set to false, sign in, then run the export.

Do I need a subscription for the local API?

The REST API is available on a subscription or during the 7-day trial, and the bearer token comes from the AI page in the app. Team seats have no API access, so a teammate who only runs shared profiles would use the profile directly rather than this script.

What happens to cookies that have expired?

Session cookies and short-lived tokens expire, so a QA session saved last week may land on the login page. Re-export after a fresh login, and treat saved sessions as short-lived test fixtures rather than long-term storage.


Try JustBrowser

A multi-account browser for teams, built on a custom Chromium engine with native C++ integration, not an extension. Real C++ engine patches at the canvas / WebGL / audio / font / screen layer, with 40+ identity parameters. REST API for Playwright, Puppeteer, Selenium. $9.99/month or $99.99/year. 7-day free trial, card required — cancel any time in the seven days and you are not charged. Unlimited profiles.

Get started → · How it differs from Multilogin / GoLogin / AdsPower

Tags
  • browser-automation
  • multi-account-scripting
  • account-maturity
  • buildinpublic
  • saasstudio
  • aiworkforce
  • buildwithclaude

Ready to manage multiple accounts?

Seven days free, then $9.99/month — one plan, everything included.

We'd like to use Google Analytics, a Google service, to understand how our website is used. It sets two cookies in your browser and runs only if you click Accept. You can change your choice at any time with Cookie settings. Cookie Policy

Sign-in cookies and the cookie that remembers this choice are always on; the website needs them to work.

Google Analytics, a Google service, helps us understand how our website is used. It sets two cookies, _ga and _ga_TVZHQ99TZW. It is now onoff in this browser. If your browser sends a Global Privacy Control or Do Not Track signal, it stays off. Cookie Policy