Scraping

How to Track Competitor Promotions and Discount Cycles

A promotion is an event with a start and an end, and price snapshots miss both. How to record promotions as events and reconstruct a competitor's calendar.

James Meadow

James Meadow

September 7, 2026 · 7 min read

Most teams that want to track competitor promotions already have price monitoring, and are surprised that it does not answer the question.

The reason is structural. Price monitoring records levels: what did this item cost when we looked. A promotion is an event: it started, it had a mechanism and a depth, it ran for a period, it ended. A series of levels can hint at an event, but it cannot tell you when the promotion began, how long it was meant to run, or what triggered it. And if your sampling interval is longer than the promotion, the event never happened as far as your data is concerned.

What a price series gets wrong

Two failure modes account for most of it.

The promotion is shorter than your interval. A daily snapshot sees nothing of a six-hour flash sale. Not a shallow discount, nothing at all. Your data says the competitor held price while their customers saw a sale.

The promotion is longer than your interval but you only see the edges. A weekly snapshot that happens to land inside a three-day promotion records it as the prevailing price for the whole week. That single misread will distort every average built on top of it.

Both produce clean-looking data. Neither raises an error. This is why promotion tracking needs its own design rather than being treated as a report over the price table.

The price field is not where promotions live

The second structural problem is that a discount often does not change the number your parser reads.

Mechanisms that price monitoring routinely misses:

  • Cart-level discounts. The item price is unchanged; the reduction appears at checkout.
  • Coupon codes. Applied at cart, sometimes surfaced on the page as a banner, sometimes distributed by email only.
  • Bundles and multibuy. Buy two for a lower unit price. The listed unit price is untouched.
  • Conditional eligibility. Member pricing, first-order discounts, regional offers, loyalty tiers.
  • Shipping thresholds. Functionally a discount, invisible in the price field entirely.

So the collection has to capture more than the number. At minimum: the displayed price, any strike-through or reference price, promotional badge text, banner text, and the stated end time if one is shown. Countdown timers are worth parsing specifically, because they are the only place a competitor tells you their intended end date.

The general retail collection mechanics are in residential proxies for price monitoring, and the store-scoped version of the problem is in Walmart price and inventory monitoring.

Record events, not observations

The design decision that makes everything downstream work: derive promotion events from your observations and store them as their own records.

An event needs a start observation, an end observation, and the fields that describe it:

FieldWhy it matters
Base priceThe reference the discount is measured against, not last week’s price
Promo priceThe effective price during the event
MechanismPercentage, fixed amount, bundle, coupon, cart-level, shipping
DepthComputed from base and promo, stored rather than recalculated
Start and end observationWith timestamps, so duration is measurable
Stated endFrom a countdown or banner, where the competitor published one
MarketThe country and, where relevant, the region the observation came from
ConfidenceWhether the boundaries were observed or bounded by your sampling interval

That last field is the honest one. If you sample every six hours, you know the promotion started within a six-hour window, not when it started. Recording the uncertainty means your duration analysis can account for it instead of pretending to a precision it does not have.

Cadence has to be shorter than what you want to see

The rule is uncomfortable but simple: you cannot detect a promotion shorter than your sampling interval, and you cannot measure the duration of one to better precision than that interval.

Rather than raising frequency everywhere, tier it. A small watchlist of high-value items on your most aggressive competitors justifies a short interval. The long tail can run daily. Then add an event-driven layer: when one item on a competitor moves, tighten the interval on that competitor for a period, because promotions cluster.

Retail calendars also make this predictable in parts. The weeks around known sale periods deserve a raised cadence set in advance, since that is when both the frequency and the depth of promotions change.

Promotions are regional

A competitor’s promotional calendar is usually not one calendar. Offers run by market, and the same product page can show a discount in one country and full price in another, on the same day.

Collecting from a single vantage point gives you one market’s calendar labelled as the competitor’s strategy. If you sell across markets, the collection has to come from each of them. Residential proxies with country targeting are what makes that view real. With the Shifter gateway, targeting and session go in the credentials against p.shifter.io:443:

customer-USERNAME-country-fr-sid-promo-fr-01-ttl-600:PASSWORD

country-fr sets the market, sid-promo-fr-01 holds one exit for the duration of a category walk so the pricing you read is internally consistent, and ttl-600 keeps it for ten minutes. Rotating mid-crawl is how you end up comparing two markets’ prices inside one record.

Keep concurrency modest and back off rather than retrying through errors, as covered in rate limiting and request throttling. The product view is on the e-commerce data collection page.

What the event data actually tells you

Once promotions are events, the analysis becomes straightforward and genuinely decision-useful.

Cadence per competitor. How often they promote, and whether the interval is regular enough to anticipate. Some competitors run a discoverable fortnightly rhythm.

Depth distribution. Their typical discount, their maximum, and which categories get the deep cuts. This is the number your own pricing committee actually wants.

Duration. How long offers run, which separates genuine clearance from a permanent fake sale where the strike-through price never applies.

Lead or follow. Whether a competitor consistently moves before or after you. This is only visible with timestamps precise enough to order events, which is another argument for interval discipline.

Calendar clustering. Which weeks concentrate activity, so your own planning stops being reactive.

FAQ

How often do I need to collect to catch flash sales?

Shorter than the flash sale. For a watchlist where hours matter, that means hourly or better on a small set of items, not on your whole catalogue. Sizing the watchlist is the real decision.

How do I establish the base price?

Track it as a separate slow-moving series rather than using the previous observation. Using last week’s price as the base makes a second consecutive discount look like no discount.

Do I need to add items to a cart to catch cart-level offers?

For the mechanisms that only appear at cart, some form of checkout-stage observation is the only way to see them. Keep that to a small deliberate set, respect the site’s terms, and never complete a transaction.

Is a strike-through price reliable as the base?

Not always. Some retailers show a reference price that the item has not sold at recently. Keep your own observed base price alongside theirs and note when they disagree, since the gap is itself a finding.

The bottom line

Promotion tracking fails when it is treated as a query over price history. Promotions are events with a mechanism, a depth, a duration and a market, and most of that information is not in the price field at all.

Capture badges, strike-throughs and stated end times alongside the price, derive events with explicit confidence about their boundaries, sample faster than the promotions you care about on the items that justify it, and collect from every market you sell in. Rates are on the pricing page.

Ready to get started?

Try Shifter's residential proxies, 205M+ IPs, 195+ countries, from $0.10/GB.

Get Started