← All use cases
E-commerce & PricingCSS

Competitor Price Tracking

Watch every competitor SKU you care about and get notified the moment a price moves - without scraping infrastructure or daily manual checks.

Verid Use Cases·4 min read

The scenario

You sell a product that competes with three or four other stores online. Your pricing analyst opens a spreadsheet on Monday morning, visits each competitor's product page, copies the current price into the sheet, and decides whether to adjust. By Wednesday afternoon the data is already stale - one of those competitors ran a flash sale at 2am and you missed it for thirty-six hours.

This is the core repricing problem. The faster you react to a competitor's price move, the more margin and volume you protect. The slower you react, the more your sales team gets stuck answering "why are you $40 higher than store X?"

The problem

Manual price checks have three failure modes that compound. They're slow - a once-a-day check means up to twenty-three hours of blindness. They're shallow - analysts check the URLs they remember, not the long tail. And they're inconsistent - humans miss the difference between $1,299 and $1,289 when they're tired.

Buying a full-blown competitive intelligence platform solves it but introduces its own problems: month-long onboarding, expensive seats, opaque "AI-powered" dashboards that don't fit your team's tools. What most pricing teams actually want is much simpler - a notification when a competitor's price changes, with the new value attached.

How Verid solves it

Point Verid at the competitor's product page, tell it which CSS selector contains the price, and pick a check interval - every fifteen minutes if the category is volatile, hourly for everything else. Verid loads the page on schedule, extracts the price into a named field, diffs it against the last value, and fires a webhook (or Slack message, or email) the moment the number changes.

You define one monitor per SKU you care about. There's no scraping pipeline to maintain, no headless browser cluster to babysit. When a competitor reskins their site and the selector breaks, Verid surfaces that as an extraction error in the dashboard and you fix it with a one-line edit.

Build the monitor

Extraction config

{
  "method": "css",
  "fields": {
    "price": ".product-price .current",
    "title": "h1.product-title",
    "availability": ".stock-status"
  }
}

Predicate

Fire on any change to any of the tracked fields. If you only care about the price, narrow it:

{ "type": "field_changes", "field": "price" }

Create the monitor

curl:

curl -X POST https://api.verid.dev/v1/monitors \
  -H "Authorization: Bearer vrd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Competitor - Acme Laptop 14",
    "url": "https://competitor.com/products/acme-laptop-14",
    "schedule_interval_seconds": 1800,
    "extract_config": {
      "method": "css",
      "fields": {
        "price": ".product-price .current",
        "title": "h1.product-title",
        "availability": ".stock-status"
      }
    },
    "diff_predicate": { "type": "field_changes", "field": "price" },
    "deliveries": [
      { "type": "slack", "webhookUrl": "https://hooks.slack.com/services/..." }
    ]
  }'

SDK:

import { VeridClient } from '@verid.dev/sdk';

const client = new VeridClient({ apiKey: 'vrd_your_api_key' });

await client.monitors.create({
  name: 'Competitor - Acme Laptop 14',
  url: 'https://competitor.com/products/acme-laptop-14',
  schedule_interval_seconds: 1800,
  extract_config: {
    method: 'css',
    fields: {
      price: '.product-price .current',
      title: 'h1.product-title',
      availability: '.stock-status',
    },
  },
  diff_predicate: { type: 'field_changes', field: 'price' },
  deliveries: [
    { type: 'slack', webhookUrl: 'https://hooks.slack.com/services/...' },
  ],
});

What the webhook delivers

{
  "id": "del_01H...",
  "version": "2026-05-01",
  "monitor_id": "9b1c…",
  "run_id": "7e2a…",
  "fired_at": "2026-05-08T12:00:00Z",
  "diff": {
    "fields_changed": ["price"],
    "before": { "price": "$1,299.00", "title": "Acme Laptop 14", "availability": "In stock" },
    "after":  { "price": "$1,199.00", "title": "Acme Laptop 14", "availability": "In stock" }
  },
  "monitor": {
    "url": "https://competitor.com/products/acme-laptop-14",
    "name": "Competitor - Acme Laptop 14"
  }
}

Your repricing service consumes the webhook, computes the new gap, and decides whether to match, undercut, or hold.

Caveats & tips

  • Currency symbols block percent predicates. If you want to fire only on drops larger than 5%, the field has to parse as a number. "$1,299.00" parses to NaN. Either strip the symbol in your downstream consumer, or watch for field_changes and apply the threshold there.
  • No fire on the first run. Verid needs a baseline before it can diff. The first run records the starting price silently; the second run onwards is where alerts come from.
  • Heavy JavaScript pages need browser mode. If view-source: doesn't show the price string, set fetch_mode: 'browser' when creating the monitor so Verid renders with a real browser before extracting.
  • Build one monitor per SKU, not one per store. Verid's tier limits are per-monitor, and per-SKU monitors give you clean diffs and clean notifications.

Related use cases

If you're tracking prices across Shopify storefronts specifically, see Shopify product stock & price. For Amazon listings (which need browser mode), see Amazon product watch. And for restock-aware monitoring, see restock alerts.

Ship this monitor today

5 monitors free, no credit card. Set up takes about a minute.

Get started free