Canadian Grocery Price Comparison API avatar

Canadian Grocery Price Comparison API

Pricing

from $10.00 / 1,000 searches

Go to Apify Store
Canadian Grocery Price Comparison API

Canadian Grocery Price Comparison API

Compare grocery prices across 16 Canadian chains, Loblaws, Superstore, No Frills, Zehrs, Fortinos, Valu-mart, etc from one input. Get normalized product matches, prices, unit prices, sale flags, store details, product URLs, and CSV/JSON/Excel-ready output for apps, AI agents, and research.

Pricing

from $10.00 / 1,000 searches

Rating

0.0

(0)

Developer

JChaw

JChaw

Maintained by Community

Actor stats

1

Bookmarked

21

Total users

4

Monthly active users

19 hours ago

Last modified

Share

Compare Canadian grocery prices across 16 chains in one run, with every result matched, normalized and scored.

The Canadian Grocery Price Comparison API takes a grocery list and a location and returns one comparison row per item per retailer, so you can see which store is cheapest without joining four datasets yourself.

  • Loblaw Companies: Loblaws, Real Canadian Superstore, No Frills, Zehrs, Fortinos, Valu-mart, Your Independent Grocer, Provigo, Maxi, Wholesale Club, Atlantic Superstore
  • Pattison Food Group: Save-On-Foods, PriceSmart Foods, Urban Fare, Quality Foods
  • T&T Supermarket
  • Every row: matched product, retailer, store, price, sale price, normalized unit price, availability, product URL, match confidence
  • Setup: none. No API key, no account, no proxy.

Run it

Paste this into the Input tab (switch to JSON view) and hit Start:

{
"queries": ["eggs", "chicken breast", "celery"],
"location": "Vancouver, BC",
"retailers": ["loblaws", "saveonfoods", "tnt"]
}

Comparison rows stream into Output as each retailer finishes. Download from Storage → Dataset as JSON, CSV or Excel.

Three things to change from there:

  • Compare a real basket by extending queries to your weekly list
  • Move region by editing location, then naming the banners that serve it: Montréal is ["maxi", "provigo", "valumart"], Halifax is ["atlanticsuperstore", "nofrills", "independent"]
  • Add basket totals with "includeSummaries": true

From the API

Grab a token at console.apify.com/settings/integrations:

curl -X POST \
"https://api.apify.com/v2/acts/sunny_eternity~canada-grocery-price-comparison/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["eggs", "chicken breast", "celery"], "location": "Vancouver, BC", "retailers": ["loblaws", "saveonfoods", "tnt"]}'
  • run-sync-get-dataset-items suits small runs and can time out on large ones
  • For scheduled runs or large baskets, POST to /runs and read the returned defaultDatasetId
  • Official JavaScript and Python clients work too

What you get back

One query against three retailers returns one row each:

queryretailermatched productpriceunit pricesaleconfidence
eggsloblawsNo Name Large Eggs 12-pack4.490.37/eachfalsehigh
eggssaveonfoodsWestern Family Large Eggs 12-pack5.290.44/eachfalsehigh
eggstntLarge White Eggs 12-pack4.990.42/eachtruemedium

Each row in full:

{
"_type": "comparison",
"schema_version": "2026-05-compare-v1",
"query": "ground beef",
"retailer": "loblaws",
"banner": "Loblaws",
"store": "Robson Street",
"store_id": "1050",
"matched_product": "PC Lean Ground Beef",
"price": 7.99,
"unit_price": "$1.76/100g",
"comparable_unit_price": 1.76,
"comparable_unit_basis": "100g",
"sale_price": null,
"was_price": null,
"is_on_sale": false,
"availability": "in_stock",
"match_confidence": "high",
"match_score": 0.86,
"match_reasons": ["brand_match", "size_match"],
"source_url": "https://www.loblaws.ca/...",
"image_url": "https://...",
"product_id": "20123456",
"package_size": "454 g",
"selling_type": "by_weight",
"multi_buy_deal": null,
"pc_optimum_offer": null,
"category": "search:ground beef",
"country": "CA",
"currency": "CAD",
"region": "BC",
"scraped_at": "2026-05-15T14:32:11.123Z",
"run_id": "abc123"
}

Every dataset record carries a _type. Branch on it: comparison and category_browse_product are product rows, the rest are roll-ups and run metadata.

Why this Actor

  • 705 runs across the suite in the last 30 days, none ended in a failed state. Run stats are public on the Apify API; figures from August 2026.
  • One call replaces four. Running the retailer scrapers yourself leaves you with four schemas, four location systems and a matching problem. This Actor handles the fan-out, the normalization and the matching in one run.
  • Every match shows its work. match_score runs 0 to 1, match_confidence buckets it high, medium or low, and match_reasons and mismatch_reasons name the signals behind the score, such as brand agreement or a differing package size.
  • Unit prices compare across chains. comparable_unit_price and comparable_unit_basis (100g, 100ml, each, lb) put a 1.89 L Superstore carton and a 2 L Save-On-Foods one on the same footing, and is_comparable_unit_price marks the rows where that holds.
  • Every retailer gets a verdict. run_meta.retailer_status reports success, no_results, failed with a reason, or skipped, and run_meta.warnings collects location and search failures, so a partial run tells you which retailer came up short.
  • Defaults stay small. Naming no retailers runs the six national chains; the other ten are opt-in, so an unspecified run stays predictable.
  • Runs without a browser, over plain HTTP against each retailer's own JSON API, with the Apify SDK as its only runtime dependency and no API keys.

What people build with it

  • Fixed-basket inflation tracking, rerunning the same list weekly and charting basket_summary totals
  • Grocery price comparison apps, using comparison rows straight as backend data
  • AI shopping agents, which get one normalized table instead of four retailer schemas
  • CPG competitor monitoring across banners and parent companies at once
  • Household budgeting dashboards in Google Sheets or Excel, fed by a scheduled run
  • Academic and journalistic food-price research needing store-level Canadian data

Input

FieldTypeRequiredDescription
queriesstring[]yesGrocery search terms. Also accepted as items
retailersstring[]noAny subset of the 16 keys below. Default: tnt, loblaws, superstore, nofrills, saveonfoods, pricesmart
locationstringnoCity and province (Vancouver, BC) or postal code. Alias for region and postal_code
regionstringnoOne of 8 metros: Vancouver, Calgary, Edmonton, Toronto, Ottawa, Montreal, Quebec City, Halifax. Default metro_vancouver
postal_codestringnoOverrides region
locationIdsobjectnoPer-retailer store overrides, e.g. { "tnt": "MGFS", "superstore": "1517" }
categoriesstring[]no17 unified category slugs, used by category_browse and intel modes
maxResultsPerQueryPerRetailerintegernoDefault 3
retailerConcurrencyintegernoDefault 3
minMatchConfidencestringnolow (default), medium or high
strictItemBestbooleannoDefault true. Restricts item_best_options to rows with a comparable unit price and medium or high confidence
includeSummariesbooleannoDefault false. Adds basket_summary, item_best_options and run_meta rows
outputModestringnoSee below. Default comparison

Output modes

ModeBest for
comparisonFlat rows, one matched product per query per retailer. CSV, Excel and ETL
comparison_groupedOne record per query with all retailer results nested. LLM and agent input
summaryCheapest retailer, price range, median price and sale count per query
category_browseFull category listings per retailer, with no query matching
intelComparison rows plus summaries, category stats, top deals and a run summary

Start with comparison unless you know you need another one.

Fixed-basket tracking

Run the same basket on a schedule to build a price history:

{
"queries": ["eggs", "milk", "bread", "bananas", "chicken breast", "ground beef", "rice", "celery"],
"location": "Vancouver, BC",
"retailers": ["loblaws", "saveonfoods", "tnt"],
"includeSummaries": true
}

With includeSummaries on, each run also emits:

  • basket_summary, the basket total per retailer
  • item_best_options, the cheapest source per item
  • run_meta, per-retailer status and warnings

That covers basket totals, per-item winners and sale frequency over time with no post-processing.

Supported retailers

KeyChainWhere
loblawsLoblawsBC, AB, ON
superstoreReal Canadian SuperstoreBC, AB, SK, MB, ON, YT
nofrillsNo FrillsNationwide
zehrsZehrsON
fortinosFortinosON
valumartValu-martON, QC
independentYour Independent GrocerNationwide
provigoProvigoQC
maxiMaxiQC, NB
wholesaleclubWholesale ClubNationwide
atlanticsuperstoreAtlantic SuperstoreNB, NS, PE
saveonfoodsSave-On-FoodsBC, AB, SK, MB
pricesmartPriceSmart FoodsMetro Vancouver
urbanfareUrban FareVancouver, Kelowna
qualityfoodsQuality FoodsVancouver Island, Sunshine Coast
tntT&T SupermarketBC, AB, ON, QC

T&T serves one catalogue chain-wide, so its resolved store labels the rows while prices stay constant. Loblaw and Pattison banners price per store.

FAQ

How do I compare grocery prices across Canadian stores? Give queries (your grocery list), a location, and the retailers you want. Each run returns one matched row per item per retailer, with price, unit price and a confidence score.

Which is cheapest for my basket? Set "includeSummaries": true and read the basket_summary rows, which total the basket per retailer, and item_best_options, which names the cheapest source per item.

Are the matches exact? Not always. The Actor compares retailer search results, and grocery products vary by brand, size and naming. Every row carries match_score, match_confidence and the reasons behind them; filter with minMatchConfidence.

Which retailers run by default? The six national chains: tnt, loblaws, superstore, nofrills, saveonfoods and pricesmart. The other ten are opt-in.

Does it cover Sobeys, Metro, Walmart or Costco? Sobeys, Metro and Walmart Canada are outside the 16. Costco has a separate Actor.

Does it track price history? No. Each run returns current prices. Schedule the same basket and keep each dataset to build history.

Should I use this or a single-retailer Actor? Use this one to compare across chains. Use a retailer Actor when you want one chain in depth, with full category trees and whole-store scrapes.

Is scraping these retailers legal? Scraping publicly available product and price information is generally legal. Complying with each retailer's terms of service and the law in your jurisdiction remains your responsibility, so keep request volume reasonable.

Limitations

  • This Actor compares retailer search results, and makes no guarantee of exact product equivalence across stores, because grocery products vary by brand, size, store and naming. Review matches with match_confidence, package_size, comparable_unit_price and source_url, and filter them with minMatchConfidence.
  • Prices and availability vary by store, postal code, time of scrape, loyalty program and retailer search behaviour.
  • Coverage stops at 16 chains. Sobeys, Metro and Walmart Canada fall outside it, and Costco has a separate Actor.
  • Each run returns current prices and keeps no history between runs. Schedule the same basket and store the datasets to build that history yourself.

Canadian grocery Actors

ActorChainsCoverage
Canadian Grocery Price Comparison API (this Actor)16, matched and ranked in one runNationwide
Loblaws, No Frills, Superstore & Maxi Scraper API - Canada12 Loblaw bannersEvery province, YT, NT
Save-On-Foods, PriceSmart & Urban Fare Scraper API - Canada4 Pattison Food Group bannersBC, AB, SK, MB
T&T Asian Supermarket Grocery Price Scraper API - CanadaT&TBC, AB, ON, QC
Costco Scraper API - Warehouse Prices & DealsCostco warehousesCanada and US

Use this Actor to compare across chains. Use a retailer Actor when you want one chain in depth, with full category trees, whole-store scrapes and every field that chain exposes. All four retailer Actors share 21 core output fields, so their datasets concatenate without a mapping layer.

Feedback

Found a bug or have technical feedback? Open an issue on the Actor's Issues tab.