# Domino's Scraper — Stores, Menus, Prices & Coupons (`yugenox/dominos-stores-menu-prices`) Actor

Scrape Domino's Pizza Canada + USA: store addresses, hours, delivery fees, minimum orders and wait times, full menus with store-level prices, calories and toppings, coupons, and price changes between runs. By postal/ZIP code, store ID, or all ~670 Canadian stores. No login.

- **URL**: https://apify.com/yugenox/dominos-stores-menu-prices.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result rows

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Domino's Scraper: Stores, Menus, Prices & Coupons (Canada + USA)

Get **store-level Domino's Pizza data** for Canada and the USA: every store's address, phone, hours, delivery fee, minimum order and live wait times, the **full menu with that store's own prices** (every size and crust), calories, toppings, product photos and the store's **coupons and deals**. Turn on **price changes** and each run tells you what went up, went down, was added or was removed since your last run.

- 🇨🇦 **All ~670 Canadian stores in one run.** Turn on *All Canadian stores*. You don't need to guess postal codes.
- 🇺🇸 **US stores by ZIP code or city.**
- 💲 **Real store-level prices.** Domino's prices differ from store to store. For example, a large hand-tossed pizza cost $12.99 in Toronto, $13.80 in Edmonton, $13.99 in Vancouver, $14.99 in Montreal and $16.99 in Nova Scotia (September 2026), and 170 of 279 menu items were priced differently between one Toronto store and one Vancouver store.
- 📈 **Price tracking built in.** Schedule the actor and get one row per price change.
- 🇫🇷 **French menus** for Canadian stores.
- No login or cookies needed. You don't have to set anything up.

### What you can scrape

| Row type (`type`) | One row per | Highlights |
|---|---|---|
| `store` | store | address, phone, lat/lng, hours per service, open now, online ordering, **delivery fee**, **minimum delivery order**, **delivery and carryout wait minutes**, payment methods, time zone, store page link |
| `menuItem` | size or crust of each product, per store | product and item names, **price**, **price per extra topping**, full price tiers, size, crust/flavour, category, **calories**, servings, description, default and available toppings, new-item flag, photo |
| `coupon` | deal, per store | code, name, **price**, carryout/delivery validity, valid days, start and end dates, local-deal flag |
| `priceChange` | changed price, per store | old price, new price, change, change %, increase / decrease / added / removed |

### How to use it

**Stores and menus near an address.** Add one or more *Locations*:

```json
{ "locations": ["M5V 3L9", "Vancouver, BC", "37203"], "maxStores": 3 }
```

Postal codes, ZIP codes and `City, Province/State` all work. Canadian and US locations are detected automatically. Each location returns the stores in range with the nearest first. With several locations, *Max stores* takes stores from each location in turn.

**Every store in Canada, or in some provinces:**

```json
{ "allStores": true, "regions": ["ON", "QC"], "outputs": ["stores", "menuItems", "coupons"] }
```

**Specific stores:**

```json
{ "storeIds": ["10497", "US:5422"], "outputs": ["stores", "menuItems", "coupons"] }
```

**Track a few prices across the whole country (schedule it daily or weekly):**

```json
{
  "allStores": true,
  "outputs": ["priceChanges"],
  "variantCodes": ["14SCREEN", "12SCREEN", "CHSBREAD"],
  "priceHistoryName": "canada-pizza-tracker"
}
```

The first run saves a baseline. Every later run with the same *Price history name* outputs only what changed.

### Input

| Field | What it does |
|---|---|
| `locations` | Postal/ZIP codes, `City, Province/State`, or street addresses |
| `storeIds` | Domino's store numbers (`10497`, `US:5422`) or pizza.dominos.ca store links |
| `allStores` | Every Canadian store (~670) |
| `regions` | Keep only these provinces/states: codes (`ON`, `BC`, `TX`…) or names (`Ontario`, `Québec`, `Texas`) |
| `market` | `CA` (default), `US` or `both`. Used for inputs that don't name a country |
| `outputs` | Any of `stores`, `menuItems`, `coupons`, `priceChanges` (default: stores + menu items) |
| `productTypes` | Only these menu sections: Pizza, Wings, Bread, Sides, Pasta, Dessert, Drinks… |
| `variantCodes` | Only these item codes (e.g. `14SCREEN`) |
| `language` | `en` or `fr` (French is Canada only) |
| `serviceType` | `Carryout` (stores nearby) or `Delivery` (stores that deliver to the address) |
| `includeToppings` | Topping names instead of codes |
| `includeImages` | Product photo URLs (default on) |
| `priceHistoryName` | Keeps separate price trackers apart |
| `maxStores`, `maxItems` | Limits (0 = no limit) |
| `maxConcurrency` | Stores scraped in parallel (1–10) |

### Output examples

**Store**

```json
{
  "type": "store", "market": "CA", "storeId": "10497",
  "street": "344 Front St W Unit 107", "city": "Toronto", "region": "ON", "postalCode": "M5V 3W7",
  "address": "344 Front St W Unit 107, Toronto, ON M5V 3W7",
  "latitude": 43.6434, "longitude": -79.392, "phone": "416-599-2929",
  "isOpen": true, "isOnlineNow": true, "allowsDelivery": true, "allowsCarryout": true,
  "deliveryFee": 5.99, "minimumDeliveryOrder": 15,
  "deliveryWaitMinutesMin": 24, "deliveryWaitMinutesMax": 34,
  "carryoutWaitMinutesMin": 9, "carryoutWaitMinutesMax": 14,
  "hoursDescription": "Su-Th 10:30am-1:00am; Fr-Sa 10:30am-2:00am",
  "driveUpCarryoutHours": "Su-Sa 4:00pm-9:00pm",
  "currency": "CAD", "timeZone": "GMT-04:00",
  "paymentTypes": ["Cash", "GiftCard", "CreditCard", "DoorDebit", "DoorCredit"],
  "storeUrl": "https://pizza.dominos.ca/Toronto-ON-10497/",
  "menuItemCount": 279, "couponCount": 35,
  "scrapedAt": "2026-09-24T05:10:09.072Z"
}
```

**Menu item**

```json
{
  "type": "menuItem", "market": "CA", "storeId": "10497", "storeCity": "Toronto", "storeRegion": "ON",
  "category": "Pizza > Build Your Own", "productType": "Pizza", "productName": "Pizza",
  "variantCode": "14SCREEN", "variantName": "14\" Hand Tossed",
  "sizeName": "Large (14\")", "flavorName": "Hand Tossed",
  "price": 12.99, "currency": "CAD", "extraToppingPrice": 2.25,
  "calories": "Cals 240-520 per slice", "servings": "8 slices",
  "defaultToppings": ["Pizza Sauce", "Cheese"],
  "availableOnDeliveryApps": ["UberEats", "DoorDash", "SKIP"],
  "imageUrl": "https://cache.dominos.com/.../larges/S_PIZZA.jpg",
  "language": "en", "scrapedAt": "2026-09-24T05:10:09.072Z"
}
```

**Coupon**

```json
{
  "type": "coupon", "storeId": "10497", "storeCity": "Toronto", "couponCode": "3022",
  "name": "1 Medium 4-Topping Pizza", "price": 11.99, "currency": "CAD",
  "serviceMethods": ["Carryout", "Delivery"], "effectiveOn": "2018-06-11", "isStoreSpecific": true
}
```

**Price change** (illustrative values)

```json
{
  "type": "priceChange", "storeId": "10017", "storeCity": "Vancouver", "itemType": "menuItem",
  "code": "14SCREEN", "name": "14\" Hand Tossed", "productType": "Pizza",
  "changeType": "increase", "oldPrice": 12.99, "newPrice": 13.99, "change": 1, "changePercent": 7.7,
  "previousScrapedAt": "2026-09-17T06:00:00.000Z", "scrapedAt": "2026-09-24T06:00:00.000Z"
}
```

The dataset has four table views: **Menu prices**, **Stores**, **Coupons** and **Price changes**. You can export any of them to CSV, Excel or JSON.

### Use cases

- **Competitive pricing.** Compare Domino's prices by city and province against your own pizzeria or chain.
- **Price monitoring.** Schedule weekly runs and get alerted when menu prices or deals change.
- **Market research.** Map store density, delivery fees, minimum orders and opening hours across Canada.
- **Menu and nutrition databases.** Full menus with calories, servings and photos.
- **Deal aggregators.** Current coupons for each store, with service type and dates.
- **Location intelligence.** Coordinates, phone numbers and store pages for every Canadian Domino's.

### Speed

One store with its full menu takes a few seconds. All ~670 Canadian stores take about 2 minutes with store details only, or about 4 minutes with full menus and coupons (about 215,000 rows). You pay per result row, so to keep a big run small, narrow it with *Provinces / states*, *Product types* or *Item codes*, or set *Max rows*.

### FAQ

**Why do prices differ between stores?** Domino's stores are mostly franchised and set their own prices, so the same item can cost a dollar or more extra in another city. That is why every menu row carries the store it came from.

**Why did my location return nothing?** The store finder needs a location it can resolve: a full postal/ZIP code (`M5V 3L9`, `37203`) or a city with its province/state (`Toronto, ON`). A bare province (`ON`) or a partial postal code (`M5V`) is too broad. For all of Canada, use *All Canadian stores*. Canadian cities the store finder doesn't recognise (e.g. `Halifax, NS`) are matched by name against the full Canadian store list automatically.

**Can I crawl every US store?** Not yet. For the US, use ZIP codes or cities in *Locations*. Each returns about 10 nearby stores.

**What does `extraToppingPrice` mean?** It is how much one extra topping adds to that item at that store, read from the item's price tiers (`priceTiers`). `includedToppings` says how many toppings the base price already includes. It is 0 at most stores. Some stores, such as those in Montreal, include one topping in the base price.

**Some stores have no delivery fee or coordinates.** A few stores don't publish them. Those fields are left empty rather than guessed.

**How does price tracking work?** When `priceChanges` is selected, the actor stores a compact price snapshot of each store in your Apify account under the *Price history name*. The next run compares against it. Snapshots cover the whole menu, so changing your filters never creates false "added" rows.

**Is it legal to scrape Domino's?** This Actor only collects publicly available data: store locations, opening hours and store phone numbers, menus with each store's prices, and coupons that anyone can see on Domino's website without an account. Collecting publicly available data is generally legal, but you're responsible for how you use it. You must follow privacy laws such as GDPR, PIPEDA and CCPA, as well as Domino's terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?** No. Everything comes from pages Domino's shows to any visitor without logging in. It never uses a login, never touches private or restricted accounts, and never reaches password-protected areas.

# Actor input Schema

## `locations` (type: `array`):

Find the Domino's stores near each location. Use a full postal or ZIP code ("M5V 3L9", "37203"), a city with its province or state ("Toronto, ON", "Nashville, TN"), or a street address ("100 Queen St W, Toronto, ON"). Each location returns every store in range (up to ~75 in Canadian cities, ~10 in the US) — nearest first. Canadian and US addresses are recognised automatically; a Canadian city the store finder does not know is matched by name against the Canadian store list.

## `storeIds` (type: `array`):

Domino's store numbers, e.g. "10497". Prefix US stores with "US:" ("US:5422") unless Market is set to USA. Store page links from pizza.dominos.ca work too.

## `allStores` (type: `boolean`):

Scrape every Domino's store in Canada (~670). Combine with Provinces to limit the crawl. A full crawl of stores + menus + coupons takes about 4 minutes (~215,000 rows).

## `regions` (type: `array`):

Only keep stores in these provinces or states: 2-letter codes ("ON", "BC", "QC", "TX"…) or names ("Ontario", "Québec", "Newfoundland and Labrador", "Texas"). Leave empty for all. If none of the entries is recognised the run stops without scraping (it never silently widens to every store).

## `market` (type: `string`):

Which Domino's to use for inputs that don't name a country (store IDs, ambiguous city names). Postal/ZIP codes and province/state codes are routed automatically. "All Canadian stores" is Canada only.

## `outputs` (type: `array`):

Row types to save. Stores: address, phone, hours, delivery fee, minimum order, wait times. Menu items: every size/crust of every product with this store's price. Coupons: the store's deals. Price changes: what changed since your previous run with price changes turned on (the first run saves a baseline).

## `productTypes` (type: `array`):

Only output menu items of these types. Leave empty for the whole menu.

## `variantCodes` (type: `array`):

Only output these menu item codes (the variantCode field), e.g. "14SCREEN" for a large hand-tossed pizza. Handy for tracking a few prices across many stores.

## `language` (type: `string`):

French is available for Canadian stores (names, sizes, crusts, toppings and coupons). US stores are always in English.

## `serviceType` (type: `string`):

How Locations are searched: Carryout lists the stores near the address; Delivery lists the stores that deliver to it.

## `includeToppings` (type: `boolean`):

Show default and available toppings as names ("Pepperoni") instead of codes ("P").

## `includeImages` (type: `boolean`):

Add a verified product photo URL to each menu item.

## `priceHistoryName` (type: `string`):

Price changes are compared with the last run that used the same name. Use different names to keep separate trackers (e.g. "weekly-ontario").

## `maxStores` (type: `integer`):

Stop after this many stores (0 = no limit). With several locations, stores are taken from each location in turn.

## `maxItems` (type: `integer`):

Stop after saving this many rows in total (0 = no limit).

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

How many stores to scrape at once.

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

Apify Proxy is required. The default datacenter proxy works; the actor switches to residential automatically if it gets blocked.

## Actor input object example

```json
{
  "locations": [
    "M5V 3L9"
  ],
  "allStores": false,
  "market": "CA",
  "outputs": [
    "stores",
    "menuItems"
  ],
  "language": "en",
  "serviceType": "Carryout",
  "includeToppings": false,
  "includeImages": true,
  "priceHistoryName": "default",
  "maxStores": 1,
  "maxItems": 0,
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped rows.

## `run` (type: `string`):

Status and statistics for this run.

# 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 = {
    "locations": [
        "M5V 3L9"
    ],
    "outputs": [
        "stores",
        "menuItems"
    ],
    "maxStores": 1,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/dominos-stores-menu-prices").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 = {
    "locations": ["M5V 3L9"],
    "outputs": [
        "stores",
        "menuItems",
    ],
    "maxStores": 1,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/dominos-stores-menu-prices").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 '{
  "locations": [
    "M5V 3L9"
  ],
  "outputs": [
    "stores",
    "menuItems"
  ],
  "maxStores": 1,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/dominos-stores-menu-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/dominos-stores-menu-prices"
        }
    }
}
```

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/IYZb80B8qRucUKz5L/builds/x0nUFOgKj9IaSsPmq/openapi.json
