One Request = One Signal
Use the Request API to turn a product URL into clean HTML or markdown. No browser runtime, no Playwright harness.
Build hobby projects that survive real anti-bot systems. Start with the Request API (URL → markdown), then add proxies and batching when your watch list grows, without worrying about anti-bot walls.
Use the Request API to turn a product URL into clean HTML or markdown. No browser runtime, no Playwright harness.
Realistic TLS + browser fingerprints help you avoid the “403 after 3 requests” problem common in hobbyist scripts.
Retailers and marketplaces behave differently per geo and network. Choose proxy type and location when you need it.
Stop wiring third-party solvers into your scripts. Our stealth architecture prevents CAPTCHAs from appearing in the first place.
When your “watch list” becomes a catalog, use batch endpoints for higher throughput and fewer round-trips.
Per-minute pricing and a free tier make it practical for side projects and hobby monitoring without surprises.
Fetch a product page as markdown and parse a price. For multiple URLs, switch to batch endpoints and run this in a scheduler.
const authorization = ['Bearer', process.env.BROWSERCITY_API_KEY].join(' ');const page = await fetch('https://api.browser.city/v1/requests', { method: 'POST', headers: { Authorization: authorization, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://example.com/product', markdown: true }),}).then((r) => r.json());const price = String(page.content ?? '').match(/\$([0-9,.]+)/)?.[1];if (!price) throw new Error('price not found');console.log({ price });import os, requests, repage = requests.post( 'https://api.browser.city/v1/requests', headers={'Authorization': f"Bearer {os.environ['BROWSERCITY_API_KEY']}"}, json={'url': 'https://example.com/product', 'markdown': True},).json()import rematch = re.search(r'\$([0-9,.]+)', page.get('content') or '')if not match: raise RuntimeError('price not found')print({'price': match.group(1)})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 page = await (await http.PostAsJsonAsync( "https://api.browser.city/v1/requests", new { url = "https://example.com/product", markdown = true })) .Content.ReadFromJsonAsync<Response>();var match = System.Text.RegularExpressions.Regex.Match(page?.Content ?? "", @"\$([0-9,.]+)");if (!match.Success) throw new Exception("price not found");Console.WriteLine(match.Groups[1].Value);record Response(string? Content);import com.fasterxml.jackson.databind.ObjectMapper;import java.net.URI;import java.net.http.*;public class PriceTracking { public static void main(String[] args) throws Exception { var req = HttpRequest.newBuilder(URI.create("https://api.browser.city/v1/requests")) .header("Authorization", "Bearer %s".formatted(System.getenv("BROWSERCITY_API_KEY"))) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString("{\"url\":\"https://example.com/product\",\"markdown\":true}")) .build(); var page = new ObjectMapper().readValue( HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body(), Response.class); var match = java.util.regex.Pattern.compile("\$([0-9,.]+)").matcher(page.content() == null ? "" : page.content()); if (!match.find()) throw new RuntimeException("price not found"); System.out.println(match.group(1)); } record Response(String content) {}} Start for free. No credit card required. Private sessions by default.