# Walmart Reviews API Scraper (`shakamize/walmart-reviews-scraper`) Actor

Scrape Walmart customer reviews: rating, title, text, date, verified-purchase and syndication flags, helpful votes and photos, with the product's full rating-by-star breakdown on every row. Filter by star, by verified purchase, and by date. Priced per review; no reviews means no charge.

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

## Pricing

from $2.50 / 1,000 reviews

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?

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

## How to integrate an Actor?

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

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

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

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

# README

## Walmart Reviews API Scraper

Turns a Walmart product into structured customer reviews: rating, title, text,
date, verified-purchase and syndication flags, helpful and unhelpful votes, the
photos and video reviewers attached, and the seller each review was left
against.

Every row also carries **the product's full rating-by-star breakdown** - how
many ratings sit at one star, two, three, four and five - alongside the two
review counts Walmart publishes and the seller, category and image of the
product itself.

Priced **per review**, at $0.003. A product with no reviews is never charged,
and neither is an item id Walmart does not have.

Use it to monitor customer complaints on your own listing or a competitor's,
measure sentiment and its movement over time, track a product's star
distribution, or pull verified-purchase reviews for product research. For
Walmart prices, stock or catalogue data this is not the right tool: it returns
per-review records plus the product's own rating summary, not product listings.

### The two review counts, and why they differ

This is the first thing to understand about Walmart review data, and the thing
most likely to look like a scraper losing your results.

Walmart publishes **two different counts** and they are not close:

| Product                          | Ratings | Reviews with text |
| -------------------------------- | ------- | ----------------- |
| Great Value Whole Vitamin D Milk | 373,963 | **26,104**        |
| Grazeful Dairy A2/A2 Milk        | 9       | **1**             |

The larger number counts every star rating. The smaller one counts the ratings
that carry **written text** - and only those are ever listed on the reviews
page. A product with 9 ratings can list a single review, and that is Walmart's
behaviour rather than a fault.

Both numbers are on every row, as `totalReviewCount` and `reviewsWithTextCount`,
so the gap is visible before it becomes a surprise.

### Ratings by star, on every row

`starsBreakdown` gives the histogram over **every rating the product holds**,
not over the reviews on the page:

```json
{ "oneStar": 20893, "twoStars": 5847, "threeStars": 10933, "fourStars": 29141, "fiveStars": 307149 }
```

A missing count stays `null` rather than becoming `0`. Zero is a real answer
here - a product genuinely can have no one-star ratings - so reading an absence
as zero would report a fact Walmart never stated.

### Star filtering that does not read the whole product first

Walmart's own reviews page offers **no star filter over plain HTTP**: the stars
on the page are a client-side call, so a scraper asking for one-star reviews
normally has to page through everything and throw most of it away. On a product
with 26,104 listed reviews that is 2,610 requests to find a few hundred rows.

Walmart **does** sort by rating server side. So when you filter by star and
leave the sort on **Automatic**, the run orders by rating in the direction of
your band - ascending for 1 and 2 stars, descending for 4 and 5 - and stops the
moment the stream leaves it.

Measured live: twenty one-star reviews out of 26,104 came back in **two
requests** - the two pages the twenty rows themselves need, and nothing more.

The stop is only claimed on the two rating sorts. On any other ordering a
matching review can still appear on a later page, so the run pages normally
rather than truncating your answer and calling it a filter.

### Verified purchases, filtered by Walmart rather than after the fact

**Verified purchases only** puts `vp=true` on the request, which is Walmart's
own filter. Measured on the milk product: the listed count fell from 26,100 to
24,363 and the returned reviews changed, so the pages fetched contain nothing
else and no request is spent on rows that would be thrown away.

Every other filter runs over what came back, and says so.

### Syndicated reviews are told apart

Walmart carries some reviews in from a brand's own site rather than collecting
them itself. `isSyndicated` and `syndicationSource` record this on every row,
and **Exclude syndicated reviews** drops them.

Walmart writes `bazaarvoice` as the external source on its **own** reviews - it
is the platform it collects them with, not a brand it took them from. Reading
that as syndication would mark almost every review on the site as syndicated and
make the flag useless, so it is not.

### How to sort Walmart reviews by newest, oldest or most helpful

Six orderings, all Walmart's own and applied server side:

| Option              | What Walmart does      |
| ------------------- | ---------------------- |
| Most relevant       | Walmart's own ranking  |
| Newest first        | most recent submission |
| Oldest first        | earliest submission    |
| Most helpful        | most upvoted           |
| Highest rated first | five stars down        |
| Lowest rated first  | one star up            |

Each returns a genuinely different set, verified live on 2026-08-30 - the oldest
sort reached 2010 on a product whose relevance page starts in 2026.

### Dates, and the filter over them

`reviewSubmissionTime` is US `M/D/YYYY`. It is parsed month-first into an ISO
`date`, with the original kept in `dateText`. A date that cannot be read reports
`date: null` and keeps its text rather than guessing - reading `3/4/2026`
day-first would silently move it to April and quietly break every date filter.

**Only reviews since** takes an absolute date (`2026-01-15`) or a relative one
(`30 days`, `6 months`, `1 year`). A review Walmart published no readable date
for is dropped rather than kept. With **Newest first** the run also stops paging
once it is past the cutoff.

### What an unknown value does

Every filter drops a review whose value it cannot check, rather than keeping it.
A review with no rating is not a match for a star filter; a review with no date
is not inside a cutoff. An unknown value is not evidence that a review
qualifies, and treating it as one is how a run returns three-star reviews to
someone who asked for one-star ones.

### Errors are specific

| What happened                        | `error`             | Charged |
| ------------------------------------ | ------------------- | ------- |
| Walmart has no product with that id  | `product_not_found` | no      |
| The product has no reviews with text | `no_reviews_found`  | no      |
| The page could not be read           | `request_failed`    | no      |
| Walmart served a bot check           | `blocked`           | no      |

A wrong item id is never reported as "no reviews": that would tell you your id
is valid and unloved when it is simply wrong. Every product you ask for leaves a
row of some kind, so a product that produced nothing is never silent.

An entry that is not a Walmart product URL or item id **stops the run and names
itself**, rather than being skipped. A run that quietly reads four of the five
products you gave it and reports success is the complaint this field already
carries.

### Reviewer names are personal data

`reviewer` - nickname, author id and reviewer badges - is `null` unless
**Include reviewer profile** is on. It is personal data, protected by GDPR in
the EU and by comparable rules elsewhere. Enable it only if you have a
legitimate basis for collecting it.

### Walmart reviews scraper pricing, pay per review

**$0.003 per review.** Nothing else is charged.

- A product with no reviews is not charged for.
- An item id Walmart does not have is not charged for.
- A page that could not be read is not charged for.
- Reviews already stored are kept and charged when a later page fails; the run
  says how many came back.

Walmart lists ten reviews per request, so a review costs a tenth of a request.
Measured on the platform over 300 reviews: **$0.0000928 a request**, so the
price clears its cost by three orders of magnitude and even the worst case - a
product whose single written review takes a whole request - is comfortable.

### Input reference for every Walmart reviews setting

| Field                    | What it does                                                           |
| ------------------------ | ---------------------------------------------------------------------- |
| `productUrls`            | Product URLs, reviews URLs, or bare item ids. Required.                |
| `maxReviewsPerProduct`   | Cap per product. Empty means everything Walmart lists.                 |
| `maxReviews`             | Cap across the whole run.                                              |
| `sort`                   | Automatic, or one of Walmart's six orderings.                          |
| `filterByRatings`        | Keep only these stars. Automatic sorting makes this cheap.             |
| `verifiedPurchaseOnly`   | Walmart's own filter, applied to the request.                          |
| `excludeSyndicated`      | Drop reviews carried in from a brand site.                             |
| `reviewsCutoffDate`      | Absolute or relative. Undated reviews are dropped.                     |
| `withMediaOnly`          | Keep only reviews with a photo or video.                               |
| `includeAspectSentiment` | Walmart's per-aspect mention counts. On by default.                    |
| `includeReviewerProfile` | Personal data. Off by default.                                         |
| `proxyConfiguration`     | Defaults to Apify's unblocking service, which is what reaches Walmart. |

### Walmart review data you get back, as JSON, CSV or Excel

One record per review. Every one carries its product, so the dataset is usable
without a join.

```json
{
  "reviewId": "404696209",
  "itemId": "10450114",
  "productUrl": "https://www.walmart.com/ip/Great-Value-Whole-Vitamin-D-Milk-Gallon/10450114",
  "productName": "Great Value Whole Vitamin D Milk, Gallon",
  "sellerName": "Walmart.com",
  "categoryPath": ["Food", "Dairy & Eggs", "Milk"],
  "averageRating": 4.6,
  "totalReviewCount": 373963,
  "reviewsWithTextCount": 26104,
  "starsBreakdown": {
    "oneStar": 20893,
    "twoStars": 5847,
    "threeStars": 10933,
    "fourStars": 29141,
    "fiveStars": 307149
  },
  "rating": 5,
  "title": "It's a good value and has true \"SELL BY\" dates.",
  "text": "Walmart's own brand, Great Value, is true to its name in the dairy aisle...",
  "date": "2025-11-14",
  "dateText": "11/14/2025",
  "isVerifiedPurchase": true,
  "isSyndicated": false,
  "helpfulVotes": 7,
  "unhelpfulVotes": 0,
  "recommended": true,
  "fulfilledBy": "Walmart",
  "media": null,
  "reviewer": null,
  "sort": "relevancy",
  "page": 1,
  "position": 2,
  "scrapedAt": "2026-08-30T09:15:00.000Z"
}
```

### How it is tested

Fixtures prove the page they came from and nothing else, so the gate before
publishing is a **live sweep across unrelated departments** - grocery,
electronics, furniture, pet, toys and apparel - asserting invariants rather than
values:

- the star breakdown sums to the product's own rating count, on every review
- no review is dated in the future or before Walmart had reviews
- no `reviewId` appears twice and no position is reused
- every review belongs to the product whose page it came from
- coverage per field is above **its own** floor, not one floor for all of them
- a verified-only run returns nothing unverified
- a one-star filter returns only one-star reviews, in four requests rather than
  thousands
- a product with no reviews stores nothing and charges nothing

### FAQ

#### How do I get only verified purchases?

Set `verifiedPurchaseOnly: true`. The filter is applied by Walmart itself rather
than after the fact, so you are not charged for reviews that get fetched and
discarded. A run on 2026-09-01 returned **60 of 60 verified on each of two
products**, with `dropped 0 that did not match the filters`.

#### How do I get only recent reviews, newest first?

Set `"sort": "recent"` and `reviewsCutoffDate`, which takes an absolute date
(`2026-01-15`) or a relative one (`30 days`, `6 months`, `1 year`).

Prefer the cutoff over guessing a count. On a high-velocity product the **200
most recent reviews spanned five days**, so "the last 200" and "the last month"
are very different requests.

#### What is a syndicated review, and can I exclude it?

A syndicated review was written on a manufacturer's or another retailer's site
and republished on Walmart. It is a real opinion, but it is not evidence about
Walmart fulfilment. `isSyndicated` and `syndicationSource` are on every row, and
`excludeSyndicated: true` drops them.

Measure your own category before assuming it matters: on a Walmart-brand grocery
item, an unfiltered control run was 192 of 200 verified and **0 syndicated**.

#### Why do I get fewer reviews than the review count on the listing?

Those are two different populations. `totalReviewCount` counts star ratings;
`reviewsWithTextCount` counts reviews with words in them, and only the second is
scrapeable. On one product measured those were **44,981 and 5,406**; on another,
373,927 and roughly 25,000.

Budget from `reviewsWithTextCount`.

#### Am I charged if the product does not exist?

No. The run says so and stores nothing:

```
WARN  10309061: Walmart has no product with item id 10309061. Nothing was charged.
```

A review removed by a filter before it is stored is not charged either.

#### Can I pass item IDs instead of URLs?

Yes. `productUrls` takes full URLs and bare item IDs interchangeably, which
matters when the product list came out of a spreadsheet rather than a browser.

### Telemetry

The Actor reports run health to its maintainer: error codes, the build number,
and per-field counts. On a failure it also sends a capped sample of the failed
requests, including **the Walmart URL you asked for**. It carries no personal
data, but it is your input, and this section says so rather than leave you to
find out. Your proxy configuration and the scraped reviews are never sent.

# Actor input Schema

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

The products whose reviews you want. Accepts a full Walmart product URL (<code>https://www.walmart.com/ip/…/10450114</code>), a reviews URL (<code>/reviews/product/10450114</code>) or a bare item id (<code>10450114</code>) - the <code>usItemId</code> that every row carries. An entry that cannot be read stops the run with a message naming it, rather than being skipped quietly.

## `maxReviewsPerProduct` (type: `integer`):

Cap the reviews kept per product. Leave empty for everything Walmart lists, which pages ten at a time and runs to roughly ten thousand - a product with 26,104 listed reviews is 2,610 requests, so the field is prefilled low rather than left open. Raise it for a real scrape. Note that Walmart lists only reviews that carry <b>written text</b>: a product with 373,963 ratings listed 26,104 of them, and both numbers are on every row.

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

Stop the whole run after this many reviews, across every product. Prefilled with the two prefilled products at their per-product cap, so a first run is cheap to try; clear it for no overall cap.

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

Order Walmart returns the reviews in. This is Walmart's own ordering, applied server side. <b>Automatic</b> keeps Walmart's relevance order, except when you filter by star: it then sorts by rating so the stars you asked for come first and paging can stop as soon as they run out, instead of reading everything else on the way.

## `filterByRatings` (type: `array`):

Keep only reviews at these star ratings. Walmart offers no star filter on the page it serves, so this is applied to what was read - but with <b>Automatic</b> sorting the run orders by rating first, which makes it cheap rather than exhaustive. A review with no rating is dropped, never assumed to qualify.

## `verifiedPurchaseOnly` (type: `boolean`):

Keep only reviews carrying Walmart's Verified Purchase badge. <b>Walmart applies this itself</b>, so the pages fetched contain nothing else and no request is spent on reviews that would be thrown away.

## `excludeSyndicated` (type: `boolean`):

Drop reviews Walmart syndicated in from a brand's own site rather than collected itself. Every row records this either way, in <code>isSyndicated</code> and <code>syndicationSource</code>.

## `reviewsCutoffDate` (type: `string`):

Drop reviews older than this. Absolute (<code>2026-01-15</code>) or relative (<code>30 days</code>, <code>6 months</code>, <code>1 year</code>). A review Walmart published no readable date for is dropped rather than kept. With <b>Newest first</b> the run also stops paging once it is past the cutoff.

## `withMediaOnly` (type: `boolean`):

Keep only reviews carrying at least one image or video.

## `includeAspectSentiment` (type: `boolean`):

Walmart's own per-aspect mention counts for the product - flavour, value, quality and so on - computed over every review it holds rather than the ones on the page. Repeated on each row, so turn it off for a smaller dataset.

## `includeReviewerProfile` (type: `boolean`):

A reviewer's nickname and author id are personal data, protected by GDPR in the EU and by comparable rules elsewhere. Enable this only if you have a legitimate basis for collecting it. Off by default.

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

Defaults to Apify's unblocking service, which is what makes Walmart reachable over plain HTTP. Changing this is rarely useful: a datacenter or plain residential address is served a bot check instead of the page, measured 2026-08-30.

## Actor input object example

```json
{
  "productUrls": [
    "https://www.walmart.com/ip/Great-Value-Whole-Vitamin-D-Milk-Gallon/10450114",
    "1446707820"
  ],
  "maxReviewsPerProduct": 15,
  "maxReviews": 30,
  "sort": "auto",
  "verifiedPurchaseOnly": false,
  "excludeSyndicated": false,
  "reviewsCutoffDate": "6 months",
  "withMediaOnly": false,
  "includeAspectSentiment": true,
  "includeReviewerProfile": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

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

Every review returned for the products you asked for, deduplicated across pages.

# 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 = {
    "productUrls": [
        "https://www.walmart.com/ip/Great-Value-Whole-Vitamin-D-Milk-Gallon/10450114",
        "1446707820"
    ],
    "maxReviewsPerProduct": 15,
    "maxReviews": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("shakamize/walmart-reviews-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 = {
    "productUrls": [
        "https://www.walmart.com/ip/Great-Value-Whole-Vitamin-D-Milk-Gallon/10450114",
        "1446707820",
    ],
    "maxReviewsPerProduct": 15,
    "maxReviews": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("shakamize/walmart-reviews-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 '{
  "productUrls": [
    "https://www.walmart.com/ip/Great-Value-Whole-Vitamin-D-Milk-Gallon/10450114",
    "1446707820"
  ],
  "maxReviewsPerProduct": 15,
  "maxReviews": 30
}' |
apify call shakamize/walmart-reviews-scraper --silent --output-dataset

```

## MCP server setup

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