# Sobeys Grocery Scraper API - Canada Prices & Nutrition (`alduinxx/sobeys-grocery-scraper`) Actor

Prices, promotions, categories and full nutrition panels for 64,000 Sobeys Canada grocery products. Search by keyword, export CSV or JSON.

- **URL**: https://apify.com/alduinxx/sobeys-grocery-scraper.md
- **Developed by:** [Michael Hill](https://apify.com/alduinxx) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Most grocery scrapers give you a name and a price. This one gives you **the regular price, the sale price, and the date the promotion ends** — plus a **16-field nutrition panel** — for Sobeys Canada.

Sobeys is one of Canada's three big grocery chains, and its online catalogue lists about **64,000 products** across 236 stores. Search by keyword or pull the whole catalogue. Export to CSV, Excel, JSON, or pull it straight from the API.

### Why this one

| | Typical grocery scraper | This Actor |
|---|---|---|
| Current price | ✅ | ✅ |
| Regular price when an item is on sale | ❌ | ✅ `regularPrice` |
| When the promotion ends | ❌ | ✅ `priceValidUntil` |
| Full nutrition panel | ❌ | ✅ 16 fields |
| Same product across several banners | ❌ | ✅ shared `sku` |

If you are tracking promotions rather than just prices, that middle block is the difference between "this costs $4.99" and "this is $4.99 until Wednesday, normally $6.79."

Sobeys shares one product ID with Safeway, Foodland, Thrifty Foods, IGA and FreshCo — all Empire Company banners. **The same `sku` identifies the same item in every one of them.** Run this alongside the [Safeway](https://apify.com/alduinxx/safeway-canada-grocery-scraper) and [Foodland, Thrifty Foods, IGA & FreshCo](https://apify.com/alduinxx/foodland-thrifty-foods-iga-freshco-scraper) scrapers and the rows line up across six banners and every region in Canada — which is exactly the comparison a plain price scraper cannot do.

### What you get

| Field | Example |
|---|---|
| `name` | Compliments Pine Nuts 100 g |
| `brand` | Compliments (empty for unbranded items) |
| `price` | 11.99 — the current price, promotional if one is running |
| `regularPrice` | 14.99 — the regular price; same as `price` when nothing is on offer |
| `onSale` | true / false |
| `priceValidUntil` | 2026-09-30 — when a promotion ends |
| `currency` | CAD |
| `availability` | InStoreOnly or OutOfStock |
| `category` | Nuts, Seeds & Trail Mixes |
| `categoryPath` | Sobeys > Pantry > Nuts, Seeds & Trail Mixes |
| `sku` | 444192 — Sobeys' internal ID, not a UPC |
| `imageUrl` | Link to the product image — empty for about a third of the catalogue |
| `url` | Link to the product page |
| `scrapedAt` | ISO timestamp |

With **Include nutrition panel** on (the default), each row also carries `servingSize`, `calories`, `fat`, `saturatedFat`, `transFat`, `omega3`, `omega6`, `cholesterol`, `sodium`, `carbohydrate`, `fibre`, `sugar`, `protein`, `calcium`, `iron` and `potassium`.

### What people use it for

- **Price and promotion monitoring** — track list price, sale price and promotion end dates week to week
- **CPG and brand teams** — track published price and stock status for your own products
- **Price comparison apps** — populate a Canadian grocery catalogue
- **Nutrition and diet apps** — a large Canadian food database with real retail prices attached
- **Research** — food price inflation over time, product assortment, brand share of shelf

### How to use it

1. Put one or more words in **Search terms** — `milk`, `bread`, `coffee`. Leave the field empty to walk the entire catalogue.
2. Set **Maximum products**. Start small (the default 100) to see the shape of the data before a big run. This is also your spend ceiling — you are charged per product returned.
3. Run it. Results appear in the dataset tab and can be exported in any format.

#### Tips

- Search terms are matched against the product name in the URL, so `milk` works and `2% milk 4L` will not.
- Matching is a plain substring test and any term can match, so short terms catch more than you expect — `com` also matches `compliments`.
- Leave the proxy on. Sobeys blocks unproxied requests outright.
- If you see failures, lower **Parallel requests**.

### Pricing

**$0.75 per 1,000 products**, plus a $0.00005 start fee that is small enough to ignore. You are charged per product returned — nothing for products that fail, and nothing for the sitemap pages the run reads to find them. A 100-product run costs about $0.08, and 1,000 products about $0.75.

### Notes

- Prices are the national catalogue prices Sobeys publishes on its own product pages. They are not store-specific — verified by comparing an Alberta store against a Nova Scotia store across 25 products, which returned identical prices. Items are listed `InStoreOnly` or `OutOfStock`, so treat the figure as Sobeys' published price rather than a till price at a particular branch.
- Roughly two products in five are listed `OutOfStock` at any time; the rest are `InStoreOnly`. Those rows carry price and nutrition data just like the rest.
- Every product carries a price. About a third carry no image and about one in six is unbranded — both come back empty rather than missing.
- About four in five products publish usable nutrition data, and a filled panel averages roughly half its sixteen fields. Calories are there for about 80% of products, protein for a little under half. The rest come back with the nutrition columns empty rather than missing.
- About one product in seven is on offer at any time, and those rows carry the regular price and the promotion end date alongside the sale price.
- This reads the structured product data Sobeys publishes on its own pages for search engines, and only follows URLs listed in their public sitemap. It does not touch account, cart, or checkout areas, which their robots.txt disallows.
- Nutrition values come through exactly as Sobeys publishes them, which means some are numbers and some are strings with units (`21 g`). Unmeasured nutrients come back empty rather than missing, so your columns stay stable.

### Problems or requests

Open an issue on the Actor's Issues tab. Bug reports get fixed and reasonable field requests usually get added.

# Actor input Schema

## `keywords` (type: `array`):

Matched against the product name in the URL, e.g. milk, bread, coffee. Any term can match, and matching is a plain substring test, so short terms catch more than you expect ('com' matches 'compliments'). Leave empty to walk the whole catalogue.

## `maxProducts` (type: `integer`):

Stop after this many products. The full catalogue is about 64,000 items — raise this when you need more. You are charged per product returned, so this is also your spend ceiling.

## `includeNutrition` (type: `boolean`):

Adds calories, fat, sodium, protein and the rest of the panel where Sobeys publishes it.

## `maxConcurrency` (type: `integer`):

Lower this if you see failures. Higher is faster but heavier on the site.

## `proxyConfiguration` (type: `object`):

Required. Sobeys blocks unproxied requests, so runs without a proxy fail immediately. Leave this on unless you are supplying your own proxy.

## Actor input object example

```json
{
  "keywords": [
    "milk"
  ],
  "maxProducts": 100,
  "includeNutrition": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `products` (type: `string`):

No description

## `productsCsv` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "milk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("alduinxx/sobeys-grocery-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "keywords": ["milk"] }

# Run the Actor and wait for it to finish
run = client.actor("alduinxx/sobeys-grocery-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "milk"
  ]
}' |
apify call alduinxx/sobeys-grocery-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,alduinxx/sobeys-grocery-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/uKGVTxWjBDu6fkcut/builds/ut6zFRGakSAKCybps/openapi.json
