Real User Journeys
Run end-to-end flows in a real browser: login, search, checkout, payments, dashboards.
Run "real user journey" checks in bulletproof stealth browsers. Catch outages, regressions, and bot walls before your customers do, and attach screenshot and markdown evidence the moment an alert fires.
Run end-to-end flows in a real browser: login, search, checkout, payments, dashboards.
Synthetic monitors often fail first on bot walls. Stealth defaults help your checks behave like real traffic.
Validate uptime and UX from the countries your customers use. Managed egress or BYOP.
Run checks in parallel across browsers, devices, and geos to reduce time-to-detect.
Create a session, connect with Playwright, run your assertions, and tear down. Works in any runner.
On failure, capture screenshots and page markdown for fast root cause. Make alerts actionable, not noisy.
Create a session, connect with Playwright, then run your existing checks. On failure, capture screenshots/markdown via REST tools.
import { chromium } from 'playwright';const { endpoint, token, id } = await fetch('https://api.browser.city/v1/sessions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.BROWSERCITY_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ browser: 'chromium' }),}).then((r) => r.json());try { const browser = await chromium.connect(endpoint, { headers: { Authorization: `Bearer ${token}` }, }); const page = browser.contexts().at(0)!.pages().at(0)!; await page.goto('https://example.com'); if (!(await page.title()).toLowerCase().includes('example')) throw new Error('bad title');} finally { await fetch(`https://api.browser.city/v1/sessions/${id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.BROWSERCITY_API_KEY}` }, });}import os, requestsfrom playwright.sync_api import sync_playwrightauth = {'Authorization': f"Bearer {os.environ['BROWSERCITY_API_KEY']}"}session = requests.post( 'https://api.browser.city/v1/sessions', headers=auth, json={'browser': 'chromium'}).json()endpoint = session['endpoint']token = session['token']session_id = session['id']playwright = Nonetry: playwright = sync_playwright().start() browser = playwright.chromium.connect( endpoint, headers={'Authorization': f'Bearer {token}'}, ) page = browser.contexts[0].pages[0] page.goto('https://example.com') if 'example' not in page.title().lower(): raise RuntimeError('bad title')finally: try: requests.delete(f'https://api.browser.city/v1/sessions/{session_id}', headers=auth) finally: if playwright: playwright.stop()using Microsoft.Playwright;using System.Net.Http.Headers;using System.Net.Http.Json;var http = new HttpClient();http.DefaultRequestHeaders.Authorization = new( "Bearer", Environment.GetEnvironmentVariable("BROWSERCITY_API_KEY"));var session = await (await http.PostAsJsonAsync( "https://api.browser.city/v1/sessions", new { browser = "chromium" })) .Content.ReadFromJsonAsync<Session>();var (id, endpoint, token) = session!;IPlaywright? pw = null;try { pw = await Playwright.CreateAsync(); var browser = await pw.Chromium.ConnectAsync(endpoint, new() { Headers = new() { ["Authorization"] = $"Bearer {token}" } }); var page = browser.Contexts[0].Pages[0]; await page.GotoAsync("https://example.com"); if (!(await page.TitleAsync()).ToLower().Contains("example")) throw new Exception("bad title");} finally { try { if (session is not null) await http.DeleteAsync($"https://api.browser.city/v1/sessions/{id}"); } finally { pw?.Dispose(); }}record Session(string Id, string Endpoint, string Token);import com.fasterxml.jackson.databind.ObjectMapper;import com.microsoft.playwright.*;import java.net.URI;import java.net.http.*;import java.util.Map;public class SyntheticMonitor { public static void main(String[] args) throws Exception { var key = System.getenv("BROWSERCITY_API_KEY"); var http = HttpClient.newHttpClient(); var json = new ObjectMapper(); var req = HttpRequest.newBuilder(URI.create("https://api.browser.city/v1/sessions")) .header("Authorization", "Bearer %s".formatted(key)) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString("{\"browser\":\"chromium\"}")) .build(); var created = json.readValue(http.send(req, HttpResponse.BodyHandlers.ofString()).body(), Session.class); var id = created.id(); var endpoint = created.endpoint(); var token = created.token(); Playwright pw = null; try { pw = Playwright.create(); var browser = pw.chromium().connect(endpoint, new BrowserType.ConnectOptions().setHeaders(Map.of("Authorization", "Bearer %s".formatted(token)))); var page = browser.contexts().get(0).pages().get(0); page.navigate("https://example.com"); if (!page.title().toLowerCase().contains("example")) throw new RuntimeException("bad title"); } finally { try { http.send(HttpRequest.newBuilder(URI.create("https://api.browser.city/v1/sessions/" + id)) .header("Authorization", "Bearer %s".formatted(key)).DELETE().build(), HttpResponse.BodyHandlers.discarding()); } finally { if (pw != null) pw.close(); } } } record Session(String id, String endpoint, String token) {}} Start for free. No credit card required. Private sessions by default.