# Starbucks Scraper — Stores, Menu, Nutrition & Availability (`yugenox/starbucks-stores-menu-scraper`) Actor

Scrape every Starbucks store in Canada and the USA (address, phone, hours, drive-thru, mobile order, Wi-Fi, licensed vs company-operated) and the full menu with per-store availability, calories, caffeine, allergens and ingredients. By city, postal/ZIP, province/state or country. No login.

- **URL**: https://apify.com/yugenox/starbucks-stores-menu-scraper.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.50 / 1,000 stores

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

## Starbucks Scraper: Store Locations, Menu, Nutrition & Availability

Get **every Starbucks store in Canada and the USA** and the **full Starbucks menu**, with nutrition and **per-store item availability**, in one actor. No login or API key is needed, and there are no browser sessions to manage.

- **Stores:** address, phone, coordinates, weekly opening hours, open-now status, time zone, drive-thru, Mobile Order & Pay, Wi-Fi, Nitro Cold Brew, seating, and whether the store is **company-operated or licensed** (inside a grocery store, airport or campus).
- **Menu:** every drink and food item with its category, sizes, default size and photo.
  - **At a store:** each item's **availability** (Available / Temporarily unavailable), which works as a ready-made out-of-stock report.
  - **Nutrition, for every size:** calories, caffeine, sugar, fat, saturated and trans fat, cholesterol, sodium, carbs, fibre, protein, serving size, **allergens** and **ingredients**, plus the description, customization groups and the **Stars** redemption cost.
- **Search by** city, postal or ZIP code, street address, coordinates, province or state, or **the whole country**.
- **Speed:** all of Canada in about a minute, all of the USA in about 8 minutes, and the nearest 50 stores to a city in seconds.
- **English and French.** Canadian data is available in French: store amenities, hours and the menu.

### What you can use it for

- **Location intelligence and site selection:** map Starbucks density, drive-thru coverage and licensed vs company-operated footprints by city, province or state.
- **Competitive analysis for cafés, QSR chains and franchisors:** see where Starbucks is, what hours it keeps and which formats it runs.
- **Out-of-stock and menu monitoring:** schedule a daily run on your stores and use **Only unavailable items** to get a list of what is out today.
- **Nutrition databases, diet and fitness apps:** complete calorie, macro, caffeine and allergen data for every size of every item.
- **Real estate and retail research:** measure foot-traffic anchors near a property. Every store row carries its distance from your address.
- **Lead lists** for suppliers and service companies that sell to cafés.

### How to use

1. In **Locations**, enter one or more of:
   - `Toronto, ON`, `Austin, TX`, `Montreal`: the stores within the **Radius** (default 20 km), nearest first;
   - `M5V 3L9`, `10001`, `220 Yonge St, Toronto, ON`, `43.65,-79.38`: the stores around that point;
   - `Ontario`, `BC`, `Texas`: every store in that province or state;
   - `Canada`, `USA`: every store in the country (or switch on **Whole country**).
2. Pick **What to scrape**: *Stores*, *Menu* or *Stores + menu*.
3. Optional settings:
   - **Max stores per location**, for example the nearest 10 stores to each of your addresses.
   - **Must have** (drive-thru, Wi-Fi, mobile order…) and **Store type** (company-operated or licensed) to filter stores.
   - **Language** set to French for Canadian data.
4. Click **Start**. Rows appear in the dataset as the run goes.

For the menu alone, choose **Menu** and leave Locations empty. You get the national menu of the selected country, with nutrition.

#### Input example

```json
{
  "mode": "storesAndMenu",
  "locations": ["Toronto, ON", "Vancouver, BC"],
  "maxStoresPerLocation": 5,
  "amenities": ["driveThru"],
  "includeNutrition": true
}
```

### Output

Every row has a `type`, either `store` or `menuItem`. The dataset has ready-made tables: **Stores**, **Opening hours**, **Menu items** and **Nutrition**. You can export to JSON, CSV, Excel or HTML, or use the API.

#### Store row

```json
{
  "type": "store",
  "storeNumber": "4455-310581",
  "name": "Toronto Eaton Centre South",
  "ownershipType": "Company-operated",
  "phone": "+1 416-506-9946",
  "address": "220 Yonge St, Toronto ON M5B 2H1",
  "street": "220 Yonge St, Unit 2111",
  "city": "Toronto",
  "region": "ON",
  "regionName": "Ontario",
  "postalCode": "M5B 2H1",
  "country": "CA",
  "latitude": 43.65276,
  "longitude": -79.38036,
  "timeZone": "America/Toronto",
  "isOpenNow": true,
  "openStatus": "Open 6:30 AM-9:30 PM",
  "weeklyHours": { "monday": "6:30 AM to 9:30 PM", "saturday": "7:00 AM to 9:30 PM", "sunday": "8:30 AM to 7:30 PM" },
  "hasDriveThru": false,
  "hasMobileOrder": true,
  "hasWifi": false,
  "hasNitroColdBrew": true,
  "hasOvenWarmedFood": true,
  "amenities": ["In café", "Mobile Order and Pay", "Nitro Cold Brew", "Oven-Warmed Food", "Redeem Rewards"],
  "mobileOrderStatus": "READY",
  "guestOrdering": true,
  "distanceKm": 0.234,
  "query": "Toronto, ON",
  "storeUrl": "https://www.starbucks.ca/store-locator?map=43.65276,-79.38036,17z",
  "googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=43.65276,-79.38036"
}
```

#### Menu item row

```json
{
  "type": "menuItem",
  "market": "CA",
  "storeNumber": "4455-310581",
  "storeName": "Toronto Eaton Centre South",
  "name": "Iced Pumpkin Cream Chai",
  "productType": "Beverage",
  "availability": "Available",
  "categoryPath": "The Latest > Trending",
  "categoryPaths": ["The Latest > Trending", "Tea > Chai > Specialty Chai"],
  "sizes": ["Tall", "Grande", "Venti"],
  "defaultSize": "Grande",
  "calories": 400,
  "caffeineMg": 60,
  "sugarG": 55,
  "fatG": 16,
  "proteinG": 9,
  "servingSize": "473 ml",
  "starCost": 200,
  "customizations": ["Flavors", "Cold Foams", "Toppings", "Milk", "Sweeteners"],
  "sizeDetails": [
    { "size": "Tall", "sku": "11151106", "calories": 310, "caffeineMg": 45, "sugarG": 41 },
    { "size": "Grande", "sku": "11151107", "calories": 400, "caffeineMg": 60, "sugarG": 55 }
  ],
  "imageUrl": "https://cloudassets.starbucks.com/is/image/sbuxcorp/IcedPumpkinCreamChaiTeaLatte",
  "productUrl": "https://www.starbucks.ca/menu/product/2123774/iced"
}
```

Food rows also carry `allergens` (for example `"Barley, Egg, Gluten, Milk, Wheat"`) and the full `ingredients` list.

### How long does it take?

| Run | Time |
|---|---|
| Nearest 50 stores to a city | ~5 seconds |
| All stores within 20 km of a big city (~180 in Toronto) | ~15 seconds |
| A province (Ontario, ~600 stores) | under a minute |
| All of Canada (~1,400 stores) | about 1 minute |
| All of the USA (~16,900 stores) | about 8 minutes |
| Menu with nutrition (~250 items) | ~1–2 minutes |
| Menu of each extra store | well under a second per store |

### FAQ

**Does it include prices?**
No. Starbucks only shows prices inside the ordering flow, so they are not part of this data.

**How do you get past the 50-store limit of the store locator?**
The actor splits the map into smaller and smaller areas wherever stores are dense, so every store in a city, province or country is found. For a city or address, you get the exact nearest stores, sorted by distance.

**What is the difference between company-operated and licensed stores?**
Company-operated stores are run by Starbucks. Licensed stores are run by a partner, usually inside a grocery store, airport, hotel, hospital or campus, and some have fewer amenities (for example no Mobile Order).

**What does the availability field mean?**
For a store's menu, `Available` means the item can be ordered there right now. `TemporarilyUnavailable` usually means it is out of stock today. `NotAvailableHere` means that store doesn't sell it. National menu rows are simply `Available`.

**Why does a city search show a store from another city or country?**
Locations are searched by distance. A 20 km radius around Windsor, ON includes Detroit, MI stores. Use **Provinces / states filter** or a smaller **Radius** to narrow it.

**Can I run it on a schedule?**
Yes. Schedule the actor in Apify (daily for availability, weekly for store lists) and connect it to Google Sheets, Slack, webhooks or your database through Apify integrations.

**Is a proxy needed?**
Apify Proxy is used automatically. The default datacenter proxy is enough, and the actor switches to residential proxies by itself if it ever gets blocked.

**What if I type a store number that doesn't exist?**
Starbucks answers an unknown store number with its generic menu instead of an error. When a store's menu is identical to that generic menu, its rows carry `matchesDefaultMenu: true` and the run's status message says so. Either every item is available at that store, or the number is wrong (US stores need the `US:` prefix unless Country is USA). Use the `storeNumber` of a store row to be sure.

**What happens if Starbucks is down or blocking?**
The run still finishes successfully. You get every row collected up to that point, and the status message explains what happened (for example "Partial — stopped because …" or "0 items, no charge"). If product details fail, menu rows are still delivered, just without nutrition.

**Is it legal to scrape Starbucks?**
This actor collects only public information: store locations, opening hours, amenities and the public menu with nutrition, the same data anyone can see on starbucks.ca and starbucks.com without logging in. It does not collect personal data. How you use the results is up to you, so follow the laws that apply to you (such as GDPR, PIPEDA or CCPA) and the website's terms, and check with a lawyer if you are unsure. For background, read [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. It uses no login, account, cookie or API key. It reads only the public store locator and menu that the Starbucks websites show to every visitor, and it never touches ordering, cart, payment or Starbucks Rewards account data. That is also why prices are not included.

***

City and postal-code coordinates come from [GeoNames](https://www.geonames.org/) (CC BY 4.0).

# Actor input Schema

## `mode` (type: `string`):

Stores: one row per store. Menu: menu items — per store for the stores found by your locations (with that store's availability), or the national menu when no location is given. Stores + menu: both.

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

Cities ("Toronto, ON", "Austin, TX"), postal/ZIP codes ("M5V 3L9", "10001"), street addresses, coordinates ("43.65,-79.38"), provinces/states ("Ontario", "TX") or a whole country ("Canada", "USA"). Cities, postcodes and addresses return the stores within the radius below, nearest first; provinces, states and countries return every store in them.

## `maxStoresPerLocation` (type: `integer`):

Keep only the nearest N stores for each city/postcode/address (0 = every store within the radius).

## `radiusKm` (type: `integer`):

How far from each city/postcode/address to look. 20 km covers most of a big city; use 40–80 km for a metro area.

## `fullCountry` (type: `boolean`):

Scrape every Starbucks store in the country selected below (Canada ≈ 1,430 stores in about a minute; USA ≈ 16,900 stores in about 8 minutes). Combine with Provinces/states to narrow it.

## `country` (type: `string`):

Used by "Whole country", by the national menu (Menu mode without locations), and to break ties for ambiguous names ("CA", "Springfield"). Cities, postcodes and provinces/states are recognised automatically.

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

Only keep stores in these provinces or states ("ON", "QC", "BC", "NY", "California"…). Leave empty for all.

## `amenities` (type: `array`):

Only keep stores that have ALL of these.

## `ownership` (type: `string`):

Company-operated Starbucks stores, licensed stores (inside grocery stores, airports, campuses, hotels…), or both.

## `storeNumbers` (type: `array`):

Fetch the menu of these stores directly, e.g. "4455-310581" (the storeNumber field of a store row). Prefix US stores with "US:" unless Country is USA. Used by the Menu modes.

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

Add calories, caffeine, sugar, fat, protein, carbs, sodium, serving size, allergens and ingredients for every size of every menu item, plus the description and Stars cost. Adds about 1–2 minutes per run (each product is fetched once, whatever the number of stores).

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

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

## `onlyUnavailableItems` (type: `boolean`):

For store menus: only output items that are temporarily unavailable or not sold at that store — an out-of-stock report.

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

French is available for Canada (store amenities, hours, menu names and descriptions). US data is always in English.

## `thoroughScan` (type: `boolean`):

Advanced. By default a whole-country or province/state run only visits the map areas that held stores on the last full scan (much faster). Turn this on to sweep every inhabited area instead — slower, but it also finds a brand-new store in a town that never had one.

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

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

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

How many requests run 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
{
  "mode": "stores",
  "locations": [
    "Toronto, ON"
  ],
  "maxStoresPerLocation": 50,
  "radiusKm": 20,
  "fullCountry": false,
  "country": "CA",
  "ownership": "any",
  "includeNutrition": true,
  "onlyUnavailableItems": false,
  "language": "en",
  "thoroughScan": false,
  "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 = {
    "mode": "stores",
    "locations": [
        "Toronto, ON"
    ],
    "maxStoresPerLocation": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/starbucks-stores-menu-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 = {
    "mode": "stores",
    "locations": ["Toronto, ON"],
    "maxStoresPerLocation": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/starbucks-stores-menu-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 '{
  "mode": "stores",
  "locations": [
    "Toronto, ON"
  ],
  "maxStoresPerLocation": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/starbucks-stores-menu-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/starbucks-stores-menu-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/9RwVcKCp0xbTxCYy2/builds/UaAeP4eI7NW4othri/openapi.json
