Quick verdict: Steel.dev and browser.city are closer peers than most comparisons: both are developer-first, Playwright-native, and agent-friendly. The practical decision comes down to billing ergonomics, privacy posture, and whether you want extraction and agent tools in the same surface area as your browser sessions.
What’s the same
Both products are built for modern “agent + browser” workflows:
- Playwright-compatible remote browsers
- emphasis on developer experience
- integrations that assume AI-assisted automation is the default, not the edge case
If you’re already happy with Steel.dev’s reliability and cost model, you may not need to switch.
What’s different (and shows up in week 2)
1) Billing shape
Steel.dev commonly uses a credit model (often denominated in browser-hours). Credit models are not inherently bad, but they tend to add friction when:
- you want to predict cost per job
- you have mixed workloads (fast extraction + long sessions)
- you run large retry storms (anti-bot targets, flaky sites)
browser.city is built around transparent pricing primitives and a Request API that’s intentionally cheaper to use than spinning up full sessions for “fetch + extract” jobs.
2) Privacy posture: policy vs architecture
Most browser infra providers publish policies. Fewer design the system so session content can’t be retained as a default path.
browser.city’s public position is zero-logs by design: no session recording pipeline, no content-at-rest capture, and minimal metadata. If your automation touches sensitive data (internal tools, customer portals, finance), this distinction matters.
3) Product surface: extraction + agents + sessions
browser.city deliberately supports:
- Request API (
/v1/requests,/v1/requests/batch) to return clean markdown - Sessions API (
/v1/sessions) for long-running Playwright automation - MCP server for agent clients (Codex, Claude Code, Cursor, etc.)
Example: batch extract multiple URLs in one shared session:
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/batch", { ...opts, body: JSON.stringify({ requests: [ { url: "https://example.com", markdown: true }, { url: "https://example.org", markdown: true }, ], }),}).then((r) => r.json());console.log(res.successCount, res.errorCount);import osimport requestsapi_key = os.environ["BROWSERCITY_API_KEY"]res = requests.post( "https://api.browser.city/v1/requests/batch", headers={"Authorization": f"Bearer {api_key}"}, json={ "requests": [ {"url": "https://example.com", "markdown": True}, {"url": "https://example.org", "markdown": True}, ] },).json()print(res["successCount"], res["errorCount"])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/batch", new { requests = new[] { new { url = "https://example.com", markdown = true }, new { url = "https://example.org", markdown = true }, } });Console.WriteLine(await res.Content.ReadAsStringAsync());import java.net.URI;import java.net.http.*;var apiKey = System.getenv("BROWSERCITY_API_KEY");var http = HttpClient.newHttpClient();var body = "{\"requests\":[{\"url\":\"https://example.com\",\"markdown\":true},{\"url\":\"https://example.org\",\"markdown\":true}]}";var req = HttpRequest.newBuilder() .uri(URI.create("https://api.browser.city/v1/requests/batch")) .header("Authorization", "Bearer " + apiKey) .POST(HttpRequest.BodyPublishers.ofString(body)) .build();var res = http.send(req, HttpResponse.BodyHandlers.ofString());System.out.println(res.body());
At a glance
| Dimension | browser.city | Steel.dev |
|---|---|---|
| Pricing ergonomics | “Head math” + Request API for extraction | Credits model (typically browser-hours) |
| Privacy stance | Zero-logs architecture | Verify current data retention posture |
| Entry points | Request API, Sessions API, Humanized REST, MCP tools | Playwright sessions + platform integrations |
| Best for | Mixed workloads: scrape + automate + agent control | Teams that want a polished agent-first platform |
When to pick which
Choose Steel.dev if:
- you want a very polished interactive platform experience
- you’re already standardized on their billing model and integrations
- you don’t need a separate “Request API” style primitive
Choose browser.city if:
- you care about zero-logs as an architectural guarantee
- you want extraction workloads to be first-class (markdown, batch, metadata)
- you want agents to work through MCP without glue code