This pattern launches an isolated Multilogin profile via API, attaches Playwright through CDP, runs automation, and always stops the profile in a finally block.
Environment setup
pip install playwright httpx playwright install chromium export MLX_TOKEN="your_api_token" export MLX_PROFILE_ID="your_profile_uuid"
Launch + Playwright attach
import os
import asyncio
import httpx
from playwright.async_api import async_playwright
MLX = "https://api.multilogin.com" # verify current base URL in docs
TOKEN = os.environ["MLX_TOKEN"]
PROFILE = os.environ["MLX_PROFILE_ID"]
async def run():
headers = {"Authorization": f"Bearer {TOKEN}"}
async with httpx.AsyncClient(timeout=60) as client:
r = await client.post(
f"{MLX}/profile/start", # endpoint name varies by API version
headers=headers,
json={"profile_id": PROFILE, "headless": False},
)
r.raise_for_status()
data = r.json()
cdp_url = data["cdp_url"] # field name per API response
pw = await async_playwright().start()
try:
browser = await pw.chromium.connect_over_cdp(cdp_url)
context = browser.contexts[0] if browser.contexts else await browser.new_context()
page = context.pages[0] if context.pages else await context.new_page()
await page.goto("https://example.com", wait_until="domcontentloaded")
print(await page.title())
finally:
await pw.stop()
async with httpx.AsyncClient(timeout=30) as client:
await client.post(f"{MLX}/profile/stop", headers=headers, json={"profile_id": PROFILE})
asyncio.run(run())
Error handling checklist
- Retry 429/5xx with exponential backoff
- Poll profile status if CDP URL not immediate
- Validate proxy before launch — dead proxy = timeout
- Log full response body on 4xx for debugging
Related
Full automation setup guide
Playwright anti-detect patterns
Cloudflare & captcha triage
API error reference
Production recipe
All code recipes
Free scripts on Telegram
Disclosure: MLX-MMO affiliated with Multilogin. Endpoint paths may change — verify against official API docs. Promo: SAAS50 / MIN50.