Browser infrastructure is weirdly broken for something that should feel like compute.
In 2025–2026 the market exploded: BaaS providers, scraping APIs, AI browser agents, anti-detect tools, proxy hybrids. But most teams run into the same three problems within the first week:
- Billing you can’t reason about. Credits, units, multipliers, stealth upgrades, proxy add-ons. You only learn the real cost after your first retry storm.
- Stealth that’s not a default. “Stealth” exists, but it’s often gated, inconsistent, or requires a matrix of options and plan tiers.
- Privacy that’s mostly policy. If your sessions touch sensitive surfaces, “we don’t log” is not enough. Architecture is the guarantee.
What we optimized for
We built browser.city around a few constraints:
- Stealth by default. If you have to remember to turn it on, it will be off in production.
- Zero-logs by design. No session recording pipeline. No content-at-rest capture. Minimal metadata required to operate the service.
- APIs that don’t make you pick a product. You can start with the Request API, graduate to Playwright sessions, and then add MCP tools for agents without switching stacks.
Four entry points, one mental model
1) Request API (fast extraction)
const apiKey = process.env.BROWSERCITY_API_KEY!;const opts = { method: "POST", headers: { Authorization: `Bearer ${apiKey}` } };const res = await fetch("https://api.browser.city/v1/requests", { ...opts, body: JSON.stringify({ url: "https://example.com", markdown: true, }),}).then((r) => r.json());console.log(res.content);import osimport requestsapi_key = os.environ["BROWSERCITY_API_KEY"]res = requests.post( "https://api.browser.city/v1/requests", headers={"Authorization": f"Bearer {api_key}"}, json={"url": "https://example.com", "markdown": True},).json()print(res["content"])using System.Net.Http.Headers;using System.Net.Http.Json;var apiKey = Environment.GetEnvironmentVariable("BROWSERCITY_API_KEY")!;var http = new HttpClient();http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);var res = await http.PostAsJsonAsync( "https://api.browser.city/v1/requests", new { url = "https://example.com", markdown = true });var json = await res.Content.ReadFromJsonAsync<RequestResponse>() ?? throw new Exception("bad response");Console.WriteLine(json.content);public record RequestResponse(string content);import java.net.URI;import java.net.http.*;var apiKey = System.getenv("BROWSERCITY_API_KEY");var http = HttpClient.newHttpClient();var req = HttpRequest.newBuilder() .uri(URI.create("https://api.browser.city/v1/requests")) .header("Authorization", "Bearer " + apiKey) .POST(HttpRequest.BodyPublishers.ofString( "{\"url\":\"https://example.com\",\"markdown\":true}")) .build();var res = http.send(req, HttpResponse.BodyHandlers.ofString());System.out.println(res.body());
2) Sessions API (full browser automation)
Create a session and connect with Playwright using the returned token header.
3) Humanized REST tools (/v1/do/*)
For step-by-step actions over a remote session (open, navigate, click, type, markdown) without running Playwright.
4) MCP server (agent-native browser tools)
Add browser.city to Codex, Claude Code, Cursor, or any MCP client and let your agent use browser tools as needed.
What’s next
This blog will focus on practical content:
- competitor comparisons that are honest and technical
- integration guides for the tools people actually use
- stealth research, benchmarks, and “how we built it” deep dives