# Etsy Reviews Scraper: Get Every Review via Official API (`wheaten_steelpan/etsy-reviews-scraper`) Actor

Pull EVERY review from an Etsy shop or listing through Etsy’s official Open API. No scraping, so no DataDome blocks and no captchas — and no “8 reviews out of 3,000”. Returns Etsy’s own review count so you can check the pull was complete. Reviews we cannot return are never charged.

- **URL**: https://apify.com/wheaten\_steelpan/etsy-reviews-scraper.md
- **Developed by:** [Vanja V](https://apify.com/wheaten_steelpan) (community)
- **Categories:**
- **Stats:** 3 total users, 2 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 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.

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

## Etsy Reviews Scraper: Get Every Review via Official API

Pulls every review from an Etsy shop or listing: rating, review text, date, buyer language, buyer
photo, and which listing it was left on.

### Why other scrapers miss reviews

Most Etsy review scrapers read the storefront. The storefront is bot-protected and paginated for
humans, so they tend to stop early. Paying for a shop with 3,000 reviews and getting 8 back is the
usual complaint about review scrapers.

This one uses Etsy's official Open API. It reads reviews in blocks of 100, and Etsy tells it how
many exist, so there is nothing to get blocked by.

### Check the pull yourself

Every run prints Etsy's own review count next to the number of rows you got:

```
1,271 reviews from VintageImageMadness — Etsy reports 1,271. Complete.
```

If those two numbers differ, the run says why:

| reason | meaning |
|---|---|
| `complete` | you have all of them |
| `row-cap` | your "Max reviews" setting stopped it |
| `charge-limit` | the run reached your maximum charge |
| `time-budget` | the run hit its time limit; start it again to continue |
| `rate-limit` | Etsy's daily API quota ran out; try later |
| `etsy-error` | Etsy stopped answering after several retries. Run it again to pick up the rest |

### Pricing

$4.00 per 1,000 reviews returned. No start fee and no per-dataset-item fee.

You are billed for rows you actually receive. If a run stops early for any of the reasons above,
you pay for what arrived. A shop with no reviews costs nothing, and so does a shop name that turns
out not to exist.

There is no cap by default. Leave "Max reviews" blank and you get everything; set it if you would
rather spend less. The median Etsy shop has around 1,800 reviews and large ones run past 15,000, so
it is worth deciding before you start a big shop.

### What you get

One row per review, exportable as CSV, JSON or Excel.

| field | |
|---|---|
| `target` | the shop or listing you asked for |
| `rating` | 1-5 |
| `review` | the review text |
| `hasText` | whether the buyer wrote anything or only left a rating |
| `createdAt` / `updatedAt` | ISO timestamps |
| `language` | the language the buyer wrote in |
| `imageUrl` | buyer photo, where there is one |
| `listingId` / `shopId` / `transactionId` | Etsy's own identifiers |

The run summary, under **Completeness check**, shows rows returned against Etsy's count for each
shop or listing, the stop reason, and anything skipped or not charged.

Buyer IDs are dropped. Etsy's API returns a `buyer_user_id` with every review; this Actor does not
pass it through.

### Input

```json
{
  "shopNames": ["FreedomMockups"]
}
```

Shop names are the `NAME` part of `etsy.com/shop/NAME`. Pasting the full URL works too. You can
pull several shops in one run and mix in individual listings:

```json
{
  "shopNames": ["FreedomMockups", "https://www.etsy.com/shop/VintageImageMadness"],
  "listingIds": ["4512653980", "https://www.etsy.com/listing/1234567890/handmade-mug"],
  "itemLimit": 500,
  "textOnly": true
}
```

Shop names have to match exactly. Etsy's own shop search matches on prefixes, so when there is no
exact match the run stops and lists the closest real names instead of pulling a different seller's
reviews.

### Options

**Max reviews per shop or listing.** Blank means everything. Set a number to spend less.

**Skip reviews with no text.** Etsy lets buyers leave a rating without writing anything. Tick this
and those rows are left out, and you are not billed for them. Across a sample of 16 shops they were
about 5% of reviews, usually 0-3%, though two shops came in at 22% and 33%.

### Limits

Runs stop at 210 seconds and report `time-budget` rather than being killed by the platform. A very
large shop may need more than one run.

Etsy's API has a daily quota shared across everyone using this Actor. If it runs out, the run ends
with `rate-limit`, nothing is charged for what could not be fetched, and you can run it again
later.

Reviews come back in Etsy's own order. There is no date filter because the API does not offer one,
so filter on `createdAt` after exporting.

# Actor input Schema

## `shopNames` (type: `array`):

One or more Etsy shop names, spelled exactly as Etsy spells them. You can find the name in the shop's web address, for example etsy.com/shop/FreedomMockups gives you FreedomMockups. It never contains spaces, and it is often different from the large title at the top of the shop page. Upper and lower case do not matter, but the spelling has to match, because this Actor will not guess between similar shops. A name that does not match stops the run and lists the closest real shop names for you. Every review the shop has is available. Use Max reviews per shop below if you want fewer.

## `listingIds` (type: `array`):

Pull reviews for specific listings instead of, or alongside, whole shops. Accepts a listing ID (1234567890) or a full listing URL.

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

Leave blank to pull EVERY review. That is the default, and it is what this Actor is for. Set a number only if you want to spend less: the median Etsy shop holds about 1,800 reviews and large shops run past 15,000, and each review returned is charged. Reviews that cannot be returned are never charged.

## `textOnly` (type: `boolean`):

Etsy lets a buyer leave stars without writing anything. Tick this to leave those out. You are not charged for them. Measured across 16 real shops: about 5% of reviews are star-only, usually 0-3%, but two shops in the sample were 22% and 33%. Leave it off to get every review, including ratings with no words.

## Actor input object example

```json
{
  "shopNames": [
    "FreedomMockups"
  ],
  "textOnly": false
}
```

# Actor output Schema

## `data` (type: `string`):

One row per review: rating, the review text, the date, the buyer's language and the listing it was left on. This is the product — download it as CSV, JSON or Excel from the Export button.

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

How many reviews were returned against how many Etsy reports exist, per shop or listing, and the reason for any pull that stopped short. Reviews that were not returned were not charged.

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

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

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

```

## MCP server setup

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