How Actowiz Solutions captured UK grocery loyalty pricing — Clubcard, Nectar & More Card prices as distinct fields across Tesco, Sainsbury's & Morrisons, with stable IDs.
A pricing-intelligence business building a product around UK grocery — the market where, more than almost anywhere, the loyalty price has quietly become the real price. When the majority of a supermarket's promotional volume moves at Clubcard Price, Nectar Price, or More Card Price, a dataset that captures only the standard shelf price is describing a market that increasingly doesn't exist at the till. The client understood this precisely, which is why their engagement with Actowiz Solutions began not with a full production order but with a sample — a verification step before commercial scoping, targeting the exact field that makes or breaks UK grocery data: member pricing, captured correctly.
This case study is worth documenting for two reasons: it's a clinic in what UK grocery pricing data actually requires, and it shows how a sophisticated buyer de-risks a data engagement — by testing the hardest field first, and asking the one technical question most buyers forget to ask.
The client's sample brief was specific, and every specification pointed at a genuine difficulty:
The heart of the engagement: extraction logic tuned per chain to correctly identify and separate standard price, loyalty price (Clubcard/Nectar/More Card, captured with its scheme label), and promotional price — as three distinct fields, with member and promotional prices null where genuinely absent, and layered cases (member + promo on one product) represented correctly rather than flattened. This three-way model, validated against each chain's specific presentation, was exactly the field the client's sample existed to verify.
Every record delivered with the client's specified fields: product identifier, chain, product title, brand, pack size, standard price, member/loyalty price (separate, null where none), promotional price (distinguished from both), price-per-unit, direct product-page URL, stock availability, category, and capture timestamp — in the client's preferred JSON (CSV available), the complete record as specified.
The defined search terms run per chain with all matching products returned per term (not a first-page sample), plus the targeted loyalty-priced product set per chain across categories — delivered with the completeness the brief required, so the sample genuinely represented the chains' matching assortment.
Price-per-unit captured/computed consistently and, where the client needed comparison, aligned to the member price too — so loyalty-price-per-unit was comparable across the three chains, the genuinely useful comparison in a loyalty-driven market.
Rather than a marketing reassurance, we gave the client the real engineering answer their question deserved: which identifier we return (the retailer's own stable product identifier where exposed, resolved from the product URL/page), why that ID is stable across refreshes (it's the retailer's persistent product key, not a position- or session-derived value), the specific cases where it can change (product relisting, catalogue restructures) and how those are handled, and — crucially — that our recurring feeds are built to maintain a consistent internal product key that survives retailer-side changes, so the client's time series stays joinable even when a retailer reshuffles. This answer, more than the data itself, was what the sample was really testing.
Per the brief's request, the sample stated, per chain, exactly when it was crawled — capture timestamps per record and a per-chain crawl-window summary — so the client knew the data's vintage and freshness precisely, and could judge it as the point-in-time snapshot it was.
Public catalogue and pricing data only; no personal or loyalty-account data (the loyalty price is public on the product page; no member accounts, no personal data involved); GDPR-conscious posture per our compliance framework; per-record lineage.
{
"product_id": "tesco-284729103",
"id_stable": true,
"chain": "tesco",
"title": "Tesco British Semi Skimmed Milk 2 Pints 1.13L",
"brand": "Tesco",
"pack_size": "1.13L (2 pints)",
"standard_price": 1.45,
"loyalty_price": {"scheme": "Clubcard", "value": 1.25},
"promo_price": null,
"price_per_unit": {"standard": "1.28/ltr", "loyalty": "1.11/ltr"},
"url": "https://www.tesco.com/groceries/en-GB/products/284729103",
"availability": "in_stock",
"category": "Fresh Milk",
"captured_at": "2026-08-11T07:20:00+01:00"
}
| Chain | Loyalty Scheme | Crawled (window)* | Search Terms | Loyalty-Priced Set | ID Stability |
|---|---|---|---|---|---|
| Tesco | Clubcard Price | 11 Aug, 07:00–07:40 BST | 6 terms, all matches | 20+ | Retailer product key (stable) |
| Sainsbury's | Nectar Price | 11 Aug, 07:45–08:30 BST | 6 terms, all matches | 20+ | Retailer product key (stable) |
| Morrisons | More Card Price | 11 Aug, 08:35–09:15 BST | 6 terms, all matches | 20+ | Retailer product key (stable) |
Sample data — illustrative of deliverable format.
| Metric | Value* |
|---|---|
| Chains (sample) | 3 (Tesco, Sainsbury's, Morrisons) |
| Loyalty schemes captured | Clubcard, Nectar, More Card |
| Price fields per record | 3 distinct (standard / loyalty / promo) + per-unit |
| Search terms per chain | 6, all matches returned |
| Loyalty-priced verification set | 20+ per chain |
| ID stability | Retailer product key, consistent-key maintained across refreshes |
| Delivery | JSON (client schema) + crawl-transparency metadata |
| Time to sample delivery | Days |
Representative engagement figures — illustrative of project structure.
The client got exactly what a well-designed sample delivers: verification of the hard thing. The three-way price model — standard, loyalty, and promotional as distinct, correctly-populated fields across three different loyalty schemes and three different site structures — was proven on their own specified search terms and loyalty-priced set. This was the field their entire product depended on, and the sample demonstrated it worked, per chain, with the null-handling and layered-case correctness that separates a usable loyalty-price dataset from a misleading one.
The ID-stability answer was, by the client's own framing, the deciding factor. Because we answered it honestly and specifically — which ID, why it's stable, when it can change, and how our consistent-key approach protects their time series through retailer-side changes — the client could scope their production time series with confidence rather than discovering an ID-drift problem three months into a longitudinal dataset. That honesty, delivered at the sample stage, is what earns the production engagement: a buyer scoping recurring price data is really buying reliability over time, and the sample proved it.
The crawl-transparency metadata closed the loop: the client knew precisely when each chain was captured and could judge the sample as the point-in-time reference it was. The sample did its job — it verified the pipeline on the client's terms — and set up the commercial scoping for the full production programme (more UK chains, Aldi/Lidl coverage, with and without member pricing) on a foundation of demonstrated capability rather than promised capability.
UK grocery — and increasingly grocery markets everywhere with loyalty-tiered pricing — cannot be understood without capturing member pricing correctly, as a field distinct from standard and promotional price. And any recurring price dataset lives or dies on identifier stability. The transferable design: a rigorous multi-way price model tuned per retailer's presentation, complete search-driven collection, price-per-unit across price types, an honest and engineered answer to ID stability, and crawl-transparency metadata — proven on a sample before production. The loyalty price is the real price now; capturing it correctly, with joinable IDs over time, is the whole game.
Because in UK grocery the loyalty price (Clubcard, Nectar, More Card) is increasingly the price most volume actually transacts at — and collapsing it into a single "price" field destroys the exact signal that matters. Standard, loyalty, and promotional must be three distinct, correctly-populated fields.
We return the retailer's persistent product key (resolved from the product page/URL) and maintain a consistent internal key across refreshes, so the same product carries the same ID week to week — the prerequisite for any price time series. Cases where retailer IDs can change (relisting, restructures) are handled to preserve joinability.
No — the loyalty price is displayed publicly on the product page. No member accounts, no personal data; public catalogue and pricing data only, handled per our compliance framework.
Yes — the same model extends across UK chains including Aldi and Lidl, with and without member pricing. This sample is the verification step before that production scope. Contact Actowiz Solutions to scope UK grocery price coverage.
Our web scraping expertise is relied on by 4,000+ global enterprises including Zomato, Tata Consumer, Subway, and Expedia — helping them turn web data into growth.
Watch how businesses like yours are using Actowiz data to drive growth.
From Zomato to Expedia — see why global leaders trust us with their data.
Backed by automation, data volume, and enterprise-grade scale — we help businesses from startups to Fortune 500s extract competitive insights across the USA, UK, UAE, and beyond.
We partner with agencies, system integrators, and technology platforms to deliver end-to-end solutions across the retail and digital shelf ecosystem.
Track the US Grocery Price Inflation Tracker 2026 to monitor food price trends, category changes, and inflation insights for smarter decisions.
Discover how Sobeys and Walmart retail data scraping helps brands track prices, products, promotions, and assortment for smarter retail decisions.
Zomato Restaurant & Menu Data Intelligence Report 2026 reveals restaurant, menu, pricing, ratings, and food delivery trends for smarter decisions.
Whether you're a startup or a Fortune 500 — we have the right plan for your data needs.