Skip to article

Price intelligence data · Matching and history

Build a price monitoring dataset around offers, not pages.

Design a price monitoring dataset with separate product, variant, listing, offer, and observation grains, evidence-based matching, price and availability semantics, history, and QA.

Published August 25, 202624 min readBy DanielReviewed by Alexandra

A dependable product price monitoring dataset keeps the product family, sellable variant, retailer listing, seller-and-market offer, dated observation, and detected change as related but different records.

A product family is not a sellable variant. A variant is not an offer. Price is a dated offer claim, not a product attribute. A missing page is not proof of an out-of-stock offer. These boundaries prevent false product matches, mixed pack comparisons, invented stock events, and price histories that silently combine different sellers or purchase conditions.

The useful output is a versioned evidence system, not a one-price-per-URL spreadsheet. It records the sellable item, seller, channel, market, terms, observation time, and unresolved evidence.

Price monitoring dataset: the short answer

Record grain · linked commercial identitiesCompare the variant; observe the offer; preserve the source listing.
Six grains · one evidence chain
  1. 01

    Product family

    product_family_id

    The shared model or commercial family, before color, size, capacity, or pack differences.

    Useful for rollups and labeled ranges; too broad for a like-for-like offer comparison.

  2. 02

    Sellable variant

    trade_item_id

    The exact color, size, capacity, pack, or other orderable trade item.

    The comparison grain for like-for-like pricing.

  3. 03

    Source listing

    source_listing_id

    One retailer page or source-scoped product record, including its native SKU and URL.

    A page can represent several sellers or buying options.

  4. 04

    Market offer

    offer_id

    One seller, channel, region, destination, quantity, and purchasing condition.

    The same listing can expose offers that are not interchangeable.

  5. 05

    Observation

    observation_id

    A dated capture of displayed price, terms, availability, and supporting evidence.

    A failed request is a collection-attempt outcome, not a product or offer observation or a market event.

  6. 06

    Change event

    offer_event_id

    A typed difference derived from before-and-after observations under a versioned rule.

    A parser correction is not a retailer price or availability change.

Offer claim · promotion

Promotion is a typed condition, not a cheaper product.

Attach coupon, membership, subscription, bundle, quantity, and validity terms to the offer observation. Store each promotional amount as a typed claim while preserving any public or reference amount; do not create a new variant.

Offer claim · availability

Availability belongs to seller, channel, destination, and time.

“In stock” for one postcode or fulfillment method does not establish universal stock. Preserve the scope and the literal evidence that supported the state.

Build the dataset in this order:

  1. Define the decision, named markets, included sellers and channels, eligible products, comparison basis, cadence, and tolerated delay.
  2. Separate product family, sellable variant or trade item, retailer listing, offer, observation, and change-event grains; derive each change event from observations under a versioned policy.
  3. Register each source with its access basis, seller identity, regional scope, rights, fields, cadence, and known blind spots.
  4. Assign stable internal IDs while retaining source-scoped listing keys, GTINs, MPNs, SKUs, URLs, and every identity decision.
  5. Preserve source-native titles, attributes, pack text, prices, availability, shipping terms, and timestamps before normalization.
  6. Match variants with positive evidence and hard conflicts; do not let a similar title override incompatible size, count, condition, or model.
  7. Model multipacks, bundles, subscriptions, refurbished items, and marketplace sellers explicitly rather than hiding them in a product name.
  8. Store active, reference, sale, member, coupon, subscription, installment, tax, and shipping amounts as separate typed claims.
  9. Normalize currency and units only through documented rules, retaining the original value and the inputs behind every derived comparison.
  10. Derive availability from explicit source evidence and successful observations, never from a request failure or one disappeared page.
  11. Keep append-only observations and reproducible events so corrections do not masquerade as retailer price changes.
  12. Test collection, extraction, identity, offer semantics, availability, history, and delivery against representative labeled cases.
  13. Publish dated snapshots, history, deltas, manifests, quality results, and limitations with stable replay semantics.
  14. Approve access, licensing, attribution, media, personal-data, retention, and comparison-claim controls before recurring collection.

Use this guide when you are designing the operational model. If you need a maintained feed for specified competitors, products, markets, fields, refresh rates, and delivery, use the managed product price and stock monitoring service. If you want to analyze one already published public data edition in Python, the retail product prices walkthrough is a snapshot-analysis recipe, not the recurring collection and history model described here.

Define the decision, market, and source universe

“Monitor competitor prices” is a theme, not a specification. A merchandising team may compare current advertised prices for directly substitutable variants. A procurement team may follow distributor pack prices. A brand may audit channel availability. A promotion analyst may need reference-price and sale-window evidence. Each question creates a different eligible population and a different definition of a meaningful change.

Write a decision contract before selecting sources:

Questions and bounded examples for a price monitoring dataset decision contract
Contract itemQuestionBounded example
DecisionWhat action will this evidence support?Review same-variant advertised price gaps each morning
MarketWhich country, currency, tax region, delivery area, or store?Named online storefront delivered to one postal region
UniverseWhich sellers, channels, categories, and conditions qualify?First-party new items from five named retailers
GrainFamily, variant, listing, offer, or observation?One retailer offer for one matched variant per observation
Comparable amountWhich charges and eligibility conditions belong in comparison?Public active item price and separately reported standard shipping
FreshnessHow late may an observation or alert be?Daily successful coverage before a documented cutoff
ExclusionsWhat must never be inferred?No stock quantity, checkout total, or market index from page display alone

Describe the universe as an intersection: named sources, sellers, storefronts, countries or delivery regions, store locations, product taxonomy, brands, identifier coverage, item condition, fulfillment modes, customer eligibility, and time window. “All online prices” has no measurable denominator. “Public offers observed on five named storefronts for successfully collected catalog partitions” is narrower but auditable.

A source partition is the smallest collection slice whose success and completeness can be assessed independently—for example, one storefront, seller type, region, category, pagination path, and crawl window. Record caps, login gates, geolocation behavior, cookie state, dynamic availability, personalization, and delivery-postcode assumptions. An empty partition can mean no eligible offers, an access denial, a source redesign, or a collector defect. Preserve those states separately.

Store-level projects need a stable seller and location model. A retailer name, marketplace seller, franchise, branch, fulfillment warehouse, pickup location, and delivery market are not interchangeable. The business location data guide explains how to preserve source identity and location evidence; use that discipline where an offer changes by store or delivery area.

Separate product family, variant, listing, offer, and observation

The central modeling decision is record grain:

  • Product family: a conceptual model or group whose members vary by declared dimensions such as color, size, capacity, flavor, or finish.
  • Sellable variant or trade item: the exact configuration a customer can select, order, or receive, including condition and declared pack configuration.
  • Retailer listing: one publisher's product page, catalog entry, feed row, or source record, identified within that publisher's namespace.
  • Offer: commercial terms from a seller through a channel for a variant, region, customer class, fulfillment mode, and time.
  • Observation: what the collector successfully saw about that listing and offer at a recorded time, with source evidence and collector context.
  • Change event: a typed difference or source event derived from observations under a versioned policy.

One family can contain many sellable variants. One variant can appear in many retailer listings. A marketplace listing can expose offers from several sellers. One seller can quote different prices for delivery, pickup, membership, subscription, or regions. One observation may see only part of that state. Model the relationships instead of flattening them into one mutable row.

Schema.org ProductGroup provides hasVariant, variesBy, and productGroupID, while a Schema.org Product can point back with isVariantOf. Its Offer vocabulary can represent commercial terms including price, price currency, availability, seller, and eligible conditions. These are useful web-publishing concepts, not evidence that every page implements them, that visible markup is current, or that one offer covers every seller and region.

Keep separate tables or equivalent event-stream entities:

  • product_families hold the conceptual grouping and the attributes on which members vary;
  • variants hold stable internal identity, manufacturer assertions, exact attributes, condition, and pack definition;
  • source_listings hold source, source key, URL history, source-native identifiers, title, and represented variant match;
  • sellers, channels, and markets define who offers what, where, and under which fulfillment context;
  • offers hold stable seller, variant, market, channel, fulfillment, quantity, condition, and eligibility identity;
  • offer_claims hold each typed price, tax, shipping, promotion, or availability assertion with source text, observation, eligibility, and stated effective interval;
  • identifier_aliases hold scoped GTIN, MPN, SKU, offer-ID, and URL claims with issuer, namespace, validity, verification, and evidence;
  • match_decisions hold candidate pairs, compared evidence, hard conflicts, rule or model version, outcome, reviewer, and decision time;
  • collection_attempts hold attempted time, request context, outcome, and failure evidence;
  • observations hold successfully extracted source claims, linked collection attempt, raw-evidence reference, and parser version;
  • offer_events hold price, promotion, availability, seller, URL, or identity changes with derivation provenance.

Do not require every listing to resolve to a variant before publication. Retain an unresolved or ambiguous source listing with its evidence. A false match blends two products' price histories; an unresolved record can be revisited when a better identifier or attribute arrives.

Google's product variant structured-data guidance illustrates a publisher-side family and variant distinction: a group declares its varying properties, variants carry unique identifiers in markup, and each variant must be directly selectable through a distinct URL state for Google's feature. Treat that as Google-specific publishing guidance. It does not prove that a URL outside that implementation represents one variant or that every visible selection was collected.

Register sources, rights, and coverage limits

A source register should state what the source asserts, how it may be accessed, and which uses are permitted. Record the owner, entry point, authentication, approved method, expected cadence, rate limits, geographic behavior, seller model, subject grain, identifiers, field scope, terms, license, attribution, retention, redistribution, media rules, and operational owner.

Standards and structured-data vocabularies are not product feeds or reuse licenses. Schema.org describes a vocabulary. GS1 defines identification rules. Google documents requirements for its products. None grants access to a retailer's data or establishes rights to retain, combine, publish, or use the source for automated comparison.

Assign field authority locally. A manufacturer page may be strongest for a model specification. A brand-issued GTIN can identify a trade item within GS1's scope. A retailer directly asserts its listing, advertised price, promotion text, and seller attribution. A delivery quote may supply a destination-specific charge. A marketplace page may aggregate several sellers. One source rarely establishes all fields.

For every run, preserve enough evidence to distinguish:

  • a successfully observed listing and offer;
  • an explicitly unavailable, out-of-stock, preorder, or backorder claim;
  • a successful catalog partition in which a listing was absent;
  • a changed URL, redirected identifier, or seller substitution;
  • a login wall, consent block, throttle, timeout, partial render, parser failure, or challenge;
  • a source-wide change in totals, filters, pagination, markup, or regional behavior.

Only apply absence logic to successfully covered partitions. If a retailer caps category results or personalizes delivery availability, “not returned” is not equivalent to “not offered.” Retain the source-native payload or the minimum permitted evidence, plus source, URL or key, attempted time, request market, response state, content hash where available, collector or extractor version, and extracted values only when an observation succeeded. A hash supports byte comparison; it does not prove truth, completeness, identity, or permission.

Design stable product and offer identifiers

Create opaque internal IDs for families, variants, listings, sellers, markets, offers, observations, and events. Identity persistence is grain-specific: family and variant IDs may survive title, URL, and image changes; source-listing IDs can retain URL history; offer IDs may survive price, promotion, availability, and parser changes only while seller, variant, channel or market, fulfillment, condition, eligibility, and quantity identity remain stable. Do not build a permanent variant ID from mutable presentation text.

Store every external identifier as a scoped alias: scheme or issuer, namespace, entity grain, value, source, market if relevant, observed interval, verification state, and evidence. A manufacturer part number is manufacturer-scoped. A retailer SKU is retailer-scoped and may refer to a listing, an assortment, or a fulfillment item under that retailer's rules. A marketplace offer ID may identify a seller's terms rather than the product. A URL is a locator whose query parameters can encode variant, region, or campaign state.

The GS1 GTIN Management Standard describes a GTIN as identifying a trade item that may be priced, ordered, or invoiced in a supply chain. It requires new GTINs for new products and gives variant and pack-level cases where distinct identification is needed; its rules also address changes such as declared net content and pack quantity. A GTIN whose structure, GS1 assignment, represented trade item, and packaging level have been verified is strong evidence for that documented scope; a correct length and check digit alone establish only that the number is correctly composed. Verified by GS1 can return assignment and available product or company information, but the GTIN is not a universal product-family, seller-offer, or listing ID, and it does not guarantee that a retailer's claim is correct.

Never silently “repair” identifiers by dropping leading zeros, converting them to numbers, or accepting a check-digit failure. Preserve the source string and a validation outcome. Store any scheme-defined canonical form separately and compare canonical forms before declaring a GTIN conflict; never overwrite the exact source representation. Keep multiple claimed GTINs, MPNs, and SKUs when sources disagree. Resolve the current preferred alias through a versioned decision without rewriting historical observations.

An offer identity needs more than variant ID. At minimum consider seller, channel or storefront, market or delivery region, fulfillment mode, item condition, customer eligibility, quantity basis, and source listing. Treat those dimensions as offer-identity constraints. Preserve a verified seller rename or alias through a resolution event; otherwise create a related offer when the seller or another identity-defining dimension changes. Keep redirects, replacements, and listing lineage explicit.

Match products with evidence and hard conflicts

Identity resolution · evidence with vetoesA probable match is never permission to ignore a hard variant conflict.
Evidence types, identities supported, limitations, and hard conflicts for retail product and offer matching
EvidenceWhat it supportsWhat it cannot proveHard conflict
01GTIN (including UPC/EAN encodings)Strong candidate for a specific trade item and packaging level when assignment is verifiedThat a check-digit-valid code is correctly assigned or that offer terms matchDifferent verified, canonically unequal GTINs for the same claimed packaging level, absent a documented replacement or hierarchy relationship
02Brand + MPNManufacturer model or variant candidatePack, color, size, region, or bundle equivalenceDifferent normalized manufacturer part numbers for the same claimed variant
03Source SKUStrong source-scoped continuity evidence within one retailer or seller, subject to its reuse rulesIdentity across merchants or after SKU reuseOne live SKU resolves to incompatible variant attributes
04Variant attributesColor, size, capacity, flavor, configuration, or editionBrand ownership or exact pack compositionIncompatible order-defining attribute such as 128 GB versus 256 GB
05Pack quantity + unitComparable count, mass, volume, or length basisA match when units or included items remain unknownSingle item versus multipack, or incompatible normalized quantity
06Image + text fingerprintsA corroborating candidate when captured near the same timeExact trade-item identity by themselvesFingerprint reused across visibly incompatible products
07Seller + observation timeWhether offers coexist, succeed one another, or represent a marketplace sellerProduct identity without item evidenceSupposed duplicates are distinct live seller offers or time periods
accepted
Evidence meets the versioned rule and no hard conflict remains.
rejected
A hard conflict or reviewed evidence establishes distinct variants.
ambiguous
A plausible match exists, but accepting it would be unsafe without more evidence or review.
unreviewed
The candidate has not passed an automated rule or human review.

Store the decision, evidence IDs, matcher version, thresholds, reviewer where applicable, and effective time. A score without its evidence trail is not an auditable identity.

Product matching should produce an auditable decision, not merely a similarity score. Start with blocking rules that generate plausible candidates, then compare evidence at the sellable-variant grain. Candidate features may include validated GTIN, manufacturer and MPN pair, brand, model, normalized title tokens, exact variant attributes, dimensions, declared net content, pack count, compatible category, source-native structured data, and permitted image fingerprints.

Apply hard conflicts before fuzzy similarity. Examples include different verified, canonically unequal GTINs for the same claimed packaging level with no documented replacement or hierarchy relationship, incompatible model numbers, different size or color where those define a variant, new versus refurbished condition, single item versus multipack, conflicting voltage or region, and a bundled accessory absent from the candidate. A high title score must not override a conflict that changes what the buyer receives.

Use explicit match states:

  1. Accepted: the evidence meets a versioned rule for the same sellable variant.
  2. Rejected: the records refer to distinct variants or violate a hard constraint.
  3. Ambiguous: a plausible match exists, but accepting it would be unsafe.
  4. Unreviewed: the candidate has not passed an automated rule or human review.

Store both compared records, source values, normalized features, missingness, candidate rule, hard conflicts, score components, decision rule or model version, threshold, outcome, reason codes, reviewer, and decision time. A single confidence number is not enough to reproduce why two listings were joined.

Use identity inheritance cautiously. If a retailer family page contains several selectable variants, a family-level brand or model may apply to all children, while price, availability, GTIN, seller SKU, image, or pack text may change with the selected option. Record which page state was selected and which claims were inherited. Do not copy one observed variant's offer onto its siblings.

Evaluate matching on labeled pairs that reflect the real catalog: near-identical titles, missing GTINs, regional model suffixes, multipacks, refurbished items, private-label equivalents, marketplace duplicates, and variant selectors. Report precision and recall by category, brand, source pair, identifier coverage, and conflict type. Optimize false merges aggressively because one false merge fabricates a price comparison; track false splits too because they hide genuine competitor coverage.

Model bundles, packs, and variants explicitly

A shopper can buy a 500-millilitre bottle, a two-pack of that bottle, a mixed bundle, a refill, or a subscription. They may share a brand and marketing name while differing in quantity, included items, packaging hierarchy, condition, or purchase commitment. Treat these distinctions as data, not title cleanup.

For a simple item, store the base product kind, declared amount, unit, and count. For a multipack, store units per pack, amount per unit, total amount, and whether the packaging itself has an identifier. For a bundle, model component variant, quantity, required or optional status, and bundle-level seller terms. For a set with unknown components, retain the source description and mark the composition unresolved rather than inventing a total.

Make variant-defining dimensions category-aware. Apparel may vary by size and color. Electronics may vary by capacity, connectivity, voltage, or regional model. Food may vary by flavor, net content, count, or formulation. Furniture may vary by finish and dimensions. Keep source-native attributes, then map them through a versioned taxonomy with exact, broader, narrower, related, and unmapped outcomes.

Condition and fulfillment deserve first-class fields. New, used, refurbished, open-box, rental, digital, and physical items are not direct equivalents. Delivery, pickup, marketplace fulfillment, backorder, preorder, and made-to-order can change both price and availability meaning. If the decision contract excludes a class, retain the observed class as an exclusion reason rather than deleting the evidence silently.

Comparisons should state their basis: exact variant, compatible substitute, family-level range, identical declared quantity, or normalized unit basis. Never label a family minimum as the price of every variant, and never compare a bundle total with a single item without making the quantity transformation visible.

Separate active, reference, member, and promotional prices

Offer semantics · one illustrative captureKeep the displayed price separate from every condition that changes its meaning.
Currency EURDestination 10115 · DEObserved 12 Aug · 08:00
Claim 01

Active per-pack price

source

€24.00 / six-pack

Displayed per-pack amount; the minimum order is two six-packs, so the minimum item total is €48 before shipping.

Claim 02

Reference price

source

€30.00 / six-pack

Strikethrough or comparison value; preserve the source label and validity context.

Claim 03

Member / coupon

source

€21.60 / six-pack with code MEMBER10

Conditional price; membership and coupon requirements stay attached.

Claim 04

Subscription

source

€20.40 / six-pack on recurring delivery

A separate buying condition, not the default active price.

Claim 05

Tax

source

VAT included

Literal inclusion claim for the observed destination.

Claim 06

Shipping

source

€4.90 below €50 basket

Basket- and destination-dependent charge; not silently folded into item price.

Claim 07

Minimum quantity

source

2 six-packs

The lowest eligible order quantity for this offer.

Claim 08

Unit price

derived

€0.40 / 100 ml

€48.00 ÷ 12,000 ml × 100 ml, using the minimum order of two six-packs of 1 L bottles.

Source fields
Literal price text, promotion copy, tax and shipping statements, currency, destination, capture time, and evidence reference.
Normalized fields
Typed amounts and conditions produced by a named parser version while the source values remain intact.
Derived fields
Unit price, discount percentage, landed estimate, and comparable basis with formula, inputs, and rounding rule.

One offer can display several amounts simultaneously. Store each as a typed, dated claim rather than choosing one generic price column:

  • Active public price: the currently advertised amount for the stated market and quantity, before any separately modeled charges.
  • Reference or regular price: a crossed-out, list, was, recommended, or prior amount with its exact source label.
  • Sale price: a promotional active amount, with stated start and end times when available.
  • Member or loyalty price: an amount conditional on enrollment, tier, account, or other eligibility.
  • Coupon price or discount: a code, clip, basket, rebate, or post-purchase condition whose redemption is not guaranteed.
  • Subscription price: an amount conditional on recurring purchase, schedule, or cancellation terms.
  • Installment terms: payment count, amount, deposit, financing conditions, and any separately stated total.

Preserve the source display text and label. “From,” “starting at,” “up to,” “save,” and “as low as” do not become exact prices through parsing. Keep ranges as lower and upper bounds. Keep percentage, fixed-amount, multi-buy, and gift promotions in separate structures with prerequisites and affected quantities.

Google's Merchant Center product data specification separates price, sale price, sale-price effective dates, loyalty programs, subscriptions, installments, and unit-pricing measures. Those are Google platform semantics and requirements, not a universal ontology. Use them as useful examples, while preserving each retailer's native labels and the rules in the target market.

Google's merchant listing structured-data documentation places an Offer under a Product and requires the merchant to be the seller for eligibility. That reinforces the product-versus-offer boundary, but markup remains a publisher claim rather than proof of checkout terms.

Price changes need typed causes. A retailer may change the active amount, start or end a sale, alter a member condition, replace a seller, change tax display, or correct a page. The pipeline may also fix a parser. A source-observed change and a processing correction must never share one event type.

Normalize currency, tax, shipping, and unit price

Keep the original amount string, parsed decimal, currency claim, amount type, seller, market, quantity basis, source, observation time, and parse status. Use decimal arithmetic. Do not infer a currency solely from a symbol when several currencies share it; use page locale, explicit code, storefront, and source evidence under a documented rule, or leave the value unresolved.

Tax treatment varies by jurisdiction, customer, and channel. Record whether the source says tax is included, excluded, estimated, or unknown, and which tax or region that claim concerns. Google Merchant Center itself documents different price-tax submission rules for the United States and Canada versus other target countries. That is a Google-specific platform rule, but it demonstrates why one global “tax included” assumption is unsafe.

Shipping is not one scalar property of a product. It may depend on destination, seller, cart total, membership, speed, weight, pickup choice, surcharge, and time. Store shipping method, destination context, amount, currency, threshold, eligibility, estimated window, and observed time. If the page only says “calculated at checkout,” preserve that state. Do not turn a product-page price into a delivered or checkout price without a reproducible quote for the same context.

Unit price is derived from a compatible item amount and declared measure. Retain the source measure, count, unit, denominator, conversion rule, and resulting value. The UNECE code-list recommendations include Recommendation 20 codes for units of measure used in international trade. A controlled code can improve interchange, but it does not repair ambiguous source text or determine whether gross, net, drained, usable, or per-item quantity is intended.

For every conversion, retain the original values. A volume-to-mass conversion requires a justified density and normally should not be assumed. Count-based and weight-based prices are not interchangeable. “Each,” “pair,” “sheet,” “dose,” and “serving” need category context. A pack of six 330-millilitre cans can yield a price per litre only when both count and per-unit volume are established.

Currency conversion is another derived layer. Record the rate provider, rate timestamp or date, base and quote currencies, rate type, rounding policy, and calculation version. Do not overwrite the observed amount. For historical comparisons, decide whether to use observation-date rates, period-average rates, or no conversion at all, and label the result.

Publish at least three comparison fields when needed: observed item price, derived unit price, and a separately constructed delivered-price estimate. Each needs eligibility and quality flags. None should be described as the checkout total unless an actual checkout-context quote establishes that claim.

Track availability without inventing stock

Availability ledger · ordered evidenceCapture failures, page removals, and stock changes are different events.
Illustrative source history
Ordered observations, preserved evidence, ledger actions, and interpretations for a retail offer
ObservedSource signalPreserved evidenceLedger actionInterpretation
108:00 · 12 AugProduct page loads; “In stock” and delivery date shown200 response · evidence E-101 · postcode 10115Set observed availability to in_stockExplicit offer claim for one destination and capture time
208:00 · 13 AugMember coupon appears: €21.60 with code MEMBER10; public active price remains €24.00200 response · evidence E-118 · eligibility terms capturedAppend conditional-promotion event; keep active price unchangedSame offer; eligibility terms changed
308:00 · 14 AugCollector times out before page content arrivesTimeout · request log R-144 · no page evidenceRecord capture_failed; carry no new stock stateOperational failure is not an out-of-stock event
408:07 · 14 AugRetry loads; explicit “Out of stock” message200 response · evidence E-145 · destination unchangedAppend explicit out_of_stock observationSource evidence supports a scoped availability change
508:00 · 16 AugKnown URL returns a branded not-found page404 response · evidence E-173 · redirect chain retainedRecord page_missing for this capture; keep offer status unchanged pending policy evidenceMissing page does not prove discontinued product or universal unavailability
609:20 · 24 AugA candidate for the same variant appears at a new retailer URLNew URL and SKU · matching evidence E-221 · in-stock textCreate a new source listing; link as a replacement or continuity candidatePreserve both URL histories and the identity decision

The latest successful observation can remain the latest known source claim while its freshness decays. Never convert a timeout into stock, a 404 into discontinuation, or a new URL into continuity without explicit evidence.

Availability is an offer claim under a specific context, not a warehouse count. Preserve source-native text and map it conservatively to classes such as available, unavailable, preorder, backorder, limited, made to order, pickup only, delivery only, unknown, and not observed. Keep seller, variant, market, destination, store, fulfillment mode, and observation time attached.

Google Merchant Center's specification uses in_stock, out_of_stock, preorder, and backorder values and tells participating merchants to align availability across their feed, landing page, checkout, and structured data. Those values are Google-specific submission semantics. A monitored page may use different labels, and a collector usually cannot verify the seller's physical inventory.

Distinguish four evidence states:

  1. Explicit availability: the source successfully displayed a recognizable state for the selected variant and context.
  2. Successful unknown: the page loaded, but no supported availability claim could be extracted.
  3. Successfully absent: the listing was not present within a demonstrably completed source partition.
  4. Collection unavailable: access, rendering, selection, request, or parsing failed.

A missing page is not proof of an out-of-stock offer. The item may have moved, been delisted, changed identifiers, become region-restricted, disappeared from a capped result set, or encountered a collection failure. Record a disappearance or absence event. Only map it to an inactive offer under a versioned, source-specific rule with successful coverage and an appropriate observation window.

Do not infer inventory quantity from “in stock,” delivery speed, purchase limits, urgency text, or a successful add-to-cart interaction. “Only three left” is a source claim if explicitly shown; it is not independently verified stock. Preserve the phrase, quantity claim, context, and timestamp, then decide whether the intended use permits publication.

Reappearance should reopen the prior offer or create a linked replacement under the identity policy. Preserve the gap: observations can bound a state, but they cannot establish what happened between checks.

Preserve price, promotion, and availability history

An overwrite-only table answers “what does the latest parser believe?” but cannot answer when an offer changed, how long a promotion appeared, or whether a correction altered history. Keep append-only observations as the evidence layer and derive current views and events from them.

Every collection attempt should carry source, listing or partition, market and destination context, attempted timestamp, request outcome, failure evidence, and collector version. A successful observation should link to that attempt and carry the selected variant, seller, observed timestamp, source timestamps if present, raw-evidence reference, parser version, extracted claims, and content or field hashes. Deduplicate retries through stable attempt and observation keys without collapsing genuinely distinct observations.

Keep the clocks separate:

  • source time: when a retailer says a price, promotion, listing, or availability state applies;
  • observed time: when the collector successfully saw the claim;
  • processed time: when extraction and normalization ran;
  • decision time: when a match or derived event was accepted;
  • effective time: the interval a derived current view assigns under its policy;
  • publication time: when a dataset release became available to consumers.

A first observation is not necessarily a promotion start. A last observation is not necessarily its end. If the source supplies an effective interval, retain it as a source claim and compare it with observations. Otherwise label first-seen and last-seen bounds; do not manufacture exact campaign dates.

Create typed events only when a versioned comparison rule supports them: active-price claim changed, reference price first observed, sale first observed, sale no longer observed, member terms changed, availability claim changed, seller offer appeared or disappeared, listing redirected, variant match corrected, parser corrected, or record suppressed. Reserve sale_started and sale_ended for explicit source-effective intervals; otherwise retain first-seen and last-seen bounds. Store the before and after observations, compared fields, tolerance, policy version, reason, and event-generation time.

Numeric equality alone can hide semantic change. The same amount can move from a public price to a member price, tax display can change, or the pack count can change. Conversely, a presentation rewrite or rounding change may not meet the project's material-change rule. Compare the complete typed offer context.

The monitoring runbook describes schedules, incidents, staleness, and recovery states. Apply those operational controls per source partition before deriving business events. Reprocessing old observations under an improved parser should emit a correction or restatement, not a fictional historical retailer change.

Distinguish market observations from price indices

A recurring dataset of observed offers is not automatically a market price index. Its records reflect the included retailers, successfully covered partitions, matched variants, visible sellers, regions, observation schedule, and price-eligibility rules. Assortment changes and collection incidents can move a simple average even when no continuing item's price changed.

Before computing an index, define the target population, sampling frame, item and outlet weights, comparable item specification, substitutions, new and disappearing products, promotions, seasonal products, quality change, missing observations, tax and shipping treatment, aggregation formula, base period, revision policy, and uncertainty. Those are statistical design decisions beyond collection.

Publish descriptive measures with their denominators: exact-variant offer count, matched retailer count, observation window, coverage rate, unresolved-match rate, and promotion inclusion. Label an unweighted median of observed offers exactly that. Do not call it representative of a country, category, or consumer experience without a defensible sampling and weighting design.

The retail product prices Python guide demonstrates how to analyze a specific public snapshot while keeping its edition, source currency, coverage, and observation dates visible. It does not convert that snapshot into a live feed or a representative price index, and it should not be used as a substitute for the operational evidence model in this guide.

Measure quality at each boundary

Release control · six decision boundariesGate the evidence, identity, semantics, history, and delivery—not just the row.
Pass · review · quarantine
  1. 01

    Source

    Pass
    Expected retailers, regions, pages, and cadence are observed; access basis and retention or redistribution permissions are documented and approved for this scope.
    Review
    Layout, response mix, or coverage crosses a documented threshold, or terms or access conditions change.
    Quarantine
    Rights are unclear, evidence cannot be retained, or a source partition is materially incomplete.
  2. 02

    Identity

    Pass
    Every accepted product, variant, listing, and offer link has evidence and no hard conflict.
    Review
    A candidate sits near threshold, identifiers disagree, or pack and variant attributes are incomplete.
    Quarantine
    A hard conflict survives resolution or a source SKU maps to incompatible live variants.
  3. 03

    Offer semantics

    Pass
    Seller, channel, destination, conditions, active price, reference price, and promotions are typed.
    Review
    Membership, coupon, subscription, bundle, or validity wording is ambiguous.
    Quarantine
    A conditional price would be published as universally available or attributed to the wrong seller.
  4. 04

    Price + unit

    Pass
    Currency, tax, shipping, quantity, unit, normalization, and derivation lineage validate.
    Review
    Displayed unit price conflicts with the computed basis or conversion requires an assumption.
    Quarantine
    Currency is unknown, pack math fails, or incomparable variants would enter the same metric.
  5. 05

    Availability + history

    Pass
    Availability claims, failures, removals, replacements, and freshness follow versioned temporal rules.
    Review
    Only one weak signal supports a change or observations arrive out of order.
    Quarantine
    A request failure becomes an availability event or prior evidence is overwritten instead of versioned.
  6. 06

    Delivery

    Pass
    Snapshot, delta, schema, manifest, counts, evidence links, and destination receipt reconcile.
    Review
    Freshness, match, or coverage metrics drift while record-level outputs remain usable.
    Quarantine
    The edition is partial, orphaned, stale beyond policy, or fails downstream reconciliation.

Apply outcomes at the smallest safe scope: release clean records, route uncertain records with their evidence, and exclude unsafe partitions while disclosing the gap.

Quality metrics should reveal where evidence or processing failed:

  1. Collection: expected partitions attempted and completed, response states, throttling, caps, variant-selection success, and evidence retention.
  2. Extraction: required fields found, structured-versus-visible disagreements, parser errors, source-native fidelity, and fixture regressions.
  3. Identity: candidate coverage, accepted and ambiguous rates, precision, recall, hard-conflict escapes, false merges, and review age.
  4. Variant and pack semantics: attribute-map coverage, condition, pack count, declared measure, bundle composition, and unmapped reason codes.
  5. Offer semantics: seller, market, eligibility, active and reference price labels, promotion prerequisites, currency, tax, and shipping completeness.
  6. Availability: explicit versus inferred states, successful-unknown rate, absence evidence, transition validity, reappearance, and stale records.
  7. History: ordered observations, event replay, clock completeness, correction separation, and policy-version reproducibility.
  8. Delivery: schema validation, referential integrity, counts, hashes, atomic publication, delta replay, and consumer acknowledgments.

Every rate needs a numerator, denominator, time window, filters, and exclusions. “Prices are 99% complete” is meaningless unless the eligible offer population and required components are stated. Segment metrics by source, seller type, market, category, brand, identifier coverage, variant complexity, pack form, parser version, and collection path.

Build representative gold sets for product matching, pack parsing, seller attribution, price classification, availability mapping, and change detection. Include shared family names, regional model suffixes, size and color selectors, multipacks, mixed bundles, member prices, coupon conditions, marketplace sellers, out-of-stock pages, redirects, source failures, and parser corrections. Keep evaluation examples separate from tuning.

Measure false merges and false out-of-stock classifications on high-risk segments, not only globally. Track false splits and missed availability changes separately because their harms differ.

Monitor distributions alongside pass rates: offer counts, prices by currency, active-to-reference ratios, discount depths, pack quantities, unit-price tails, seller mix, state transitions, observation gaps, match-score bands, ambiguous queues, and partition duration. Sudden shifts can expose a selector failure, consent wall, taxonomy redesign, or promotion-parser error before consumers act on bad data.

The web-scraping data-quality framework covers completeness, validity, fidelity, duplicates, freshness, and release gates. Quality must pass per source before cross-retailer comparisons are released; a perfect schema cannot compensate for a failed source partition.

Publish snapshots, history, and deltas

Publish convenient views without discarding evidence:

  • a current family and variant view with stable IDs, source aliases, and match state;
  • a current listing and offer view with seller, market, terms, availability claim, and last successful observation;
  • append-only observations and typed offer events;
  • match decisions, listing lineage, redirects, replacements, and corrections;
  • versioned snapshots, deltas, manifests, schemas, code lists, and limitation notes.

A release manifest should name the dataset and release IDs, schema and policy versions, covered source partitions, collection cutoff, files, record counts, byte counts, hashes, quality-gate results, and known incidents. Publish files to versioned locations, validate the complete release, and then atomically update the current pointer.

Define delta semantics. State whether an update replaces a complete record or named fields, how source absence differs from a deletion, how offer closure differs from item unavailability, how ID merges and splits are represented, and whether corrections restate previous releases. Use stable event IDs and sequence rules so retries are idempotent and consumers can detect gaps.

The W3C PROV overview describes provenance through the entities, activities, and people involved in producing data. Apply that discipline pragmatically: connect a published offer assertion to source evidence, the extraction and normalization activity, the matching or event decision, and the software or reviewer responsible.

Document covered sellers, markets, channels, destination assumptions, successful partitions, field freshness, match thresholds, promotion rules, missing-price reasons, availability limits, and degraded incidents in every release. The custom data feed guide covers contracts, manifests, atomic delivery, snapshots, and deltas in more detail.

Govern licenses, media, and retention

Public visibility does not settle permission to collect, retain, combine, compare, republish, or commercialize data. Review source terms, contracts, licenses, database rights, copyright, access controls, permitted fields, recipients, territories, retention, attribution, and automated-use restrictions with qualified counsel for the intended use.

Different source elements may be governed by different contractual, database, trademark, copyright, privacy, or other restrictions. Minimize collection to the decision purpose. Store identifiers, images, text, reviews, seller profiles, badges, promotional creative, or derived fingerprints only where permitted and necessary, and do not assume that a right to view a page includes a right to redistribute its contents.

Account-based or localized collection can expose personal data, tokens, addresses, saved locations, or personalized prices. Use controlled service identities where allowed, separate secrets from evidence, restrict raw captures, encrypt sensitive fields, log exports, and define deletion procedures. Label a personalized offer with its eligibility context or exclude it.

Comparison outputs require their own review. A technically accurate observation can still become misleading when tax, shipping, pack size, condition, seller, membership, time, or coverage is omitted. Define which claims may be automated, what evidence appears beside them, when human review is required, and how corrections reach consumers. This guide is an engineering framework, not legal advice or a guarantee that a comparison claim complies with a particular jurisdiction.

Set source-specific retention for raw pages, structured payloads, screenshots, media, normalized observations, and published releases. When rights change or access ends, know which artifacts must stop, expire, be suppressed, or remain solely as permitted audit evidence. WebTruffle's responsible data and security principles describe the boundaries applied to managed work.

Price monitoring dataset checklist

Before production, confirm all of the following:

  • [ ] The decision, sellers, channels, markets, product universe, customer context, cadence, delay, and exclusions are explicit.
  • [ ] Product family, sellable variant, retailer listing, seller-and-market offer, observation, and event grains are separate.
  • [ ] Internal IDs survive title, URL, price, promotion, seller, availability, and parser changes.
  • [ ] GTIN, MPN, SKU, offer ID, and URL aliases retain issuer, namespace, grain, evidence, and valid interval.
  • [ ] Accepted, rejected, ambiguous, and unreviewed product matches remain reproducible.
  • [ ] Hard conflicts cover variant attributes, pack size, bundle composition, condition, model, voltage, and region where relevant.
  • [ ] Source-native attributes, quantity text, prices, availability, seller, shipping, tax, and timestamps survive normalization.
  • [ ] Active, reference, sale, member, coupon, subscription, installment, tax, and shipping claims use separate fields.
  • [ ] Unit prices retain item quantity, denominator, unit code, conversion rule, and eligibility status.
  • [ ] Missing listings, collection failures, unknown availability, explicit out-of-stock claims, and offer closure remain distinct.
  • [ ] Source, observed, processed, decision, effective, and publication times are not substituted.
  • [ ] Price and availability events can be replayed from observations under a named policy version.
  • [ ] Matching and quality metrics publish denominators, windows, segments, exclusions, and support counts.
  • [ ] Snapshots, deltas, manifests, redirects, corrections, tombstones, replay, and atomic publication are documented.
  • [ ] Descriptive comparisons are not labeled checkout prices, inventory quantities, or representative indices without supporting evidence.
  • [ ] Source access, licenses, media rights, personal data, security, retention, attribution, correction, and claim review have owners.
  • [ ] Every published product link, offer, price, availability state, and event can be traced to source evidence and transformation history.

Frequently asked questions

What is a product price monitoring dataset?

It is a dated record of product variants, retailer listings, seller-and-market offers, advertised price components, availability claims, source evidence, and detected changes. A dependable dataset also publishes its coverage, collection context, match decisions, quality results, and limitations.

What is the difference between a product family and a variant?

A family groups related items under a model or concept. A sellable variant is the exact configuration a buyer can select, such as one size, color, capacity, condition, or pack. Compare prices at the variant grain unless the output is explicitly labeled as a family-level range.

Is a GTIN enough to match products across retailers?

A GTIN whose structure, GS1 assignment, represented trade item, and packaging level have been verified is strong evidence for that documented scope, but it is not a family, listing, seller-offer, or universal identity. Preserve the exact source string, canonical form, issuer, and evidence; handle pack levels; and use MPN, exact attributes, condition, quantity, and hard conflicts when GTIN claims are missing or disputed.

How should products without GTINs be matched?

Generate candidates from manufacturer and MPN, brand, model, category, title, exact variant attributes, declared quantity, pack composition, and permitted image evidence. Apply hard conflicts first, then store accepted, rejected, ambiguous, and unreviewed outcomes with the features and rule version.

How do I compare multipacks, bundles, and single items?

Model the pack or bundle composition first. Keep units per pack, amount per unit, total declared measure, components, and conditions. Compare exact configurations directly or publish a derived unit price with its denominator and conversion rule; do not present a bundle total as the price of a single item.

Which price should a monitoring dataset store?

Store every relevant typed claim: active public, reference, sale, member, coupon, subscription, installment, tax, shipping, and any stated effective interval. Preserve the source labels and eligibility conditions. A consumer-facing comparison should state exactly which components it includes.

Does a missing product page mean an item is out of stock?

No. A page can move, be removed, become region-restricted, change identifiers, disappear from a capped catalog, or fail to load. Record the observation or collection failure. Publish out_of_stock only from an explicit source claim; a documented absence policy may mark an offer inactive or not observed, but it must not turn absence into an out-of-stock claim.

Can monitored prices be treated as checkout prices?

Usually not. A displayed item price may omit destination-specific shipping, tax, fees, minimum quantities, membership conditions, coupons, or seller changes. Label it as an observed offer claim. Call an amount a checkout total only when a reproducible checkout context establishes that amount.

How should price and promotion history be stored?

Keep append-only observations and derive typed events from them under versioned rules. Preserve source, observed, processed, effective, decision, and publication times separately. Parser corrections should restate processed data rather than appearing as retailer price changes.

How often should competitor prices be refreshed?

The cadence follows the decision, source behavior, promotion speed, and cost of stale evidence. Define targets per source partition and separately measure schedule adherence, successful coverage, offer freshness, event latency, and publication latency. A fast schedule does not compensate for failed or partial collection.

Can publicly visible retailer prices be reused freely?

Not necessarily. Visibility alone does not resolve source terms, contracts, database rights, copyright, media permissions, privacy, attribution, retention, automated access, or comparison-law obligations. Review the exact source and intended output, minimize retained evidence, and obtain qualified legal advice where appropriate.