# Walmart Scraper - Products, Prices, Sellers & Reviews (`abotapi/walmart-scraper`) Actor

Scrape Walmart.com by keyword, URL, or item ID. Extract prices, was-prices, sellers, marketplace offers, stock, ratings, specs, images, and reviews. Track NEW, UPDATED, REAPPEARED, and EXPIRED items with resume and MCP export.

- **URL**: https://apify.com/abotapi/walmart-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 4 total users, 0 monthly users, 93.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 product records

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

## Walmart Scraper: Products, Prices, Sellers & Reviews

Walmart Scraper turns walmart.com into structured product data. Search by keyword, paste storefront links, or look up specific products by link or item id, and get prices, was-prices, every seller offer, stock status, ratings, specifications, images and the customer reviews the product page publishes. Run search mode for fast listing-level pulls, or turn on detail enrichment for a fully specced record, then export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **Reviews and offers ride the same request as the product page.** Every walmart.com product page ships its reviews and its seller offers in the same document as the product itself, so this actor returns them from one detail read instead of a separate call per review or per offer.
- **A listing page returns full product rows for free.** A search or browse page carries its whole result grid as structured data, so a listing-level pull returns price, was-price, rating, review count, seller and stock for every card with no per-product request at all.
- **Filters that are actually true.** The storefront's own sort and filter parameters are sent with the request, so filtering narrows results before they count against your item cap. Sponsored tiles are injected into the grid regardless of the active filters, and this actor re-checks every row so "hide sponsored" and "sold by Walmart" mean what they say.
- **Search keywords and pasted links in one run.** Mix keyword searches with pasted search, browse, shop or category links; each is walked on its own, page by page, with the storefront's own pagination bound.
- **Monitoring built in.** Label every record NEW, UPDATED, REAPPEARED or EXPIRED across scheduled runs, resume an interrupted crawl, and export results through MCP connectors.
- **Structured failures.** A run the storefront refuses fails loudly with a clear message instead of returning an empty dataset that looks like a search with no matches.

### Use Cases

- **Price and stock monitoring:** track prices, was-prices and availability for a product list or a category, and get alerted only to what actually changed.
- **Marketplace and seller research:** compare offers, seller types and fulfillment options across the same product to study competition on a listing.
- **Catalog and assortment analysis:** pull a whole category or search result to study assortment, brand coverage and pricing bands.
- **Review and reputation analysis:** collect ratings, rating breakdowns and customer review text for products you sell or compete with.
- **Comparison shopping and repricing tools:** feed live prices and seller data into your own pricing or comparison app through the API.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

| Field | Example |
| --- | --- |
| `kind` | `"product"` (the only record type this actor returns) |
| `itemId` | `"000000000000"` |
| `title` | `"Sample Product Name 15-inch Laptop"` |
| `brand` | `"Sample Brand"` |
| `price` / `wasPrice` | `199.0` / `249.0` |
| `currency` / `priceRangeLow` / `priceRangeHigh` | `"USD"` / a variant group's "from" price range, when a card has no single price |
| `rating` / `reviewCount` | `4.5` / `123` |
| `ratingHistogram` / `recommendedPercentage` | star breakdown and percent who'd recommend it (`fetchDetails` only) |
| `sellerName` / `sellerType` | `"Sample Seller"` / `"INTERNAL"` |
| `offerCount` / `offers` | `2` / every seller offer with price, condition and fulfillment (`fetchDetails` only) |
| `availabilityStatus` / `inStock` | `"IN_STOCK"` / `true` |
| `condition` / `model` / `upc` | `"New"` / `"SAMPLE-MODEL-01"` / `"0000000000000"` (`fetchDetails` only) |
| `categoryPath` | `"Electronics / Sample Category / Sample Subcategory"` |
| `badges` / `sponsored` | `["Sample badge"]` / `false` |
| `fulfillmentOptions` / `returnPolicy` | `["DELIVERY", "PICKUP", "SHIPPING"]` / returnable, free returns, window in days, policy text (`fetchDetails` only) |
| `specifications` / `productHighlights` / `images` / `imageUrl` | name and value pairs the product page publishes (`fetchDetails` only) / the full gallery and the first image |
| `description` / `shortDescription` / `reviews` | full and short product copy / up to 10 reviews, each with rating, title, text, date, verified-purchase marker, helpful votes and, when the page shows one, the seller's reply; the product page publishes at most 10 (`includeReviews` only) |
| `priceScope` / `searchQuery` / `resultPage` / `resultPosition` | the postal code, city, state and store the prices were quoted for (`fetchDetails` only) / which keyword, result page and grid slot a product was found at (search mode only) |
| `usItemId` / `productId` / `itemType` / `fulfillmentType` | the item id again under the name other Walmart scrapers use, the catalog product id, the item class and the fulfilment type (`itemType` and `fulfillmentType` appear when the page publishes them) |
| `name` / `availability` / `averageRating` / `numberOfReviews` | the same values as `title` / `availabilityStatus` / `rating` / `reviewCount`, under the alternate names |
| `ratingCounts` / `priceInfo` / `variantList` | the star breakdown again as `{"1".."5"}` counts (`fetchDetails` only), `{price, priceDisplay, wasPrice, unitPrice}`, and each size or colour variant with ids, price, options and availability (cards carry ids; `fetchDetails` adds prices and options) |
| `sellerAverageRating` / `additionalOfferCount` / `shippingRestrictions` | seller rating, number of other offers and any shipping restriction, when the product page publishes them (`fetchDetails` only) |
| `url` / `sourceUrl` | the product page link / the listing page this record came from |
| `changeType` / `changedFields` / `firstSeenAt` / `lastSeenAt` | incremental mode only: `"NEW"`, `"UPDATED"`, `"UNCHANGED"`, `"REAPPEARED"` or `"EXPIRED"`, the fields that changed, and when the record was first and last seen |

Product mode looks up product links or bare item ids directly and always returns a fully enriched record, the same shape detail enrichment adds to a search-mode record.

**Output views.** The dataset has five views in the Console: **Products** (the overview grid), **Product detail** (specifications, brand, model, UPC, return policy), **Reviews**, **Seller offers**, and **Changes since the last run** (incremental mode: change type, changed fields, first and last seen). Each run also stores a run summary under the `OUTPUT` key of its default key-value store.

### How to Use

1. Keep the default **search** mode, add one or more keywords, and run. Paste storefront links (search, browse, shop or category) instead of, or alongside, keywords if you already have them; filters already in a pasted link are kept and this run's own filters are added on top.
2. Narrow with the storefront's own filters: sort, brands, sold by, condition, deals, minimum rating, availability and price range. Turn on **Hide sponsored results** for a clean assortment view.
3. Turn on **Fetch product details** for full specs, offers and return policy, and **Include customer reviews** for the reviews the product page itself publishes (no extra request beyond the detail read).
4. Set **Max products** to control run size and cost, then click **Start**. Switch to **products** mode instead when you already know which items you want, and list their links or item ids.

**Quick keyword search:**

```json
{
  "mode": "search",
  "queries": ["desk lamp"],
  "maxItems": 20
}
```

**Filtered search, sorted and priced within a range:**

```json
{
  "mode": "search",
  "queries": ["running shoes"],
  "sortBy": "price_low",
  "retailerType": "walmart",
  "minPrice": 20,
  "maxPrice": 80,
  "excludeSponsored": true,
  "maxItems": 50
}
```

**A whole category, with full detail and reviews:**

```json
{
  "mode": "search",
  "searchUrls": ["https://www.walmart.com/browse/electronics/3944"],
  "fetchDetails": true,
  "includeReviews": true,
  "maxItems": 100
}
```

**Look up specific products:**

```json
{
  "mode": "products",
  "productInputs": ["10000000001", "https://www.walmart.com/ip/10000000002"],
  "fetchDetails": true
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/walmart-scraper").call(run_input={"mode": "search", "queries": ["desk lamp"], "maxItems": 20})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["title"], product["price"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/walmart-scraper').call({ mode: 'search', queries: ['desk lamp'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### Caps and pagination

**Max products** stops the whole run once that many records have been returned; each keyword and each pasted link is otherwise walked to its own natural end. **Max result pages** bounds how many pages are walked per keyword or link; `0` walks every page the storefront offers for that search, up to an internal ceiling of 100 pages per scope, then stops at the storefront's own last page or when a page returns nothing new.

A keyword or link that shares products with an earlier keyword or link in the same run only returns each shared product once, credited to whichever scope reached it first. Known limitation: one list of already-collected products is shared by every keyword and link in the run, and a walk treats a page on which every product is already on that list as the end of its results. So when any page of a later keyword or link (its first page or a later one) holds only products an earlier keyword or link already returned, that walk stops there and never requests its remaining pages, silently dropping products that only appear on those pages. In incremental mode such a walk still counts as having reached its end, so products tracked from a previous run that sat on those unrequested pages can be reported `EXPIRED` even though they are still listed. If you run several closely related keywords or overlapping links, run each as a separate actor call (with its own `stateKey` if you monitor them) instead of one combined run.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) skips products already collected by an earlier run: paste its run or dataset ID and those products are neither returned nor charged again. It works as expected in **products** mode. Known limitation in **search** mode: the collected products are added to the same already-collected list described under Caps and pagination, so a keyword or link walk stops at the first page on which every product was already collected. An interrupted crawl has usually collected all of page 1, so the resumed walk typically ends right there and returns nothing from that keyword's or link's later pages, and the run can finish with zero records. To pick up a large search crawl, start a fresh run rather than a resumed one.
- Resume and incremental mode together: products skipped because the resumed run already collected them are never added to the incremental state, so a later incremental run reports them as `NEW` again. Run a normal (non-resumed) incremental pass afterward so the tracked baseline reflects everything.
- **Incremental mode** (`incrementalMode`) is for scheduled runs over the same search or link. Each record is classified `NEW`, `UPDATED` (with `changedFields`), `UNCHANGED` (suppressed and not billed unless `emitUnchanged` is on), `REAPPEARED`, or `EXPIRED` (only after a run whose walks all reached their end, never after a capped or resumed run, and only with `emitExpired` on; see the overlapping-scope limitation under Caps and pagination). `stateKey` names or shares the stored state; leave it empty and the actor derives one from the run's search and filter setup. When a complete scan does tombstone EXPIRED products, that batch is not itself limited by **Max products**, so a monitoring run with a low cap and a large tracked baseline can return more records than the cap on the run where products disappear.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify, Settings, Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field (`mcpConnectors`). (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.
4. Optionally set `maxNotifyListings` to cap how many items are written to each connector per run (default 50).

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

`searchUrls` and `productInputs` come pre-filled in the Console form with one example link per link shape, but their stored default is empty, so an API call or saved task that omits them runs only the keywords or ids it supplies. Max products is capped at one million records per run.

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` (keywords and pasted listing links) or `products` (specific product links or item ids). |
| `queries` | array | `laptop` | Search mode: keywords to search, each walked separately. |
| `searchUrls` | array | one example link per supported listing shape | Search mode: walmart.com search (keyword, paged, sorted, faceted, price-range), browse, category (`/cp`), shop, curated (`/c/kp`) and seller storefront (`/seller/<id>`, `/global/seller/<id>`) links. The page, sort, facets and price range in a pasted link are kept; a link to page 2 starts at page 2. A link that is not a supported listing shape is skipped with a warning in the log. |
| `productInputs` | array | one example per supported product shape | Product mode: product links (with or without the name slug), reviews-page links (`/reviews/product/<id>`) or bare item ids, mixed freely. Unrecognised entries are skipped with a warning in the log. |
| `startUrls` | array | (none) | Any walmart.com links in one list: product links are read as products, listing links (search, browse, shop, category, seller) are walked. Works in either mode, in addition to the fields above. Each product link is read from its product page and carries the detail-enrichment unit. When Start URLs is filled and Search keywords still holds the untouched prefilled `laptop` with no Storefront links, the Start URLs are the run's only target and the demo keyword is not searched; type any other keyword (or links) to run them as well. |
| `maxProductsPerStartUrl` | integer | `0` | Stop each listing link in `startUrls` after this many returned products. `0` means no per-link cap; Max products still applies to the whole run. |
| `enqueueProductVariants` | boolean | `false` | Also read every size or colour variant a product lists as its own record (one extra product page each, counted in Max products; each variant record carries the detail-enrichment unit). |
| `sortBy` | string | `best_match` | Storefront sort order: best match, price low to high, price high to low, best seller, highly rated, or new arrivals. |
| `brands` | array | (none) | Keep only products from these brands, spelled as the storefront spells them; several are combined as "any of these". |
| `retailerType` | string | `any` | Narrow to who sells the item: Walmart, Pro Sellers, or marketplace sellers fulfilled by Walmart. |
| `condition` | string | `any` | Narrow to new, restored or pre-owned items. |
| `specialOffer` | string | `any` | Narrow to reduced price, clearance or rollback items. |
| `minRating` | string | `any` | Narrow to 4 stars and up, or 3 stars and up. |
| `inStockOnly` | boolean | `false` | Hide items the storefront currently cannot sell or deliver. |
| `excludeSponsored` | boolean | `false` | Drop advertising tiles from the results, even though the storefront injects them regardless of the filters above. |
| `minPrice` | integer | (none) | Only keep products priced at or above this amount (USD). |
| `maxPrice` | integer | (none) | Only keep products priced at or below this amount (USD). |
| `fetchDetails` | boolean | `false` | Read each product's own page for brand, model, UPC, full description, specifications, all images, every seller offer, return policy and rating breakdown. Charged once per record enriched. |
| `includeReviews` | boolean | `false` | Add the reviews the product page itself publishes. Reads the same page as `fetchDetails`, so it costs no extra request, but it does turn detail enrichment on and it takes part in change detection. |
| `maxReviews` | integer | `10` | How many of the product page's own reviews to keep per product, newest-first, up to the 10 the page publishes. |
| `maxItems` | integer | `20` | Maximum number of records to return across the whole run. `0` is unlimited. |
| `maxPages` | integer | `0` | Maximum result pages walked per keyword or pasted link. `0` walks every page the storefront offers for that search. |
| `resumeFromRunId` | string | (none) | Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for products already collected there. |
| `incrementalMode` | boolean | `false` | Turn on for scheduled monitoring. The first run returns every matching product as `NEW`; later runs return only `NEW`, `UPDATED` and `REAPPEARED` products by default. |
| `stateKey` | string | (none) | Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. |
| `emitUnchanged` | boolean | `false` | Also return, and bill, products that have not changed since the last run, marked `UNCHANGED`. |
| `emitExpired` | boolean | `false` | Also return, and bill, products present in a previous run but no longer found, marked `EXPIRED`. Only produced after a run that fully scanned the tracked search or link. |
| `ignoreFieldsForChanges` | array | `[]` | Incremental mode only. Field names (matched at any depth, for example `badges` or `sponsored`) that never count as a change. A product whose only differences are in these fields stays `UNCHANGED` and is not returned or billed as `UPDATED`. The fields still appear on rows that are returned. Adding a name never re-emits tracked products. |
| `proxy` | object | Apify Proxy, US residential | Connection settings. walmart.com serves search and product pages only on a US residential exit; a datacenter exit is refused. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

```json
{
  "kind": "product",
  "itemId": "000000000000",
  "url": "https://www.walmart.com/ip/Sample-Product-Name/000000000000",
  "title": "Sample Product Name 15-inch Laptop",
  "brand": "Sample Brand",
  "model": "SAMPLE-MODEL-01",
  "upc": "0000000000000",
  "shortDescription": "A sample product description written for this example.",
  "price": 199.0,
  "wasPrice": 249.0,
  "currency": "USD",
  "rating": 4.5,
  "reviewCount": 123,
  "ratingHistogram": {"5": 80, "4": 25, "3": 10, "2": 5, "1": 3},
  "recommendedPercentage": 90,
  "sellerName": "Sample Seller",
  "sellerType": "INTERNAL",
  "offerCount": 2,
  "offers": [
    {"sellerName": "Sample Seller", "price": 199.0, "condition": "New",
     "fulfilledByWalmart": false, "isBuyBoxWinner": true},
    {"sellerName": "Sample Reseller", "price": 209.5, "condition": "New",
     "fulfilledByWalmart": true, "isBuyBoxWinner": false}
  ],
  "availabilityStatus": "IN_STOCK",
  "inStock": true,
  "condition": "New",
  "categoryPath": "Electronics / Sample Category / Sample Subcategory",
  "badges": ["Sample badge"],
  "sponsored": false,
  "fulfillmentOptions": ["DELIVERY", "PICKUP", "SHIPPING"],
  "returnPolicy": {"returnable": true, "freeReturns": true, "windowDays": 90,
                   "text": "Free 90 day returns"},
  "specifications": [{"name": "Sample specification", "value": "Sample value"}],
  "reviews": [
    {"reviewId": "000000000", "rating": 5, "title": "Sample review title",
     "text": "Sample review text written for this example.",
     "submittedAt": "1/1/2026", "authorNickname": "SampleShopper",
     "verifiedPurchase": true, "helpfulVotes": 3}
  ],
  "priceScope": {"postalCode": "00000", "city": "Sample City", "state": "ST",
                 "storeId": "00000"},
  "searchQuery": "sample keyword",
  "sourceUrl": "https://www.walmart.com/search?q=sample+keyword",
  "resultPage": 1,
  "resultPosition": 4,
  "changeType": "NEW",
  "changedFields": [],
  "firstSeenAt": "2026-09-04T02:00:00+00:00",
  "lastSeenAt": "2026-09-04T02:00:00+00:00"
}
```

Every value above is illustrative and fictional, invented for this example, not a real walmart.com product, price, seller or customer. A real run's reviews carry only what walmart.com prints publicly beside each review: a rating, text and the reviewer's public display name, never an email address, phone number or profile link, because the product page does not publish those.

### Plan Requirement

Pay per event: one unit per returned record, plus an actor start event, plus a detail-enrichment unit for each record actually enriched from its product page. The detail-enrichment unit is charged per record, one at a time as each enriched record is delivered, not as a single total at the end of the run. A record whose product page could not be read still ships, uncharged, and a suppressed unchanged record in incremental mode is neither returned nor charged. **A US residential Apify Proxy exit is required**; the default proxy setting is already set to this. walmart.com serves its home page on other connections but refuses search and product pages on a datacenter exit.

### FAQ

#### How much does it cost?

You pay per record returned, plus one detail-enrichment unit for every record actually read from its own product page: search records when `fetchDetails` (or `includeReviews`) is on, and always for product-mode records, product links in `startUrls`, and variants read through `enqueueProductVariants`. A record whose product page could not be read ships uncharged for detail enrichment. Reviews add no extra charge beyond that. The **Pricing** tab shows the current rates. Use **Max products** to cap the cost of any run.

#### Is it legal to scrape walmart.com?

This actor collects only publicly available product data that walmart.com prints on its own pages. You are responsible for how you use it: follow Walmart's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product prices and specifications are generally facts, but images, descriptions and review text may be subject to third-party rights.

#### Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Each run then returns only new, updated and reappeared products, and unchanged ones are not billed unless you turn `emitUnchanged` on.

#### Why do reviews cost the same as detail enrichment?

Because they come from the same request. The product page walmart.com serves carries the specifications, offers and reviews in one document, so turning `includeReviews` on reads the same page `fetchDetails` reads; you're never billed twice for the same read.

#### Why did my run fail instead of returning an empty dataset?

If the storefront refuses every request, the run stops with a clear message so "no products matched" is never confused with "nothing could be read". Run it again in a few minutes, and check that the proxy is set to a US residential exit. The messages you may see in the run log:

- When the selected connection is unavailable to your account (Apify free plans do not include residential proxies), the log says: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs."
- When pages are then read over the backup connection: "Served over the backup connection (the default connection was unavailable)." Set `WALMART_COM_ALTERNATE_CONNECTION=0` in the run's environment variables to disable the backup connection.
- If the proxy connection is refused for the account and no page could be read: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
- If residential access is unavailable and the backup connection also cannot load the pages: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Walmart pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
- If every page request failed for another reason: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."

If only some keywords or pages could be read, you still get what was found.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 More scrapers you might like

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🧩 <a href="https://apify.com/abotapi/gopuff-prices-assortment-scraper"><b>Gopuff Scraper</b></a><br>Scrape Gopuff, the US quick-commerce delivery store, by location or product: prices...</td><td>🛒 <a href="https://apify.com/abotapi/bigw-marketplace-scraper"><b>BIG W Marketplace Scraper</b></a><br>Scrape BIG W Marketplace seller listings from bigw.com.au: name, brand, price, was-price...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/mediamarkt-de-scraper"><b>MediaMarkt Germany Scraper</b></a><br>Scrape MediaMarkt.de products by keyword or URL. Extract current and original prices...</td><td>👗 <a href="https://apify.com/abotapi/next-uk-product-scraper"><b>Next.co.uk Scraper</b></a><br>Scrape Next.co.uk: keyword search, category and product-listing walks, full product...</td></tr>
<tr><td>🧩 <a href="https://apify.com/abotapi/allegro-pl-scraper"><b>Allegro Scraper</b></a><br>Scrape Allegro marketplace (allegro.pl) by keyword or URL. Extract product offers...</td><td>🧩 <a href="https://apify.com/abotapi/bigw-marketplace-scraper-lite"><b>BIG W Marketplace Scraper Lite</b></a><br>Scrape BIG W products &amp; specials from bigw.com.au: name, title, brand, seller, price...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/walmart-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

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

Choose 'search' to run keyword searches and walk pasted search, browse or category links. Choose 'products' to look up specific products by their walmart.com link or item id.

## `queries` (type: `array`):

One or more keywords to search on walmart.com, for example 'laptop' or 'coffee maker'. Each keyword is searched separately and walked page by page.

## `searchUrls` (type: `array`):

Paste walmart.com listing links to walk, for example https://www.walmart.com/browse/electronics/3944 or a search link you copied from your browser. Filters you had already selected in that link are kept, and this run's own filters are added on top. Product links do not belong here; use Product mode for those.

## `productInputs` (type: `array`):

Only used when mode = products. Mix freely: full product links such as https://www.walmart.com/ip/Apple-MacBook-Air/19699754154 or bare item ids such as 19699754154.

## `startUrls` (type: `array`):

Paste walmart.com links in one list. Product links are read as products; search, browse, shop, category and seller links are walked as listings. Works in either mode, in addition to anything entered above, except that the untouched prefilled keyword 'laptop' is not searched when Start URLs is filled and no Storefront links are given. Each entry can be a plain link or a {"url": ...} object. Each product link is read from its product page and carries the detail-enrichment unit.

## `maxProductsPerStartUrl` (type: `integer`):

Stop each listing link in Start URLs after this many returned products. 0 means no per-link cap (the overall Max products still applies).

## `enqueueProductVariants` (type: `boolean`):

When on, every size or colour variant that a product lists is read as its own record too (one extra product page each, counted in Max products; each variant record carries the detail-enrichment unit). Off by default.

## `sortBy` (type: `string`):

The storefront's own sort order for search results.

## `brands` (type: `array`):

Optional. Keep only products from these brands, exactly as the storefront spells them (for example 'Apple', 'HP', 'Lenovo'). Several brands are combined as 'any of these'.

## `retailerType` (type: `string`):

Optional. Narrow to who sells the item: Walmart itself, Pro Sellers, or marketplace sellers whose orders Walmart fulfills.

## `condition` (type: `string`):

Optional. Narrow to new, restored or pre-owned items.

## `specialOffer` (type: `string`):

Optional. Narrow to items currently carrying a deal flag.

## `minRating` (type: `string`):

Optional. The storefront publishes two rating buckets and this filter uses them; each returned row is also checked against the number, so a row below the bucket never reaches the dataset.

## `inStockOnly` (type: `boolean`):

Optional. Hide items the storefront currently cannot sell or deliver.

## `excludeSponsored` (type: `boolean`):

Optional. Drop advertising tiles from the results. The storefront injects sponsored products into the grid regardless of the filters above, so turn this on when you want a clean, filter-true assortment view.

## `minPrice` (type: `integer`):

Optional. Only keep products priced at or above this amount.

## `maxPrice` (type: `integer`):

Optional. Only keep products priced at or below this amount.

## `fetchDetails` (type: `boolean`):

Read each product's own page to add brand, model, UPC, full description, specifications, all images, every seller offer, the return policy and the rating breakdown. Charged once per record enriched. Leave off for a fast, cheap listing-level pull.

## `includeReviews` (type: `boolean`):

Add the customer reviews the product page itself publishes, each with the reviewer's public display name, rating, title, text, date and verified-purchase marker. This reads the same product page as Fetch product details, so it costs no extra request and no extra charge; it does turn detail enrichment on. Reviews take part in change detection, so leave this off for price-only monitoring.

## `maxReviews` (type: `integer`):

How many of the product page's own reviews to keep per product, newest-first as the storefront orders them. The product page publishes up to 10, which is the ceiling here; the full rating breakdown and review counts are returned regardless.

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

Maximum number of records to return across the whole run. Use 0 for unlimited.

## `maxPages` (type: `integer`):

Maximum result pages walked per keyword or pasted link. 0 = walk every page the storefront offers for that search; the run then stops at Max products, at the storefront's own last page, or when a page returns nothing new.

## `proxy` (type: `object`):

The storefront answers search and product pages only on US residential connections. A datacenter exit is refused, so leave this on the default unless you are supplying your own US residential exits.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for products already collected there. For recurring monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. State is kept separately for each keyword, link, filter and detail setup; use State key when you want to name or deliberately share a monitoring campaign.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to derive a key automatically from this run's search and filter setup.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, never when Max products capped it or when Resume was used. This returns, and bills, extra synthetic rows.

## `ignoreFieldsForChanges` (type: `array`):

Optional. Field names that must NOT count as a change in incremental mode, for example "badges" or "sponsored". A product whose only differences are in these fields is treated as UNCHANGED, so it is not returned or billed as UPDATED. Names match at any nesting depth. The fields still appear in the output of rows that are returned.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "laptop"
  ],
  "searchUrls": [
    "https://www.walmart.com/search?q=laptop",
    "https://www.walmart.com/search?q=laptop&page=2",
    "https://www.walmart.com/search?q=laptop&sort=price_low&facet=brand%3AApple",
    "https://www.walmart.com/search?q=laptop&min_price=300&max_price=600",
    "https://www.walmart.com/browse/electronics/3944",
    "https://www.walmart.com/browse/electronics/3944?page=2",
    "https://www.walmart.com/cp/electronics/3944",
    "https://www.walmart.com/shop/deals",
    "https://www.walmart.com/c/kp/laptops",
    "https://www.walmart.com/seller/101216456",
    "https://www.walmart.com/global/seller/101216456"
  ],
  "productInputs": [
    "https://www.walmart.com/ip/Apple-MacBook-Air/19699754154",
    "https://www.walmart.com/ip/19699754154",
    "https://www.walmart.com/reviews/product/19699754154"
  ],
  "maxProductsPerStartUrl": 0,
  "enqueueProductVariants": false,
  "sortBy": "best_match",
  "retailerType": "any",
  "condition": "any",
  "specialOffer": "any",
  "minRating": "any",
  "inStockOnly": false,
  "excludeSponsored": false,
  "fetchDetails": false,
  "includeReviews": false,
  "maxReviews": 10,
  "maxItems": 20,
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `detail` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `offers` (type: `string`):

No description

## `changes` (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 = {
    "mode": "search",
    "queries": [
        "laptop"
    ],
    "searchUrls": [
        "https://www.walmart.com/search?q=laptop",
        "https://www.walmart.com/search?q=laptop&page=2",
        "https://www.walmart.com/search?q=laptop&sort=price_low&facet=brand%3AApple",
        "https://www.walmart.com/search?q=laptop&min_price=300&max_price=600",
        "https://www.walmart.com/browse/electronics/3944",
        "https://www.walmart.com/browse/electronics/3944?page=2",
        "https://www.walmart.com/cp/electronics/3944",
        "https://www.walmart.com/shop/deals",
        "https://www.walmart.com/c/kp/laptops",
        "https://www.walmart.com/seller/101216456",
        "https://www.walmart.com/global/seller/101216456"
    ],
    "productInputs": [
        "https://www.walmart.com/ip/Apple-MacBook-Air/19699754154",
        "https://www.walmart.com/ip/19699754154",
        "https://www.walmart.com/reviews/product/19699754154"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/walmart-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": "search",
    "queries": ["laptop"],
    "searchUrls": [
        "https://www.walmart.com/search?q=laptop",
        "https://www.walmart.com/search?q=laptop&page=2",
        "https://www.walmart.com/search?q=laptop&sort=price_low&facet=brand%3AApple",
        "https://www.walmart.com/search?q=laptop&min_price=300&max_price=600",
        "https://www.walmart.com/browse/electronics/3944",
        "https://www.walmart.com/browse/electronics/3944?page=2",
        "https://www.walmart.com/cp/electronics/3944",
        "https://www.walmart.com/shop/deals",
        "https://www.walmart.com/c/kp/laptops",
        "https://www.walmart.com/seller/101216456",
        "https://www.walmart.com/global/seller/101216456",
    ],
    "productInputs": [
        "https://www.walmart.com/ip/Apple-MacBook-Air/19699754154",
        "https://www.walmart.com/ip/19699754154",
        "https://www.walmart.com/reviews/product/19699754154",
    ],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/walmart-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": "search",
  "queries": [
    "laptop"
  ],
  "searchUrls": [
    "https://www.walmart.com/search?q=laptop",
    "https://www.walmart.com/search?q=laptop&page=2",
    "https://www.walmart.com/search?q=laptop&sort=price_low&facet=brand%3AApple",
    "https://www.walmart.com/search?q=laptop&min_price=300&max_price=600",
    "https://www.walmart.com/browse/electronics/3944",
    "https://www.walmart.com/browse/electronics/3944?page=2",
    "https://www.walmart.com/cp/electronics/3944",
    "https://www.walmart.com/shop/deals",
    "https://www.walmart.com/c/kp/laptops",
    "https://www.walmart.com/seller/101216456",
    "https://www.walmart.com/global/seller/101216456"
  ],
  "productInputs": [
    "https://www.walmart.com/ip/Apple-MacBook-Air/19699754154",
    "https://www.walmart.com/ip/19699754154",
    "https://www.walmart.com/reviews/product/19699754154"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/walmart-scraper --silent --output-dataset

```

## MCP server setup

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