Smart Browser Identity
We automatically sync fingerprints, viewport, locale, timezone, and proxies so every session looks like a real, legitimate user.
Spin up reliable browser sessions for research, testing, and automation. Connect via Playwright, REST, or MCP. Route through global proxies, control your fingerprint, and avoid retained session-content logs by default.
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://google.com');
} finally {
const { summary } = await fetch(`https://api.browser.city/v1/sessions/${id}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${process.env.BROWSERCITY_API_KEY}` },
}).then((r) => r.json());
console.log('Runtime seconds:', summary?.stats?.runtimeSeconds ?? 0);
console.log('Cookies stored:', summary?.storage?.cookies?.length ?? 0);
}import os, requests
from playwright.sync_api import sync_playwright
auth = {'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 = None
try:
playwright = sync_playwright().start()
browser = playwright.chromium.connect(
endpoint,
headers={'Authorization': f'Bearer {token}'},
)
page = browser.contexts[0].pages[0]
page.goto('https://google.com')
finally:
try:
deleted = requests.delete(f'https://api.browser.city/v1/sessions/{session_id}', headers=auth).json()
summary = deleted.get('summary') or {}
print('Runtime seconds:', (summary.get('stats') or {}).get('runtimeSeconds', 0))
cookies = (summary.get('storage') or {}).get('cookies') or []
print('Cookies stored:', len(cookies))
finally:
if playwright:
playwright.stop()using Microsoft.Playwright;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Collections.Generic;
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://google.com");
} finally {
try {
if (session is not null) {
var deleted = await (await http.DeleteAsync($"https://api.browser.city/v1/sessions/{id}"))
.Content.ReadFromJsonAsync<DeleteSessionResponse>();
Console.WriteLine($"Runtime seconds: {deleted?.Summary?.Stats?.RuntimeSeconds ?? 0}");
Console.WriteLine($"Cookies stored: {deleted?.Summary?.Storage?.Cookies?.Count ?? 0}");
}
} finally {
pw?.Dispose();
}
}
record Session(string Id, string Endpoint, string Token);
record DeleteSessionResponse(DeleteSessionSummary? Summary);
record DeleteSessionSummary(DeleteSessionStats? Stats, DeleteSessionStorage? Storage);
record DeleteSessionStats(double? RuntimeSeconds);
record DeleteSessionStorage(List<object>? Cookies);import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.playwright.*;
import java.net.URI;
import java.net.http.*;
import java.util.Map;
import java.util.List;
public class Quickstart {
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://google.com");
} finally {
try {
var deleteResponse = http.send(HttpRequest.newBuilder(URI.create("https://api.browser.city/v1/sessions/" + id))
.header("Authorization", "Bearer %s".formatted(key)).DELETE().build(), HttpResponse.BodyHandlers.ofString());
if (deleteResponse.statusCode() / 100 != 2) {
throw new RuntimeException("Delete failed: " + deleteResponse.statusCode());
}
var deleteBody = deleteResponse.body();
if (deleteBody.strip().startsWith("{")) {
var deleted = json.readValue(deleteBody, Map.class);
Object runtimeSeconds = 0;
int cookieCount = 0;
if (deleted.get("summary") instanceof Map<?, ?> summary) {
if (summary.get("stats") instanceof Map<?, ?> stats && stats.get("runtimeSeconds") != null) {
runtimeSeconds = stats.get("runtimeSeconds");
}
if (summary.get("storage") instanceof Map<?, ?> storage && storage.get("cookies") instanceof List<?> cookies) {
cookieCount = cookies.size();
}
}
System.out.println("Runtime seconds: " + runtimeSeconds);
System.out.println("Cookies stored: " + cookieCount);
}
} finally {
if (pw != null) pw.close();
}
}
}
record Session(String id, String endpoint, String token) {}
} We handle the infrastructure so you can focus on your agents. Enjoy real browsers, smart identity controls, clear pricing, and privacy-focused defaults.
We automatically sync fingerprints, viewport, locale, timezone, and proxies so every session looks like a real, legitimate user.
Skip the boot sequence. We keep a pool of warm browsers ready to go, so your agents can start interacting with the web immediately.
Pick your browser size and proxy type, and pay only for what you use. We accept credit cards and crypto (Bitcoin, ETH, USDC).
We don't retain session-content logs, a browsing-history log of session URLs, or stored page content by default. Operational logs, billing records, routing metadata, and provider metadata stay within the boundaries described in our policies.
Connect via Playwright, REST API, or MCP. Works with every agent framework.
Full browser infrastructure — from coherent identity controls to proxy routing to content extraction.
Supply your own custom Apify-compatible fingerprints, or let us automatically generate a perfectly aligned identity for you.
Our proprietary stealth technology bypasses the most advanced bot detectors—including DataDome—keeping your agents unblocked.
Warm sessions start in roughly 100ms for general requests, and roughly 150ms when you supply a detailed fingerprint.
First-class mobile support. Render pixel-perfect Android and tablet sessions complete with matching viewports and touch events.
Whether you use our native Model Context Protocol (MCP) server or simple REST API, every automated action behaves exactly like a real human.
Keep your existing Playwright scripts. Just change your connection endpoint to browser.city and run your code unchanged.
Route traffic through managed datacenter, residential, or mobile proxies. Or bring your own proxies on paid plans.
Top up your account balance instantly with Bitcoin, Ethereum, or USDC. No credit card or bank account required.
Clear, dimensional pricing for compute and proxy traffic. Start for free with our managed datacenter proxies, or upgrade to unlock residential, mobile, and bring-your-own-proxy (BYOP) networks.
Constrained catalog tier for testing and small workloads.
Monthly commitment tier with credits and higher limits.
Monthly commitment tier with credits and higher limits.
Monthly commitment tier with credits and higher limits.
Monthly commitment tier with credits and higher limits.
Monthly commitment tier with credits and higher limits.
Custom concurrency, Enterprise SSO, SLA, dedicated infrastructure, network access, and volume commitments.
100% of your paid monthly tier converts into usage credits. Need more? Just top up. Paid plans unlock global residential and mobile proxies, plus a $1/GB fee for BYOP traffic.
Browser size metered by session time.
| Size | Resources | Price |
|---|---|---|
| Compute M | 2 vCPU / 2 GB | $0.06/hr |
| Compute L | 4 vCPU / 4 GB | $0.12/hr |
Managed and BYOP traffic by customer-facing network class.
| Network | Price |
|---|---|
| Datacenter | $1/GB |
| Residential | $6/GB |
| Mobile | $8/GB |
| Premium Residential | $12/GB |
| BYOP fee | $1/GB |
A safer baseline for your agents: clear controls, strict privacy defaults, and public pricing you can review before you write a single line of code.
Start for free. No credit card required. Private sessions by default.