# Asda Scraper: Prices, Rollbacks, Offers & Products (UK) (`zaiq/asda-scraper`) Actor

Scrape Asda UK grocery products by search, category or product URL: price, was price (Rollback), unit price, multi-buys, stock by store, prices for England, Scotland, Wales or Northern Ireland, ratings, dietary flags, optional ingredients and nutrition. Pay per product.

- **URL**: https://apify.com/zaiq/asda-scraper.md
- **Developed by:** [Zaiq](https://apify.com/zaiq) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Asda Scraper: Prices, Rollbacks, Offers & Products (UK)

Get Asda UK grocery products as clean data: price, Rollback and was price, unit price, multi-buys and meal deals,
stock at a store, prices for England, Scotland, Wales or Northern Ireland, category, rating, dietary flags and, if
you ask for it, ingredients, allergens, nutrition and barcode. Search like a shopper, list whole categories, or check
a fixed list of products every day.

The Actor sends the same product searches the asda.com website sends, so results arrive as structured data in
seconds (up to 500 products per request), without a browser and without logging in.

### What it does

- **Search terms**, as many pages as you need.
- **Category pages**: paste the page address, for example
  `https://www.asda.com/groceries/chilled-food/milk-butter-cream-eggs/fresh-milk`. Department and top-level pages
  work too, and `https://www.asda.com/groceries/special-offers/all-offers` lists every product on offer.
- **Product URLs or product numbers** (the number at the end of a product URL): up to 100 products per request. A
  product that does not exist comes back as a free row with an error.
- **Prices for the UK nation you choose**: Asda sets prices separately for England, Scotland, Wales and Northern
  Ireland.
- **Rollbacks** with the was price, **multi-buys** ("Any 2 for £7", "Any 4 for 3") with quantity and price, and
  **meal deals**, each with start and end dates.
- **Stock at a store**: `inStock` is checked at the store you choose (asda.com's default store unless you set one).
- **Unit price** (per kg, litre, each...), **pack size** as written and as a number in grams, millilitres or items.
- **Dietary flags** for every product (Vegetarian, Vegan, Halal, Free from gluten, milk, nuts...), category path,
  rating and number of reviews, labels (New, Dropped & Locked, Sponsored, Frozen).
- **Details on request**: ingredients, allergens (as text and as a list), nutrition table, storage, preparation,
  origin, manufacturer and the barcode (GTIN) where Asda publishes it.
- **Sort**: relevance, price low to high, price high to low, unit price, rating, name (Asda's own sorting).

The output has the same columns as our Tesco, Sainsbury's and Morrisons scrapers, so the four can be compared row by
row.

### Who uses it

- **Brands and suppliers** checking their shelf price, Rollbacks and multi-buys at Asda, nation by nation.
- **Retail and pricing analysts** tracking prices, unit prices and promotions over time.
- **Deal and comparison sites** listing current Rollbacks and multi-buys.
- **Researchers** comparing grocery prices across the four UK nations.
- **Nutrition and allergen apps** that need dietary flags, ingredients and nutrition per product.

### Example

Test runs on 4 October 2026 through UK home connections:

| Run | Result |
|---|---|
| Six searches (milk, bread, coffee, pasta, eggs, bananas), up to 50 products each | 267 products in 3 seconds; 97 on offer, 42 Rollbacks with a was price |
| Two top-level categories (Food Cupboard, Chilled Food), 1,500 products each | 3,000 products from 13 requests in 11 seconds |
| One search ("chocolate") to 650 products | 650 products from 2 requests in 5.4 seconds |
| Offers only: two searches and the fresh milk aisle | 130 products, all on offer; 82 Rollbacks |
| Ten pasta products and one fruit product with details | the ten pasta products with ingredients, allergens and a nutrition table; storage and origin for the fruit |
| Prices for Scotland | 40 coffee products priced for Scotland |
| Product numbers, one of them not on Asda | the real products returned; the missing one as a free row |
| The special offers page, 300 products | 300 products on offer in under 3 seconds from one request: 146 Rollbacks, 144 multi-buys, 17 meal deals |

No request was blocked in these runs.

### Input

```json
{
  "searchTerms": ["milk", "coffee"],
  "categoryUrls": [{ "url": "https://www.asda.com/groceries/chilled-food/milk-butter-cream-eggs/fresh-milk" }],
  "productIds": ["538241"],
  "maxItems": 500,
  "maxItemsPerSource": 200,
  "offersOnly": false,
  "sort": "relevance",
  "region": "england",
  "storeId": "4565",
  "includeDetails": false
}
```

| Field | What it does |
|---|---|
| `searchTerms` | Words to search for, as you would type them on asda.com. |
| `categoryUrls` | Asda category pages, including the special offers page. |
| `productUrls` | Asda product pages. |
| `productIds` | Asda product numbers (the number at the end of a product URL). |
| `maxItems` | Stop after this many products in total (default 1000). |
| `maxItemsPerSource` | Stop each search or category after this many products (default 200). |
| `offersOnly` | Only products on offer: Rollbacks, multi-buys and meal deals. |
| `sort` | `relevance`, `price-low-high`, `price-high-low`, `unit-price-low-high`, `rating` or `name`. |
| `region` | Prices for `england` (default), `scotland`, `wales` or `northern-ireland`. |
| `storeId` | The Asda store whose stock `inStock` reports (default 4565, the store asda.com uses before you choose one). |
| `includeDetails` | Add ingredients, allergens, nutrition and barcode (charged separately). |
| `deduplicate` | Write a product found by two searches once (default on). Switch off to keep every search's full list. |
| `proxyConfiguration`, `maxConcurrency` | Advanced. UK residential connections are the default and are included in the price. |

### Output

One row per product. A row from a search for "asda ground coffee" (offers only), with details shortened:

```json
{
  "retailer": "Asda",
  "productId": "9281616",
  "sku": "1000383287489",
  "gtin": "5063089971185",
  "name": "Exceptional by Asda Ground Colombian Roast Coffee 227g",
  "brand": "Exceptional by Asda",
  "url": "https://www.asda.com/groceries/product/exceptional-coffee-and-tea/exceptional-by-asda-ground-colombian-roast-coffee-227g/9281616",
  "imageUrl": "https://asdagroceries.scene7.com/is/image/asdagroceries/5063089971185",
  "price": 3.98,
  "currency": "GBP",
  "wasPrice": null,
  "unitPrice": 17.53,
  "unitPriceUnit": "kg",
  "loyaltyPrice": null,
  "loyaltyUnitPrice": null,
  "loyaltyScheme": null,
  "loyaltyValidFrom": null,
  "loyaltyValidTo": null,
  "onOffer": true,
  "promotions": [
    {
      "id": "10000824782",
      "text": "Any 2 for £7",
      "type": "multibuy",
      "loyalty": false,
      "offerPrice": null,
      "offerUnitPrice": null,
      "quantity": 2,
      "multibuyPrice": 7.0,
      "validFrom": "2026-02-04T00:00:00Z",
      "validTo": "2026-12-29T23:59:59Z"
    }
  ],
  "promotionText": "Any 2 for £7",
  "size": "227G",
  "sizeValue": 227,
  "sizeUnit": "g",
  "packCount": null,
  "inStock": true,
  "availability": "in stock",
  "category": "Exceptional Coffee & Tea",
  "categoryPath": ["Exceptional By Asda", "Exceptional Food Cupboard & Drinks", "Exceptional Food Cupboard", "Exceptional Coffee & Tea"],
  "rating": 4.25,
  "reviewCount": 4,
  "dietary": ["Vegetarian", "Vegan", "Free from gluten", "Free from milk", "Free from lactose", "Free from egg", "Free from nuts"],
  "labels": [],
  "region": "England",
  "storeId": "4565",
  "details": {
    "description": "Roast and ground coffee",
    "storage": "Store in a cool, dry place. Once opened, store in an airtight container, keep refrigerated and best within 2 weeks.",
    "origin": "Packed In: United Kingdom"
  },
  "sourceType": "search",
  "sourceInput": "asda ground coffee",
  "position": 1,
  "scrapedAt": "2026-10-04T15:52:18Z",
  "error": null,
  "charged": true
}
```

A Rollback looks like this: `"price": 1.0, "wasPrice": 1.1` with a promotion
`{"text": "Rollback, was £1.10", "type": "price-cut", "offerPrice": 1.0}`.

Notes on the fields:

- `price` is the price for the chosen nation; `wasPrice` is set for Rollbacks only. Products marked "Dropped & Locked"
  keep that as a label.
- Asda has no member prices: `loyaltyPrice` is empty. Asda Rewards cashback, which applies to very few products and
  stores, is shown as a promotion while it runs at the chosen store.
- `gtin` comes with details (Asda publishes it on the product page); own-label internal numbers are left empty.
- `dietary` lists the flags Asda sets on the product (including the "Free from" flags it uses for its filters).
- The run's key-value store also holds `RUN-SUMMARY`: products written, what each input returned and why the run
  stopped.

### Use it from code, automations and AI agents

- **API**: run it and get the results in one call: `POST https://api.apify.com/v2/acts/zaiq~asda-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN` with the input as JSON. The API tab on this page has ready-made Python, JavaScript and cURL examples.
- **Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("zaiq/asda-scraper").call(run_input={'searchTerms': ['milk'], 'maxItems': 20})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

- **No code**: connect it to Google Sheets, Zapier, Make or n8n from the Integrations tab, schedule runs in Apify Console, and get a webhook when a run finishes.
- **AI agents (MCP)**: add it as a tool to Claude, Cursor or any MCP client through Apify's MCP server: `https://mcp.apify.com?tools=zaiq/asda-scraper`.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Product scraped (one row written) | $0.003 ($3 per 1,000 products) |
| Product details added (ingredients, allergens, nutrition, barcode; only when switched on) | $0.004 |
| Run start | $0.005 |

Free: products that cannot be found, requests that fail or are blocked, retries and duplicates. Your spending limit
for the run is respected: the run stops cleanly before going over it.

### Limits

- Prices are the ones asda.com shows to shoppers who are not signed in. Personalised Asda Rewards offers are not
  included.
- Stock is for one store per run; run again with another `storeId` for another store.
- Product details need one extra request per product (the product page), so they are slower than listings.
- Up to 10 requests at once (4 by default).
- Check that your use of the data complies with Asda's terms and with the law that applies to you.

### FAQ

**Do I need an Asda account?** No. The Actor sees what any visitor to asda.com sees.

**Are prices different across the UK?** Asda sets prices per nation; choose England, Scotland, Wales or Northern
Ireland with `region`.

**How do I track prices every day?** Put your product numbers in `productIds` and schedule the Actor.

**How do I get every product on offer?** Add `https://www.asda.com/groceries/special-offers/all-offers` under
`categoryUrls` and raise `maxItemsPerSource`, or switch on `offersOnly` for your own searches and categories.

**What if a request fails?** It is retried through another UK home connection. Failed requests are free.

**Can I get the data for Tesco, Sainsbury's or Morrisons too?** Yes, our Tesco, Sainsbury's and Morrisons scrapers
return the same columns.

# Actor input Schema

## `searchTerms` (type: `array`):

Words to search Asda for, one per line, the way you would type them on the site (for example: milk, coffee, pasta). Each term returns up to the per-search limit below.

## `categoryUrls` (type: `array`):

Asda category, aisle or shelf pages to list every product from, for example https://www.asda.com/groceries/chilled-food/milk-butter-cream-eggs/fresh-milk

## `productUrls` (type: `array`):

Asda product pages to check, for example https://www.asda.com/groceries/product/semi-skimmed-milk/asda-british-milk-semi-skimmed-2-pints/538241. Products that cannot be found come back as a free row with an error.

## `productIds` (type: `array`):

Asda product numbers: the number at the end of a product URL. Useful for checking a fixed list of products every day.

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

The run stops after writing this many products in total. You pay only for products written.

## `maxItemsPerSource` (type: `integer`):

Stop each search term or category after this many products. Raise it to list a whole category.

## `offersOnly` (type: `boolean`):

Only products on offer: Rollbacks, multi-buys and meal deals. Applies to searches, categories and product inputs.

## `sort` (type: `string`):

The order Asda returns results in (its own sort options).

## `includeDetails` (type: `boolean`):

Read each product's detail page as well and add its ingredients, allergy advice, nutrition table, storage and origin under `details`. One extra request per product, charged as a separate product-details event.

## `region` (type: `string`):

Asda sets prices separately for each UK nation.

## `storeId` (type: `string`):

Stock (inStock) is checked at this Asda store. 4565 is the store asda.com uses for visitors who have not chosen one.

## `deduplicate` (type: `boolean`):

When a product is found by two searches or categories, write it once (with the first one's search term or category). Switch off to get every search's full list, for example to track search rankings.

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

Asda answers UK home (residential) connections reliably; that is the default and is included in the price.

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

At most this many requests to Asda at the same time (kept low to be polite).

## Actor input object example

```json
{
  "searchTerms": [
    "milk"
  ],
  "maxItems": 20,
  "maxItemsPerSource": 200,
  "offersOnly": false,
  "sort": "relevance",
  "includeDetails": false,
  "region": "england",
  "storeId": "4565",
  "deduplicate": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  },
  "maxConcurrency": 4
}
```

# Actor output Schema

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

Dataset with one row per product (and a free row for each product input that could not be found).

## `summary` (type: `string`):

Products written and charged, what each search, category or product input returned, why the run stopped, requests and traffic.

# 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 = {
    "searchTerms": [
        "milk"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaiq/asda-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 = {
    "searchTerms": ["milk"],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("zaiq/asda-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 '{
  "searchTerms": [
    "milk"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call zaiq/asda-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zaiq/asda-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/I55eYGyW4PAMmkWe7/builds/vaOZkvg4PPbXggHg2/openapi.json
