If you sell anything online, somebody is undercutting you right now and you do not know it yet. The job of price monitoring is to close that blind spot: watch the listings that matter, catch the moment a competitor drops a SKU by twelve percent, and react before the weekend traffic finds the cheaper option. The hard part has never been the idea. It is the plumbing. To automate price monitoring at any real scale, you have to fetch dozens or hundreds of pages, survive their redesigns, dodge their bot defenses, and turn whatever the page renders into clean numbers your pipeline can act on. That last mile is where most homegrown scrapers go to die.
I have built both kinds of systems — the brittle CSS-selector pipelines that need a babysitter, and the newer agent-driven setups that read a page the way a buyer does. This article is an honest walkthrough of how an AI browser agent changes the economics of competitor price tracking, using BrowserBash, a free, open-source CLI that turns a plain-English objective into structured results. I will show you how to run the whole thing on a cron, feed its NDJSON output into a pipeline, and keep your model bill at exactly zero by running local models instead of paying per page to a hosted browser-cloud vendor. I will also tell you, plainly, where a paid service is the better call. Credibility beats hype.
Why price monitoring is a browser problem, not an API problem
The clean way to track a competitor's prices would be to call their API. Almost nobody exposes one, and the ones that do gate it behind partner agreements. So you are left with the public web, which means you are looking at rendered pages built for humans: prices injected by JavaScript, variant selectors that change the number when you pick a size, "members only" pricing behind a login, and A/B tests that show different layouts to different visitors.
Traditional scraping answers this with selectors. You write something like div.product-grid .price__current and pray the markup holds. It holds until the target ships a redesign, runs an experiment that renames a class, or wraps the price in a new container for a promo. Then your job silently returns null, your dashboard shows yesterday's number, and you find out three days later when a teammate asks why your "lowest price match" is wrong.
The deeper issue is that selectors encode where a value lives in the DOM, not what the value is. A human looking at the page never thinks about nth-child. They see "the price is forty-nine ninety-nine, and there's a strikethrough at sixty-nine." An AI browser agent works the same way. You describe the intent in English, it looks at the rendered page, and it reads the number. When the layout moves, it re-reads the new layout and usually keeps working, because it was never bound to a node path to begin with. For a workload as redesign-prone as competitor catalogs, that resilience is the whole ballgame.
What BrowserBash actually does
BrowserBash is a command-line tool by The Testing Academy. You install it with npm, write a plain-English objective, and an AI agent drives a real Chrome browser step by step to accomplish it — no selectors, no page objects, no recorded scripts. It returns a verdict (did the objective succeed?) plus structured results you can parse.
npm install -g browserbash-cli
browserbash run "Open example-store.com/p/widget-9000, read the current price and any strikethrough original price, and report both as numbers"
That is the entire mental model. You are not maintaining a scraper; you are handing an agent a task and reading what it found. Because it drives a genuine browser, it handles the JavaScript-rendered prices, the cookie banners, and the variant clicks that defeat a raw HTTP fetch. The agent decides what to click and what to read; you decide what you want to know.
A few facts worth pinning down before we wire this into a pipeline, because they shape the cost and trust story:
- It is Ollama-first. By default BrowserBash uses free local models through Ollama. No API key, nothing leaves your machine. It auto-resolves a local Ollama install first, then an
ANTHROPIC_API_KEY, then anOPENROUTER_API_KEYif you have set those. You can guarantee a zero-dollar model bill by staying local. - No account is required to run it. It is Apache-2.0 licensed and runs entirely on your machine out of the box. There is an optional free cloud dashboard for run history and video replay, strictly opt-in, plus a fully local dashboard if you want the UI without uploading anything.
- Agent mode emits NDJSON. The
--agentflag prints one JSON event per line to stdout, with meaningful exit codes. That is the seam where price monitoring stops being a demo and becomes a pipeline.
If you want the broader tour of how the agent reasons over a page, the BrowserBash learn pages go deeper than I can here.
The honest model caveat
I am not going to pretend local models are magic. The sweet spot matters, and getting it wrong is how people conclude "AI automation is flaky" when really they picked the wrong brain.
Very small local models — roughly 8B parameters and under — get unreliable on long, multi-step objectives. They will nail "read the price on this one page" and then lose the plot on "navigate the category, paginate, and collect twenty SKUs." For price monitoring specifically, this is mostly fine, because the right design keeps each objective small (more on that below). But if you want one agent to crawl deep, use a mid-size local model in the Qwen3 or Llama 3.3 70B class, or reach for a capable hosted model on the hard flows.
The practical rule: decompose the work so each run is short, and the small local model stays inside its competence. One product, one objective, one number. Run a hundred of those instead of one giant crawl, and even a modest local model behaves. When you genuinely need depth and judgment on a single complex page, that is when bringing your own Anthropic key or an OpenRouter free model earns its keep.
The pipeline pattern: --agent NDJSON into anything
Here is the architecture that makes this production-grade. Instead of asking the agent for prose and then regex-ing the answer out (fragile, sad), you run it in agent mode and consume structured events.
browserbash run "Open shop.example.com/p/widget-9000, read the current selling price as a number, and report it" --agent
With --agent, stdout becomes a stream of newline-delimited JSON — one event per line, each a complete JSON object describing a step, a result, or the final verdict. There is no prose to parse. Your consumer reads stdin line by line, JSON.parses each, and pulls out the values it cares about. This is the same contract CI systems and AI coding agents rely on, which is exactly why it is dependable for a price feed.
The exit code tells your scheduler what happened without you parsing anything:
| Exit code | Meaning | Pipeline action |
|---|---|---|
0 |
Objective passed | Record the price, move on |
1 |
Objective failed | Page loaded but the price was not found — flag for review |
2 |
Error | Crash, bad URL, browser issue — retry or alert |
3 |
Timeout | Page hung or the agent stalled — retry with backoff |
That four-state signal is more than most hand-rolled scrapers give you. A typical scraper either returns data or throws, and you cannot tell "the site is down" from "the price moved to a new element." Here, a 1 versus a 2 versus a 3 routes to different handling, which is the difference between a pipeline that pages you for real problems and one that cries wolf every time a CDN hiccups.
Wiring it into a job
The consumer is deliberately boring. A small Node or Python script spawns browserbash run ... --agent per target URL, reads the NDJSON, extracts the price from the final result event, and writes a row to your store — Postgres, a sheet, a Slack webhook, whatever. Because the interface is just lines of JSON on stdout and an exit code, you are not coupled to any framework. You can fan out across a URL list, throttle concurrency so you are a polite visitor, and append {url, price, captured_at, run_status} to a table. The agent does the browser work; your glue code does the bookkeeping.
Running it on a cron so prices track themselves
Monitoring is only monitoring if it repeats. The whole point is to automate price monitoring so it happens without you remembering to look. On a Mac or Linux box, that is a cron entry or a systemd timer pointed at a wrapper script. Run it headless so no window pops up on the build machine:
# crontab -e — check three competitor SKUs every morning at 6am
0 6 * * * /usr/local/bin/track-prices.sh >> /var/log/price-monitor.log 2>&1
And inside track-prices.sh, the headless run with recording for an audit trail:
browserbash run "Open competitor.com/products/blue-widget, read the price and stock status, report both" \
--agent --headless --record
The --headless flag keeps it invisible for unattended runs. The --record flag captures a screenshot and a full .webm session video for every run — which, for price monitoring, is gold. When a competitor disputes that you matched their price, or when a number looks wrong, you have a recording of exactly what the page showed at 6:02am. That is an audit trail your CSS scraper never had.
How often should you run? Match cadence to volatility. Fast-moving categories — electronics, travel, anything with dynamic pricing — justify hourly. A stable catalog of industrial parts is fine daily or even weekly. The marginal cost of running more often on local models is just your own CPU and electricity, not a per-page invoice, which quietly changes how aggressively you can poll. That cost asymmetry is the strategic point of going local, and it is worth sitting with.
The cost math: free local models vs per-page browser clouds
This is where the "running on free local models instead of paying per page" angle earns its place, so let me be precise and fair about it.
Hosted browser-infrastructure vendors — Browserbase and Steel.dev are the two most people mean — run headless browsers in their cloud and bill you for usage. As of 2026, their exact, current pricing tiers are best read on their own sites rather than quoted from memory; I am not going to invent numbers. The shape that matters is structural: when you rent browser sessions by the minute or by the page, a monitoring workload that polls hundreds of SKUs every hour turns into a metered cost that scales with how closely you want to watch. The more you monitor, the more you pay. That is fine for spiky, on-demand jobs. It works against you for a standing, high-frequency price feed, which is the opposite of spiky.
BrowserBash inverts that for the model and the browser both. The browser runs locally in your own Chrome by default, and the model runs locally through Ollama, so the marginal cost of one more check is electricity. You can run a thousand price checks a day and the bill is the same as running ten: zero. The trade you are making is real and worth naming — you operate the box, you keep Ollama and Chrome healthy, and you eat the occasional flaky-small-model run. A managed cloud takes that operational load off your plate. You are choosing between paying with money and paying with attention.
| BrowserBash (local) | Hosted browser cloud | |
|---|---|---|
| Where the browser runs | Your machine's Chrome (default) | Vendor's cloud |
| Model | Free local via Ollama by default | Bring your own / separate |
| Marginal cost per page | ~zero (your electricity) | Metered, scales with volume |
| Who runs the infra | You | The vendor |
| Best for | Standing, high-frequency feeds | Spiky, on-demand, scale-out jobs |
| Proxies / IP rotation at scale | You arrange it | Often built in |
I want to be straight about that last row, because it is the honest weakness. If you are monitoring at a scale where the target sites will rate-limit or block your single IP, a hosted cloud's managed proxy pool is a genuine advantage you do not get for free locally. BrowserBash can point at other providers when you need them — more on that next — but if heavy proxy rotation is your core problem, a service built around it may simply be the better fit. Tools should be judged on the job in front of you.
When you do need the cloud: providers and engines
BrowserBash is not religious about running everything on your laptop. It has a provider flag that decides where the browser lives, switched with one option:
# Run the same objective on LambdaTest's cloud grid instead of local Chrome
browserbash run "Read the price on competitor.com/p/widget" \
--agent --provider lambdatest
The providers are local (the default, your Chrome), cdp (any DevTools endpoint you control), browserbase, lambdatest, and browserstack. So the architecture composes: keep your routine high-frequency monitoring on free local runs, and burst onto a cloud grid only for the targets that block you or the runs you need geo-distributed. You are not locked into one mode. You pick per job.
Under the hood there are two engines. The default is stagehand (MIT-licensed, built by Browserbase), and there is a builtin engine that runs an in-repo Anthropic tool-use loop. For most price-reading objectives the default is what you want. The detail worth knowing: the builtin engine additionally captures a Playwright trace you can open in the trace viewer, on top of the screenshot and video that --record already gives you. When a particular site's price extraction misbehaves and you need to see every action the agent took, that trace is the debugging surface. The full provider and engine matrix is laid out on the features page.
Make it a committable test: Markdown monitors with variables
Cron scripts are fine, but they live on one machine and rot in obscurity. BrowserBash has a nicer pattern for anything you want versioned and reviewable: Markdown tests. You write a *_test.md file where each list item is a step, compose files with @import, and parameterize with {{variables}}. Secret-marked variables get masked as ***** in every log line, which matters the moment a monitor needs to log into a members-only price.
browserbash testmd run ./competitor_price_test.md
A monitor file might read like this — plain English, one step per line, the kind of thing a non-engineer on your pricing team can actually review in a pull request:
# Competitor price check — {{product_name}}
- Go to {{target_url}}
- If a cookie banner appears, dismiss it
- Read the current selling price as a number
- Read the original/strikethrough price if one is shown
- Report both prices and whether the item is in stock
You feed target_url and product_name in as variables, so one file covers your whole watch list. After each run BrowserBash writes a human-readable Result.md next to it, so there is a checked-in record of what the monitor saw. Now your price monitoring lives in git, gets reviewed like code, and templates across every SKU you care about. That is a meaningfully better posture than a pile of selectors in a script only one person understands. The learn section has more on @import composition if your watch list grows large.
Handling logins and gated pricing
Plenty of competitor pricing hides behind an account — wholesale tiers, member discounts, "add to cart to see price." Because the agent drives a real browser and Markdown tests support secret-marked variables, you express the login as steps and pass credentials as masked variables. The objective reads naturally: "log in with {{username}} and {{password}}, navigate to the wholesale catalog, read the tier price." The secret masking means your CI logs never leak the password, and the real-browser model means you are not reverse-engineering an auth flow — you are just describing the clicks a person would make. BrowserBash can run a full store flow end to end, the same way it can log in, add an item to the cart, complete checkout, and verify a "Thank you for your order!" confirmation.
A realistic end-to-end monitoring setup
Putting the pieces together, here is what a sane competitor-price system looks like in practice.
You keep a list of target URLs — one row per SKU you care about, tagged with the competitor and your matching internal product. A cron job fires on your chosen cadence and runs a wrapper script. The script loops the list, and for each target spawns browserbash run "..." --agent --headless, optionally --record for the audit trail. It reads the NDJSON off stdout, pulls the price from the final result event, checks the exit code to decide whether the run is trustworthy, and appends {competitor, sku, price, in_stock, captured_at, run_status} to a table. A small diff step compares today's price to yesterday's; when the delta crosses a threshold you set, it fires a Slack or email alert with the recorded screenshot attached so a human can eyeball it in two seconds.
The routine bulk runs on free local models, on local Chrome, at zero marginal cost, so you can poll as often as the category deserves. A handful of stubborn targets that block your IP get a --provider lambdatest override and run on a cloud grid. The whole watch list lives in a *_test.md file under version control, reviewed in pull requests, with credentials masked. Nobody is maintaining selectors. When a competitor redesigns their product page next quarter, the agent re-reads the new layout and the price keeps flowing, while the team that hard-coded nth-child spends a sprint rewriting scrapers.
That is the shape of the win. Not that AI is smarter, but that intent-based extraction degrades gracefully where structure-based extraction shatters, and that running it locally turns "watch more often" from a budget conversation into a non-event.
Who this is for, and who should pass
Be honest with yourself about your situation before you build this.
This fits you if: you are an ecommerce seller, reseller, or pricing analyst tracking a defined set of competitor SKUs; you want a standing, high-frequency feed without a metered per-page bill; you value an auditable, version-controlled definition of what you monitor; and you are comfortable keeping a machine with Chrome and Ollama running. The free-local story is genuinely compelling when your monitoring is continuous rather than bursty, because that is exactly the workload that punishes pay-per-page pricing.
A managed service may serve you better if: your core obstacle is anti-bot defenses and IP blocking at large scale, and you would rather buy a proxy pool than operate one; you need thousands of concurrent, geo-distributed sessions on demand; or you simply do not want to run any infrastructure and will happily pay to make that someone else's job. Those are real, defensible reasons. An honest comparison sometimes points away from the tool I am writing about, and this is one of those times. Pick the cost model that matches your traffic shape.
For teams in the middle, the composability is the answer: local by default, cloud provider for the hard targets, no all-or-nothing decision. You can read more real-world setups on the BrowserBash blog, and the pricing page lays out exactly what the optional cloud dashboard does and does not cost.
FAQ
How do I automate price monitoring without writing a scraper?
Use an AI browser agent that takes a plain-English objective instead of CSS selectors. With BrowserBash you write something like "open this product page and read the current price as a number," run it on a cron, and the agent drives a real browser to extract the value. Because there are no selectors to maintain, the monitor keeps working when the target site changes its layout, which is the failure mode that breaks traditional scrapers.
Can I track competitor prices for free?
Yes, if you run BrowserBash on free local models through Ollama and use your own local Chrome as the browser. In that configuration nothing leaves your machine and there is no per-page or per-token bill, so the marginal cost of each price check is just electricity. You only start paying if you choose to bring a hosted model key or run on a cloud browser provider for the harder targets.
How is this different from Browserbase or Steel.dev?
Those are hosted browser-infrastructure clouds that run headless browsers for you and bill for usage, which suits spiky, scale-out jobs and gives you managed proxies. BrowserBash runs the browser locally by default and the model locally too, so a standing high-frequency price feed costs nothing extra to run more often. The trade is that you operate the machine and arrange your own proxies, so heavy anti-bot scenarios at scale may genuinely favor a managed cloud.
How do I feed the price data into a pipeline?
Run BrowserBash with the --agent flag, which emits NDJSON — one JSON event per line on stdout — plus a meaningful exit code (0 passed, 1 failed, 2 error, 3 timeout). Your consumer reads each line, parses it as JSON, pulls the price from the final result event, and checks the exit code to decide whether the run is trustworthy. There is no prose to regex, which is why it slots cleanly into cron jobs, CI, and other automation.
Get started
You can have a working competitor price monitor running tonight. Install the CLI, point it at one product URL, watch it read the price, then wrap it in a cron job and a Markdown test file as your watch list grows.
npm install -g browserbash-cli
It runs fully on your machine with no account and no API key. When you want run history, video replay, and a per-run timeline across your monitors, the optional cloud dashboard is a free, opt-in upgrade — sign up here (an account is optional, never required to run). Start local, stay free, and only reach for the cloud on the targets that actually need it.