Save-On-Foods, PriceSmart & Urban Fare Scraper API - Canada avatar

Save-On-Foods, PriceSmart & Urban Fare Scraper API - Canada

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Save-On-Foods, PriceSmart & Urban Fare Scraper API - Canada

Save-On-Foods, PriceSmart & Urban Fare Scraper API - Canada

Scrape grocery prices from Pattison Food Group stores — Save-On-Foods, PriceSmart Foods, Urban Fare and Quality Foods. Product names, prices, sale prices, package sizes, normalized unit pricing and images, per store by postal code. Export JSON, CSV or Excel.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

JChaw

JChaw

Maintained by Community

Actor stats

2

Bookmarked

11

Total users

2

Monthly active users

10 days ago

Last modified

Share

Western Canada grocery price data from the four Pattison Food Group chains, priced at the individual store by postal code.

The Save-On-Foods Scraper API returns live shelf prices, sale prices, unit prices and weekly deals from Save-On-Foods, PriceSmart Foods, Urban Fare and Quality Foods, with no API key and no browser.

  • Chains: Save-On-Foods, PriceSmart Foods, Urban Fare, Quality Foods
  • Coverage: BC, Alberta, Saskatchewan, Manitoba
  • Every row: name, price, was-price, sale flag, unit price, normalized unit price, package size, image, product URL, product ID, store details, multi-buy deals
  • Setup: none. No API key, no account, no proxy.

Each chain prices independently. The same 3.25% milk can be $7.99 at Save-On-Foods and $8.49 at Urban Fare on the same day in the same city.

Run it

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

{
"banner": "saveonfoods",
"search_terms": ["eggs", "milk", "chicken breast"],
"postal_code": "V6M 2P8"
}

Rows stream into Output as they arrive. Download from Storage → Dataset as JSON, CSV or Excel.

Three things to change from there:

  • Scrape a whole department by swapping search_terms for categories, e.g. ["fruits-vegetables", "dairy-eggs"]
  • Price a different store by changing postal_code to yours
  • Switch chains with banner: pricesmart, urbanfare or qualityfoods

From the API

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

curl -X POST \
"https://api.apify.com/v2/acts/sunny_eternity~save-on-foods-pricesmart-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"banner": "saveonfoods", "search_terms": ["eggs", "milk", "chicken breast"], "postal_code": "V6M 2P8"}'
  • run-sync-get-dataset-items suits small runs and can time out on large ones
  • For scheduled or full-store scrapes, POST to /runs and read the returned defaultDatasetId
  • Official JavaScript and Python clients work too

What you get back

{
"store": "Save-On-Foods",
"name": "Organic Whole Milk 2L",
"price": "5.99",
"unit_price": "$0.30/100ml",
"comparable_unit_price": 0.30,
"package_size": "2000ml",
"selling_type": "by_unit",
"was_price": null,
"is_on_sale": false,
"multi_buy_deal": null,
"image_url": "https://assets.shop.saveonfoods.com/products/...",
"product_url": "https://www.saveonfoods.com/sm/planning/rsid/1982/product/...",
"product_id": "00000000123456",
"category": "dairy-eggs/milk-creams",
"location": "1982",
"location_name": "Save-On-Foods Marine Drive"
}
FieldWhat it holds
storeChain name: Save-On-Foods, PriceSmart Foods, Urban Fare or Quality Foods
name, priceProduct name and current price, no $ symbol
unit_priceRaw unit price string from the store, e.g. "$0.30/100ml"
comparable_unit_priceNormalized $/100 g or $/100 ml, null when the size will not parse
parsed_unit_price, parsed_package_size, normalized_package_sizeStructured value, quantity and unit forms
package_size, selling_typeSize string, plus by_weight or by_unit
was_price, is_on_sale, multi_buy_dealPre-sale price, sale flag, promotion text
image_url, product_url, product_idMedia and identifiers
categoryCategory slug, or search:<term> for dedicated search results
location, location_name, location_postal_code, location_coordinatesThe store the prices came from

Export as JSON, CSV or Excel, pull it through the Apify API, schedule recurring runs, or push it into Zapier, Make, Google Sheets and Airbyte.

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.
  • Covers four banners from one input. All four run on one platform, so categories and output fields are identical across them. Urban Fare and Quality Foods are the two most competing scrapers leave out.
  • Prices down to the individual store. Postal codes resolve against the chain's own live store directory, and every row names the store, its rsid, its postal code and its coordinates.
  • Works outside the metros. Because the directory is read at runtime, Nanaimo, Kelowna, Prince George, Calgary, Edmonton, Saskatoon and Winnipeg resolve as reliably as downtown Vancouver.
  • Runs without a browser. The only runtime dependency is the Apify SDK, reading the same JSON API the storefront reads, so you pay for no headless Chrome and hit no CAPTCHAs.
  • Needs no credentials at all: no API key, no account, no third-party geocoder, no proxy configuration.
  • Normalizes unit prices to $/100 g or $/100 ml, and leaves comparable_unit_price as null where a package size will not parse, which keeps a bad number out of your comparison.
  • Refuses out-of-footprint input. A postal code a chain does not serve returns an error naming the provinces it does, so an Ontario query never quietly comes back with a BC store.

What people build with it

  • Grocery price comparison apps covering BC, Alberta, Saskatchewan and Manitoba
  • Food inflation research, by rerunning a fixed basket weekly and diffing price over time
  • CPG competitor monitoring across all four Pattison banners at once
  • Deal sites, pulling is_on_sale, was_price and multi_buy_deal
  • AI shopping agents that need grounded Western Canada prices
  • Regional price studies, comparing Vancouver against Nanaimo, Kelowna, Prince George or Saskatoon

Input

FieldTypeRequiredDescription
bannerstringyessaveonfoods, pricesmart, urbanfare or qualityfoods
categoriesstring[]one ofDepartments or subcategories; 125 entries (14 departments, 111 subcategories)
categoryUrlsstring[]one ofRaw category IDs for subcategories missing from the dropdown
search_termsstring[]one ofKeyword queries; combined with categories they filter by name instead
postal_codestringone ofCanadian postal code; resolves the nearest store. Default V6M 2P8
locationIdstringone ofExplicit store rsid, takes priority over postal_code
  • At least one of categories, categoryUrls or search_terms is required
  • At least one of postal_code or locationId is required, so the Actor knows which store to query
  • Selecting a department queues every subcategory beneath it
  • Setting categories and search_terms together filters the category results by product name, with no separate search call, and category holds the category slug
  • Used on its own, each search term goes to the store's search API and its rows are tagged category: "search:<term>"

Examples

One subcategory:

{ "banner": "saveonfoods", "categories": ["bakery/breads"] }

Departments and subcategories mixed:

{ "banner": "saveonfoods", "categories": ["meat-seafood", "dairy-eggs/cheese", "frozen/frozen-pizza"] }

A specific store by rsid:

{ "banner": "pricesmart", "locationId": "2274", "categories": ["fruits-vegetables/fresh-fruit", "bakery/breads"] }

Keyword search:

{ "banner": "saveonfoods", "locationId": "1982", "search_terms": ["oat milk", "sourdough bread"] }

Category results filtered by keyword:

{ "banner": "saveonfoods", "postal_code": "V6M 2P8", "categories": ["dairy-eggs/cheese"], "search_terms": ["lactose free"] }

Supported stores

BannerStoreWhere
saveonfoodsSave-On-FoodsBC, AB, SK, MB
pricesmartPriceSmart FoodsMetro Vancouver
urbanfareUrban FareVancouver, Kelowna
qualityfoodsQuality FoodsVancouver Island, Sunshine Coast

All four run on one Pattison Food Group platform, so the Actor behaves identically for each.

FAQ

How do I scrape Save-On-Foods prices? Set "banner": "saveonfoods" and give either search_terms or categories, plus a postal_code or locationId. The Run it input above is a working example.

Can I get grocery prices for a specific postal code? Yes. Pass any Canadian postal_code inside the chain's footprint and the Actor resolves the nearest store, then reports its name and rsid on every row.

Does it cover Urban Fare and Quality Foods? Yes, with "banner": "urbanfare" or "qualityfoods". Both run on the same platform as Save-On-Foods, so categories and output fields are identical.

Is there an official Save-On-Foods or PriceSmart API? No. None of the four chains publishes a public product or pricing API.

How do I find a store's rsid? In most cases postal_code is enough. Otherwise browse to your store on the chain's site and read the rsid out of the URL (/sm/planning/rsid/1982/):

  • Save-On-Foods: 1982 Vancouver Marine Drive, 2236 Vancouver False Creek, 6638 Calgary Mount Royal
  • PriceSmart Foods: 2281 Burnaby Station Square
  • Urban Fare: 7614 Vancouver Yaletown
  • Quality Foods: 4714 Nanaimo Harewood

Does it work outside the big cities? Yes. The Actor reads the chain's live store directory rather than a bundled table, so Nanaimo, Kelowna, Prince George, Saskatoon and Winnipeg resolve as reliably as downtown Vancouver.

How do I track prices over time? Schedule the Actor daily or weekly in Apify, keep each run's dataset, and compare price per product_id per store. The Actor returns current prices and stores no history itself.

Is scraping Save-On-Foods 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.

Canadian grocery Actors

ActorChainsCoverage
Canadian Grocery Price Comparison API16, 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 - Canada (this Actor)4 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

All four retailer Actors emit the same 21 core fields, among them name, price, was_price, is_on_sale, unit_price, comparable_unit_price, package_size, selling_type and the location set. Their datasets concatenate without a mapping layer. Chain-specific extras such as pc_optimum_offer sit alongside those fields.

Feedback

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