Geo-Targeted Browsing
Render the same landing page from different countries, cities, and proxy types to validate targeting and localization.
Validate landing pages, redirects, and variants from the same geos your customers see. Capture proof screenshots, detect cloaking, and ship reliable verification pipelines.
Render the same landing page from different countries, cities, and proxy types to validate targeting and localization.
Capture full-page screenshots for audits, disputes, and internal debugging. Pair with HTML/markdown snapshots.
Validate mobile consent banners, redirects, and “tap-only” UX. Use fingerprints and modality-aware actions.
Compare what different egress profiles see (datacenter vs residential, US vs EU) to detect cloaking and variant routing.
Drive deterministic steps over HTTP (open, navigate, click, type, screenshot) without running Playwright in your infra.
BYOP, labeling, and a zero-logs posture help you run verification at scale without leaking sensitive ad intel.
Use Humanized REST tools to open a remote session from a specific geo, navigate to a landing page, and capture a full-page screenshot.
const apiKey = process.env.BROWSERCITY_API_KEY!;const opts = { method: "POST", headers: { Authorization: `Bearer ${apiKey}` } };const post = (path: string, body: unknown) => fetch("https://api.browser.city" + path, { ...opts, body: JSON.stringify(body) }).then((r) => r.json());const open = await post("/v1/do/open", { browser: "chromium", egress: { mode: "managed", proxyType: "residential", country: "US" },});const sessionId = open.result;await post("/v1/do/navigate", { sessionId, url: "https://example.com/landing" });const shot = await post("/v1/do/take_screenshot", { sessionId, type: "png", fullPage: true });console.log({ mime: shot.file.mimeType, bytes: shot.file.data.length });import osimport requestsapi_key = os.environ["BROWSERCITY_API_KEY"]headers = {"Authorization": f"Bearer {api_key}"}base = "https://api.browser.city"post = lambda path, payload: requests.post(base + path, headers=headers, json=payload).json()open_res = post( "/v1/do/open", { "browser": "chromium", "egress": {"mode": "managed", "proxyType": "residential", "country": "US"}, },)session_id = open_res["result"]post("/v1/do/navigate", {"sessionId": session_id, "url": "https://example.com/landing"})shot = post("/v1/do/take_screenshot", {"sessionId": session_id, "type": "png", "fullPage": True})print({"mime": shot["file"].get("mimeType"), "bytes": len(shot["file"]["data"])})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 open = await http.PostAsJsonAsync( "https://api.browser.city/v1/do/open", new { browser = "chromium", egress = new { mode = "managed", proxyType = "residential", country = "US" }, });var openJson = await open.Content.ReadFromJsonAsync<DoResponse>() ?? throw new Exception("bad response");var sessionId = openJson.result;await http.PostAsJsonAsync( "https://api.browser.city/v1/do/navigate", new { sessionId, url = "https://example.com/landing" });var shot = await http.PostAsJsonAsync( "https://api.browser.city/v1/do/take_screenshot", new { sessionId, type = "png", fullPage = true });var shotJson = await shot.Content.ReadFromJsonAsync<ScreenshotResponse>() ?? throw new Exception("bad response");Console.WriteLine($"{shotJson.file.mimeType} {shotJson.file.data.Length}");public record DoResponse(string result);public record ScreenshotFile(string kind, string data, string? mimeType);public record ScreenshotResponse(string result, ScreenshotFile file);import java.net.URI;import java.net.http.*;var apiKey = System.getenv("BROWSERCITY_API_KEY");var auth = "Bearer " + apiKey;var http = HttpClient.newHttpClient();var openReq = HttpRequest.newBuilder() .uri(URI.create("https://api.browser.city/v1/do/open")) .header("Authorization", auth) .POST(HttpRequest.BodyPublishers.ofString( "{\"browser\":\"chromium\",\"egress\":{\"mode\":\"managed\",\"proxyType\":\"residential\",\"country\":\"US\"}}")) .build();var openRes = http.send(openReq, HttpResponse.BodyHandlers.ofString());var sessionId = extractField(openRes.body(), "result");var navReq = HttpRequest.newBuilder() .uri(URI.create("https://api.browser.city/v1/do/navigate")) .header("Authorization", auth) .POST(HttpRequest.BodyPublishers.ofString( "{\"sessionId\":\"" + sessionId + "\",\"url\":\"https://example.com/landing\"}")) .build();http.send(navReq, HttpResponse.BodyHandlers.discarding());var shotReq = HttpRequest.newBuilder() .uri(URI.create("https://api.browser.city/v1/do/take_screenshot")) .header("Authorization", auth) .POST(HttpRequest.BodyPublishers.ofString( "{\"sessionId\":\"" + sessionId + "\",\"type\":\"png\",\"fullPage\":true}")) .build();var shotRes = http.send(shotReq, HttpResponse.BodyHandlers.ofString());System.out.println(shotRes.body());static String extractField(String json, String key) { // Use a proper JSON parser in production. This is intentionally minimal. var i = json.indexOf("\"" + key + "\""); if (i < 0) return ""; var start = json.indexOf('"', i + key.length() + 2); var end = json.indexOf('"', start + 1); return (start >= 0 && end > start) ? json.substring(start + 1, end) : "";} Free tier. No credit card. Full stealth from day one.