Blog
Monitor Competitor Pricing With 3 Lines of Code
Track competitor prices across any e-commerce site with just 3 lines of code. Unbrowse discovers the internal pricing APIs automatically — no scrapers, no selectors, no maintenance.
Monitor Competitor Pricing With 3 Lines of Code
Competitive pricing intelligence is a billion-dollar industry. Companies like Prisync, Competera, and Intelligence Node charge thousands per month to monitor competitor prices. Most of them run armies of web scrapers that break constantly.
You can build the same thing in 3 lines of code.
The 3-Line Solution
import { Unbrowse } from "@unbrowse/sdk";
const unbrowse = new Unbrowse();
const price = await unbrowse.resolve({ intent: "get current price", url: "https://competitor.com/product/123" });
That is not a simplified example. That is the complete working code. Unbrowse discovers the shadow API behind any product page and returns structured pricing data — no scraper configuration, no CSS selectors, no browser instances.
Why This Works
Every e-commerce site fetches product data from internal APIs. When you visit a product page, the browser does not parse HTML to display the price — it calls an API endpoint that returns JSON with the price, availability, variants, and more.
These shadow APIs are more stable than the HTML. While a site might redesign their product page every quarter, the underlying API rarely changes because their mobile apps, internal tools, and CDN layers all depend on it.
Unbrowse discovers these APIs by observing real browsing traffic, reverse-engineers the contract (URL template, parameters, auth patterns), and publishes the route to a shared marketplace. Once discovered, any agent can call the API directly.
Building a Full Competitor Monitor
The 3-line version gets you a single price check. Here is how to build a production competitor monitoring system:
import { Unbrowse } from "@unbrowse/sdk";
import { writeFileSync, readFileSync, existsSync } from "fs";
const unbrowse = new Unbrowse();
const competitors = {
"Widget Pro": [
{ retailer: "Amazon", url: "https://www.amazon.com/dp/B0EXAMPLE1" },
{ retailer: "Walmart", url: "https://www.walmart.com/ip/widget-pro/12345" },
{ retailer: "Target", url: "https://www.target.com/p/widget-pro/-/A-12345" },
],
"Widget Lite": [
{ retailer: "Amazon", url: "https://www.amazon.com/dp/B0EXAMPLE2" },
{ retailer: "Best Buy", url: "https://www.bestbuy.com/site/widget-lite/6789.p" },
],
};
const HISTORY_FILE = "./competitor-prices.json";
function loadHistory() {
return existsSync(HISTORY_FILE)
? JSON.parse(readFileSync(HISTORY_FILE, "utf-8"))
: {};
}
function saveHistory(history) {
writeFileSync(HISTORY_FILE, JSON.stringify(history, null, 2));
}
async function monitor() {
const history = loadHistory();
const timestamp = new Date().toISOString();
for (const [product, sources] of Object.entries(competitors)) {
if (!history[product]) history[product] = [];
const prices = await Promise.all(
sources.map(async (s) => {
const result = await unbrowse.resolve({
intent: `get current price and availability for ${product}`,
url: s.url,
});
return {
retailer: s.retailer,
price: result.data?.price,
available: result.data?.inStock ?? result.data?.available,
};
})
);
history[product].push({ timestamp, prices });
// Save after each product (incremental progress)
saveHistory(history);
// Log any price changes
const previous = history[product][history[product].length - 2];
if (previous) {
for (const current of prices) {
const prev = previous.prices.find((p) => p.retailer === current.retailer);
if (prev && prev.price !== current.price) {
console.log(
`PRICE CHANGE: ${product} at ${current.retailer}: $${prev.price} -> $${current.price}`
);
}
}
}
}
return history;
}
await monitor();
Key design decisions in this code:
- Parallel per product: All retailers for a single product are checked simultaneously
- Incremental saves: History is saved after each product, so interrupted runs do not lose data
- Change detection: Compares current prices against the last recorded check
- Availability tracking: Captures stock status alongside price
Detecting Price Patterns
With historical data accumulating, you can detect pricing patterns that give you a competitive edge:
function analyzePricing(history, product) {
const entries = history[product] || [];
if (entries.length < 2) return null;
const analysis = {};
for (const retailer of new Set(entries.flatMap((e) => e.prices.map((p) => p.retailer)))) {
const retailerPrices = entries
.map((e) => {
const match = e.prices.find((p) => p.retailer === retailer);
return match ? { timestamp: e.timestamp, price: match.price } : null;
})
.filter(Boolean)
.filter((p) => p.price != null);
if (retailerPrices.length < 2) continue;
const prices = retailerPrices.map((p) => p.price);
analysis[retailer] = {
current: prices[prices.length - 1],
min: Math.min(...prices),
max: Math.max(...prices),
average: prices.reduce((a, b) => a + b, 0) / prices.length,
trend: prices[prices.length - 1] > prices[0] ? "increasing" : "decreasing",
volatility: (Math.max(...prices) - Math.min(...prices)) / Math.min(...prices),
dataPoints: prices.length,
};
}
return analysis;
}
This tells you which retailers are the most volatile (opportunity for arbitrage), which trend upward (buy now signals), and which consistently undercut others.
Alerting on Competitive Moves
Set up real-time alerts when competitors change prices:
async function checkAndAlert() {
const history = loadHistory();
for (const [product, sources] of Object.entries(competitors)) {
const prices = await Promise.all(
sources.map(async (s) => {
const result = await unbrowse.resolve({
intent: `get current price`,
url: s.url,
});
return { retailer: s.retailer, price: result.data?.price };
})
);
const previousEntry = history[product]?.[history[product].length - 1];
if (!previousEntry) continue;
for (const current of prices) {
const prev = previousEntry.prices.find((p) => p.retailer === current.retailer);
if (!prev || !current.price || !prev.price) continue;
const change = ((current.price - prev.price) / prev.price) * 100;
if (Math.abs(change) >= 5) {
console.log(
`SIGNIFICANT CHANGE: ${product} at ${current.retailer} ` +
`moved ${change > 0 ? "up" : "down"} ${Math.abs(change).toFixed(1)}% ` +
`($${prev.price} -> $${current.price})`
);
}
}
}
}
Scaling to Hundreds of Products
For larger product catalogs, batch your monitoring with rate awareness:
async function batchMonitor(products, batchSize = 10) {
const history = loadHistory();
const allProducts = Object.entries(products);
for (let i = 0; i < allProducts.length; i += batchSize) {
const batch = allProducts.slice(i, i + batchSize);
await Promise.all(
batch.map(async ([product, sources]) => {
if (!history[product]) history[product] = [];
const prices = await Promise.all(
sources.map(async (s) => {
const result = await unbrowse.resolve({
intent: `get current price`,
url: s.url,
});
return { retailer: s.retailer, price: result.data?.price };
})
);
history[product].push({
timestamp: new Date().toISOString(),
prices,
});
})
);
// Save after each batch
saveHistory(history);
console.log(`Batch ${Math.floor(i / batchSize) + 1} complete (${i + batch.length}/${allProducts.length} products)`);
}
}
Comparison With Existing Solutions
| Feature | Prisync/Competera | Custom Scrapers | Unbrowse |
|---|---|---|---|
| Setup time | Days-weeks | Days | Minutes |
| Monthly cost | $500-5000+ | Hosting + maintenance | Free (marketplace earnings offset) |
| Products tracked | Plan-limited | Unlimited | Unlimited |
| Maintenance | Managed | Constant | Zero |
| Data freshness | Hourly-daily | Depends | On-demand |
| Code required | None (SaaS) | Hundreds of lines | 3 lines per product |
| Custom analysis | Limited | Full control | Full control |
The Marketplace Advantage
When your monitoring agent discovers a retailer's pricing API, that route gets published to the Unbrowse marketplace. Other agents that need pricing from the same retailer use your route instantly — and you earn x402 micropayments for every hit.
The first agent to index a major retailer's pricing API earns 2x the standard rate. If you monitor 50 competitors across 10 retailers, you are building a portfolio of high-value routes that generate passive income as more agents come online.
Getting Started
git clone --single-branch --depth 1 https://github.com/unbrowse-ai/unbrowse.git ~/unbrowse
cd ~/unbrowse && ./setup --host off
Or install the SDK:
npm install @unbrowse/sdk
Start with your top 3 competitors. Add their product URLs to the monitor. Run it once to discover the routes, then schedule it hourly. You will have better competitive intelligence than most enterprise pricing tools — in 3 lines of code.