# Etsy Reviews Scraper (`mlg14/etsy-reviews-scraper`) Actor

Collect public shop reviews with ratings, review text, dates, listing details, buyer display fields, seller responses, and shop context.

- **URL**: https://apify.com/mlg14/etsy-reviews-scraper.md
- **Developed by:** [MLG Data](https://apify.com/mlg14) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 results

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

## Etsy Reviews Scraper

Collect public Etsy shop reviews and export review data to JSON, CSV, or Excel. This Etsy reviews scraper accepts shop names or shop URLs and aims to return a flat record for each accessible review, with ratings, text, dates, listing context, public buyer fields, and seller responses. It is an Etsy reviews API alternative for workflows that need structured public feedback from specific shops.

**Validation:** the golden run collected 30 real reviews from one public shop, with all required fields present. The actor reads the public reviews page through its `?format=rss` route. The normal shop and listing pages, and the public review specification, were blocked in the same test environment. When a target has no accessible reviews, the run fails clearly instead of returning a successful empty dataset.

### What data can you extract from Etsy?

The dataset uses one flat item per review. Fields that the public reviews page does not expose are `null`. The scraper does not infer missing buyer IDs, receipt IDs, seller replies, or listing images. The validated run filled review ID, rating, text, date, shop, and listing URL for all 30 rows.

| Field | Description | Example format |
| --- | --- | --- |
| `reviewKey` | Stable key derived from the shop and review ID | `"07fb906eb5ae597db0651820"` |
| `reviewId` | Review card identifier from the public page | `"5132250084"` |
| `receiptId` | Receipt identifier; not exposed on the tested page | `null` |
| `rating` | Star rating from one to five | `5` |
| `review` | Public written review after HTML entities are decoded | `"Exactly as described."` |
| `reviewedAt` | Review date shown in the attribution | `"2026-09-26"` |
| `buyerUserId` | Buyer numeric identifier; not exposed on the tested page | `null` |
| `buyerRealName` | Public buyer display name | `"Diana"` |
| `buyerLoginName` | Public buyer profile slug | `"3mujrq3t"` |
| `listingId` | Identifier of the reviewed listing | `"1234567890"` |
| `listingTitle` | Title of the reviewed listing | `"Handmade item"` |
| `listingUrl` | Direct listing link | `"https://www.etsy.com/listing/1234567890"` |
| `listingImageUrl` | Listing image link, when included with the review | `null` |
| `reviewPhotoUrl` | Photo attached by the buyer, when present | `null` |
| `sellerName` | Shop associated with the review | `"SampleShop"` |
| `sellerUrl` | Link to that shop | `"https://www.etsy.com/shop/SampleShop"` |
| `shopAverageRating` | Shop rating when provided with the record | `4.9` |
| `shopReviewCount` | Review count shown on the shop review page | `2075` |
| `sellerResponse` | Public seller reply to the review, if present | `null` |

The `reviewKey` is derived from the shop name and public review ID. It is designed for deduplication within and across runs; it is not a source review ID. The `reviewId` field preserves the card identifier. `receiptId` and `buyerUserId` remain null because the tested public page does not expose them.

### How to scrape Etsy reviews

1. Enter one or more public shop names in `shop_name`. A full shop URL is also accepted. The shop name is extracted from URLs shaped like `https://www.etsy.com/shop/SampleShop`.
2. Set `itemLimit` to control the total number of review rows. Set `maxReviewsPerShop` when collecting the same number of records from each shop matters.
3. Run the actor. It requests the public shop reviews route and extracts the visible review cards across pages.
4. Check the run status. A failed run with an access error means the site denied public review access in that session. An empty successful export is not used to hide an access failure.
5. Once a run produces rows, open the default dataset and export it as JSON, CSV, or Excel. Use `reviewKey` to deduplicate records after combining runs.

The actor does not require account credentials. It does not attempt to access order details, private messages, unpublished reviews, or content behind a buyer or seller login.

### Input

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `shop_name` | String array | Required; one shop suggested in the form | Public shop names or full shop URLs. |
| `itemLimit` | Integer | `100` | Maximum total reviews. Use `0` for no total cap. |
| `maxReviewsPerShop` | Integer | `0` | Maximum reviews for each shop. Use `0` for no per shop cap. |
| `proxyConfiguration` | Object | Standard proxy configuration | Proxy for public requests. |

Example input:

```json
{
  "shop_name": ["RosysPatterns"],
  "itemLimit": 30,
  "maxReviewsPerShop": 30
}
```

The golden test uses one public shop and requires at least 30 real review rows. It passed with 30 rows. Entering multiple shops is useful when comparing public feedback across product categories or sellers, but each additional shop adds requests and may encounter its own access limit. The total item limit applies across all shops. The per shop limit applies independently to each target.

Shop URLs should point to the shop page rather than an individual listing. A listing URL is not currently a valid target. If you have only a listing URL, first find its seller's public shop name and use that shop name as the input. The actor validates names before making requests so a malformed name fails quickly.

### Output example

A real item from the validated 30-row run is shown below. The text is shortened; the other values are unchanged.

```json
{
  "reviewKey": "07fb906eb5ae597db0651820",
  "reviewId": "5132250084",
  "receiptId": null,
  "rating": 5,
  "review": "Excellent pattern, and the instructions were clear...",
  "reviewedAt": "2026-09-26",
  "buyerUserId": null,
  "buyerRealName": "Diana",
  "buyerLoginName": "3mujrq3t",
  "listingId": "1862330257",
  "listingTitle": "Open Back Halter Dress Tie Front Dress Beginner Sewing Pattern PDF INSTANT DOWNLOAD",
  "listingUrl": "https://www.etsy.com/listing/1862330257/open-back-halter-dress-tie-front-dress?ref=shop_review",
  "listingImageUrl": "https://i.etsystatic.com/6652811619/r/il/12ab19/6652811619/il_170x135.6652811619_1zi5.jpg",
  "reviewPhotoUrl": null,
  "sellerName": "RosysPatterns",
  "sellerUrl": "https://www.etsy.com/shop/RosysPatterns",
  "shopAverageRating": 4.6,
  "shopReviewCount": 2075,
  "sellerResponse": null
}
```

The default dataset is the output. Each accepted record includes a one to five star rating, nonempty review text, a shop name and shop URL, and a stable key derived from the review ID. A row may have null values for buyer IDs, listing image, review photo, or seller response. Downstream workflows should treat those fields as optional.

### Use cases

- **Product feedback tracking:** A shop owner can track public comments about materials, fit, packaging, shipping expectations, and customization requests when the source is accessible.
- **Listing improvement:** Compare the language in reviews with a listing's title and description to see whether buyers use different terms for the same item.
- **Quality monitoring:** Group ratings over time and inspect review text for recurring defects or successful changes. This requires dates to be present in the public record.
- **Competitive research:** Compare public review themes across several shops, while keeping source attribution and respecting the platform's terms.
- **Support triage:** Find public seller replies and follow up on repeated concerns using the public shop page as the source of truth.
- **Catalog analysis:** Join review records to listing IDs or URLs when those fields are available. This can show which products attract feedback rather than only a shopwide average.

These uses depend on the actor returning data from each chosen shop. The golden run verifies one shop and 30 rows; other shops and longer histories may have different coverage. Private buyer or order data is outside the scope of this scraper.

### How much does it cost to scrape Etsy reviews?

The configured pay per result rate is **$4.00 per 1,000 delivered review rows**. At that rate, 30 delivered reviews cost $0.12, 100 cost $0.40, and 1,000 cost $4.00 in result charges. Platform usage is included in this result price. Check the run's pricing display before use because the actor has not been published.

The item cap controls the maximum number of delivered rows, not the number of pages requested. A shop with few visible reviews will return fewer rows than requested even when access works. A shop that denies requests may return none and fail. More page requests can consume platform resources or proxy capacity; the examples above describe result charges, not a guarantee that every requested quantity is obtainable.

### Tips for best results

Start with one known public shop and a modest `itemLimit` such as 30. Check a sample of returned review text, ratings, listing links, and dates against the public reviews page. After a successful run, expand to more shops. Use `maxReviewsPerShop` for balanced comparisons and `itemLimit` for a total budget cap.

Use the `reviewKey` when appending data from scheduled runs. It prevents identical records from being counted twice. Store `sellerUrl` and `listingUrl` along with your analysis so an analyst can reopen the source context when a value looks unusual. Review text should be treated as user generated content; quotations, product claims, and sentiment labels need human interpretation.

Some reviews contain only a rating on the site. This actor currently requires nonempty review text before emitting a row, so rating only feedback is outside its present output. HTML entities are decoded in written reviews. The actor uses the text displayed on the public reviews page; that page may display a translation. It does not manufacture dates or identities from surrounding page content.

### Limits

The normal shop and listing pages returned HTTP 403 in the remote checks, including a browser attempt and a residential proxy session. The public review specification also returned HTTP 403. The reviews page with `format=rss` returned review cards on pages 1, 2, and 3 and supported a successful 30-row golden run. The alternate URL is an HTML page despite the `rss` query value. It may change or be blocked later, so monitor item counts and fill rates.

The actor checks up to 100 review page numbers and stops when a page yields no new reviews. The tested shop showed 14 review cards per page. The site may impose a smaller page cap, expose only a subset of reviews, change its page structure, or return different fields by market and shop. The actor does not claim full historical coverage. It deduplicates rows that recur across pages.

Public buyer display names, profile slugs, review photos, listing images, and seller responses may be absent. The tested page did not expose buyer numeric IDs or receipt IDs, so those fields were null. A seller may have deleted a listing or hidden a response. A date can be missing or formatted differently across locales. Validate field fill rates before feeding this dataset into a dashboard, search index, or sentiment report.

### Use with automated workflows

The input schema and output fields can be used in an automated workflow. Two example requests are:

- “Collect up to 30 public reviews from this shop and group the returned feedback by rating and listing.”
- “Check these shop reviews weekly, deduplicate by `reviewKey`, and summarize recurring product complaints with links to the listing.”

An automated workflow should check the run status before reading the dataset. If the run failed because access was denied, it should report that failure rather than presenting an empty chart as evidence that the shop has no reviews. It should also preserve nulls in optional fields rather than substituting invented buyer or listing details.

### FAQ

**Is it legal to collect public reviews?** Laws and site terms vary. Use only public data, follow the site's terms and applicable privacy law, and avoid misuse of personal data. The actor does not access account only content.

**Do I need a proxy?** Requests use the configured proxy. The validated reviews route worked with the default proxy settings. Other routes may still deny access.

**How fast is it?** The validated 30-review run finished in about 26 seconds. Run time varies with the number of pages, shops, retries, and proxy conditions.

**Can I schedule it?** Yes. Monitor the run status and item count, not just the schedule trigger, because access and page structure may change.

**Can I export to a spreadsheet?** Yes. The successful default dataset can be exported as CSV or Excel.

**Why are some fields empty?** The public source may omit them. Buyer identity, receipt IDs, seller replies, listing images, and shop rating are not guaranteed on every review.

**Can it scrape reviews for a single listing?** The current input targets shops. A listing specific target is not implemented. Listing IDs and URLs appear in output only when a public review record includes them.

### Integrations

The default dataset can feed the platform API, webhooks, schedules, spreadsheet imports, and workflow services. Use the run status as a gate before sending data to a downstream system. Retain `reviewKey` for deduplication and the seller and listing URLs for source checks. The successful golden run verifies the path for one shop; monitor other shops separately.

### Support

Open an issue on the Issues tab; we reply within 24h and add fields on request.

# Actor input Schema

## `shop_name` (type: `array`):

Public shop names or shop URLs to collect reviews from.

## `itemLimit` (type: `integer`):

Maximum reviews across all shops; 0 means no limit.

## `maxReviewsPerShop` (type: `integer`):

Maximum reviews from each shop; 0 means no per-shop limit.

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

Proxy configuration for public page requests.

## Actor input object example

```json
{
  "shop_name": [
    "RosysPatterns"
  ],
  "itemLimit": 100,
  "maxReviewsPerShop": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Public reviews in the default dataset.

# 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 = {
    "shop_name": [
        "RosysPatterns"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mlg14/etsy-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 = { "shop_name": ["RosysPatterns"] }

# Run the Actor and wait for it to finish
run = client.actor("mlg14/etsy-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 '{
  "shop_name": [
    "RosysPatterns"
  ]
}' |
apify call mlg14/etsy-reviews-scraper --silent --output-dataset

```

## MCP server setup

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