Monitoring ·
How to Track Competitor Prices on Shopify Stores
Get a webhook every time a competitor changes a price, with the old and new price per variant. Create a monitor, receive the events and store a price history in about 60 lines of TypeScript.
By the end of this tutorial you'll get a webhook every time one of your competitors changes the price of a product, with the old and the new price of every variant that changed, and you'll store those changes in a price history you can query. Instead of scraping each competitor's catalog yourself, you create one ShopLens monitor that watches up to 100 Shopify stores, and ShopLens checks them about once a day and posts each change to your endpoint.
Prerequisites
- A ShopLens API key in SHOPLENS_API_KEY.
- A public HTTPS endpoint that can receive POST requests. A Next.js route handler, an Express app or a serverless function all work. Localhost and IP addresses are rejected as webhook URLs.
- Node.js 20 or later, and the standardwebhooks package to check signatures.
- The domains of the competitors you want to track. If you don't have a list yet, start with [how to find the competitors of a Shopify store](/blog/find-shopify-competitors).
How the pieces fit
- You create a monitor with a list of stores, the change topics you care about and your webhook URL.
- ShopLens checks each store about once a day. Several monitors watching the same store share one check.
- When a price changes, ShopLens sends one POST per product to your URL, signed with the monitor's secret.
- Your endpoint verifies the signature, saves the change and answers 2xx within 10 seconds.
Step 1: make sure ShopLens has every store
A monitor only accepts stores ShopLens already has. Look each domain up once with GET /shops/{domain}. A store that hasn't been seen before answers 202 and is ready a few minutes later; then it can go into a monitor.
Move on when every domain answers 200. A 404 means the domain isn't a public Shopify store.
Step 2: create the monitor
Send the stores, the topics and your URL. For a price tracker, product.price_changed is the topic you need. Adding product.out_of_stock and product.back_in_stock is cheap and tells you when a price change coincides with a stock problem.
The response includes the monitor's id and its secret, which starts with whsec_. Store the secret in an environment variable such as SHOPLENS_WEBHOOK_SECRET; you'll need it to verify every webhook.
Price and stock topics depend on the market, because a store can sell the same product at different prices in different countries. markets lists the countries to check. Leave it empty to check only each store's primary market. A monitor costs 1 credit a month while it's active, whatever the number of changes. Every field is described in the docs.
Step 3: understand the payload
Each webhook covers one product. When several variants of that product change in the same check, they arrive together in data.variants, and each variant carries previous with the price before the change.
Prices are decimal strings. Parse them with care (or keep them as strings in your database) to avoid floating-point rounding.
Step 4: receive and verify the webhook
This is a Next.js route handler. It reads the raw body, verifies the signature with the Standard Webhooks library, skips events it has already stored and saves one row per variant.
The db call stands in for your own database client; the example uses a Prisma-style upsert. The unique key on event ID and variant ID makes the handler safe to run twice, because the event ID stays the same if a webhook is sent again. Signature checks are covered in depth in how to verify webhook signatures in Node.js.
Step 5: query your price history
With one row per variant change, the questions you care about become simple queries. For example, every variant whose price fell by more than a tenth in the last week:
From here you can send a Slack message for big cuts, chart a competitor's prices over time or compare their price to yours for the same product.
Step 6: decide what to do with each change
Storing every change is easy. Deciding which ones deserve a person's attention is where a price tracker becomes useful. A simple set of rules covers most teams:
- Ignore small moves. Changes of a few cents usually come from currency conversion or rounding in stores that sell in several markets.
- Flag big drops on overlapping products. If you sell the same product or a close substitute, a large drop on a competitor's version is the change to look at first.
- Watch for patterns, not single events. A competitor that drops prices on a whole collection on the same day is running a promotion. One product dropping alone is more likely a clearance or a price test.
- Combine price and stock. A price rise right after a product comes back in stock, or a drop just before it sells out, tells you how the competitor manages inventory.
Write the rules down before you build alerts. Teams that send every webhook to a Slack channel stop reading the channel within a week.
Step 7: keep the monitor up to date
Your competitor list changes, and the monitor should follow it. Update it with PATCH /monitors/{id}. The shops, topics and markets lists are replaced as a whole, so send the full new list each time, not only the additions. Set active to false to pause a monitor without losing its configuration, for example during a period when nobody will read the alerts, and delete it when you no longer need it. Listing, updating and deleting monitors are free.
Limits to keep in mind
- Daily checks. Stores are checked about once a day, so a price that changes and changes back within a few hours may not show up.
- Public prices only. You see what a shopper in the chosen market sees. Prices behind a login, B2B price lists and discount codes applied at checkout are not visible.
- Per-market prices. A store that prices by country can show a change in one market and not in another. Add the markets you sell in.
- One change, several topics. Putting a variant on sale can fire a price change, a compare-at change and a sale start. Subscribe only to the topics you'll act on. Detecting sales specifically is covered in [how to know when a competitor starts a sale](/blog/detect-competitor-sale-shopify).
What to build next
Once the history fills up, use it. Repricing tools adjust your price within rules you set when a competitor moves. Merchandising teams use it to spot which products a competitor discounts every month and plan around it. And if you also track new products, add product.created to the same monitor to see launches the day they go live.