# Etsy Scraper - Listings, Shops, Reviews & Keywords (`sourabhbgp/etsy-scraper`) Actor

Scrape Etsy: search listings, get full product details, shop profiles, and every review per listing or shop-wide (thousands, not just the first page), plus keyword suggestions for Etsy SEO. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/sourabhbgp/etsy-scraper.md
- **Developed by:** [Sourabh Kumar](https://apify.com/sourabhbgp) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 scraper: listings, shop profiles, full reviews & keyword research

One actor for the whole of Etsy: search listings by keyword, pull full product details, grab shop profiles and stats, and export every review for a listing or a whole shop. It also returns Etsy's own search suggestions for keyword research.

**$3 per 1,000 results. Same flat rate for every mode.**

Reviews are not capped at the first page. Point it at a shop and it pulls every review across every listing, thousands of them, not just the newest handful.

### Why this scraper?

- 🧾 **Five modes in one actor**, so you are not stitching together a separate scraper for search, details, shops, reviews, and keywords.
- ⭐ **Whole-shop reviews**, the feature no other Etsy scraper ships: every review across a shop's entire catalog, sorted by relevance or date.
- 🛡️ **Bot protection handled for you.** No proxy setup, no browser config, no blocks to babysit.
- 💵 **Flat $3 per 1,000 results** in every mode, with no surprise tiers.
- 🔎 **Keyword research built in**, pulling Etsy's live autosuggest for SEO and listing titles.
- 🧮 **You are billed per result, once.** Duplicate inputs and repeated cards are deduped before you pay.
- 📦 **Rich records**, including price ranges, ratings, review counts, images, shop team, sales, and admirer counts.
- 🌍 **US pricing and currency by default**, with results returned in the storefront you scrape.

### What data can you extract?

<table>
  <tr><td>🏷️ Title</td><td>💲 Price and price range</td><td>⭐ Rating</td><td>🗣️ Review count</td></tr>
  <tr><td>🖼️ Images</td><td>📦 Shipping origin</td><td>🧵 Material</td><td>🗂️ Category path</td></tr>
  <tr><td>🏪 Shop name</td><td>👥 Shop team</td><td>📈 Sales count</td><td>❤️ Admirers</td></tr>
  <tr><td>✍️ Review text</td><td>🙋 Buyer name</td><td>📅 Review date</td><td>🔑 Keyword suggestions</td></tr>
</table>

### Scraping modes

#### 🔎 Search
Find listings by keyword, with optional price range, sort order, and free-shipping filter. Returns title, price, rating, review count, and listing URL per card.

```json
{
  "mode": "search",
  "searchQueries": ["leather wallet"],
  "minPrice": 20,
  "maxPrice": 200,
  "sortBy": "price_asc",
  "freeShippingOnly": false,
  "maxItems": 100
}
````

#### 📄 Listing

Full details for any listing URL or ID: description, price range, currency, rating, review count, all images, material, category breadcrumb, shipping origin, and a sample of reviews.

```json
{
  "mode": "listing",
  "listingUrls": ["https://www.etsy.com/listing/1089150061", "993944520"]
}
```

#### 🏪 Shop

Shop profile and stats: description, logo, banner, team members, rating, review count, total active listings, lifetime sales, admirers, and a grid of listing previews.

```json
{
  "mode": "shop",
  "shopNames": ["Walletree"]
}
```

#### ⭐ Reviews

All reviews for a single listing, or every review across an entire shop. Each row carries the rating, date, text, buyer name, any photo, and the seller's reply.

```json
{
  "mode": "reviews",
  "reviewScope": "shop",
  "reviewSources": ["Walletree"],
  "reviewSort": "recency",
  "maxItems": 1000
}
```

#### 🔑 Keyword

Etsy's own search suggestions for any seed term. Ideal for listing titles, tags, and SEO research.

```json
{
  "mode": "keyword",
  "keywords": ["leather wallet", "engraved ring"]
}
```

### How to scrape Etsy: step by step

1. [Create a free Apify account](https://console.apify.com/sign-up). Takes 30 seconds, no card needed.
2. Open [Etsy Scraper](https://console.apify.com/actors/5a5CiEshLJaau8ger?addFromActorId=5a5CiEshLJaau8ger) in the Apify Console.
3. Pick a mode and paste your input: a search term, a listing URL, a shop name, or a seed keyword.
4. Click **Start**. Most runs finish in one to three minutes.
5. Export as JSON, CSV, or Excel, or pull the results through the API.

### How much does Etsy Scraper cost?

Etsy Scraper uses pay-per-result pricing: **$3 for 1,000 results**, the same in every mode. The Apify Free plan gives you $5 in monthly credits, enough for roughly 1,600 results. The $29/month Starter plan covers about 9,600 results a month. A small per-run start fee (around $0.01) covers the compute to launch each run. In reviews mode, each review counts as one result.

### Input

```json
{
  "mode": "search",
  "searchQueries": ["leather wallet"],
  "minPrice": 20,
  "maxPrice": 200,
  "sortBy": "relevancy",
  "freeShippingOnly": false,
  "maxItems": 100
}
```

| Field | Type | Default | Note |
|---|---|---|---|
| `mode` | string | `search` | One of `search`, `listing`, `shop`, `reviews`, `keyword`. |
| `searchQueries` | array | | Search terms (Search mode). |
| `minPrice` / `maxPrice` | integer | | Price range filter (Search mode). |
| `sortBy` | string | `relevancy` | `relevancy`, `price_asc`, `price_desc`, `most_recent` (Search mode). |
| `freeShippingOnly` | boolean | `false` | Only free-shipping listings (Search mode). |
| `listingUrls` | array | | Listing URLs or numeric IDs (Listing mode). |
| `shopNames` | array | | Shop names or shop URLs (Shop mode). |
| `reviewScope` | string | `listing` | `listing` or `shop` (Reviews mode). |
| `reviewSources` | array | | Listing URLs/IDs, or shop names/URLs (Reviews mode). |
| `reviewSort` | string | `relevancy` | `relevancy` or `recency` (Reviews mode). |
| `keywords` | array | | Seed terms (Keyword mode). |
| `maxItems` | integer | | Stop after this many result rows. Leave empty for no cap. |

### Output

**Search**

```json
{
  "scrapedFrom": "search",
  "query": "leather wallet",
  "id": "1089150061",
  "title": "Brown bifold in Horween Chromexcel leather, personalizable gift for him",
  "price": 89,
  "url": "https://www.etsy.com/listing/1089150061/brown-bifold-in-horween-chromexcel",
  "rating": 4.9,
  "reviewCount": 3100,
  "freeShipping": false
}
```

**Listing**

```json
{
  "scrapedFrom": "listing",
  "id": "1089150061",
  "title": "Brown bifold in Horween Chromexcel leather, personalizable gift for him",
  "shopName": "Walletree",
  "category": "Bags & Purses < Wallets & Money Clips < Wallets",
  "material": "Tiger Thread/Horween Chromexcel Leather",
  "rating": 4.9,
  "reviewCount": 21,
  "price": 89,
  "priceHigh": 95,
  "currency": "USD",
  "shippingOriginCountry": "UA",
  "images": ["https://i.etsystatic.com/..."],
  "imageCount": 10,
  "breadcrumb": ["Bags & Purses", "Wallets & Money Clips", "Wallets"]
}
```

**Shop**

```json
{
  "scrapedFrom": "shop",
  "shopName": "Walletree",
  "slogan": "Personalized Luxury Leather Wallets, the perfect gift!",
  "team": [{ "name": "Ash", "role": "owner" }],
  "rating": 5,
  "reviewCount": 17603,
  "numberOfItems": 217,
  "salesCount": 82792,
  "admirersCount": 3725,
  "onEtsySince": 2021,
  "listingPreviews": [{ "id": "1089150061", "title": "Brown bifold...", "price": 89 }]
}
```

**Reviews**

```json
{
  "scrapedFrom": "reviews",
  "listingId": "1089150061",
  "rating": 5,
  "reviewDate": "Mar 16, 2026",
  "reviewText": "Very nice Horween leather wallet. Well crafted, compact, just what I was looking for.",
  "buyerName": "Robert",
  "hasPhoto": false,
  "sellerResponse": null,
  "listingTitle": "Brown bifold in Horween Chromexcel leather"
}
```

**Keyword**

```json
{
  "scrapedFrom": "keyword",
  "seed": "leather wallet",
  "suggestion": "leather wallet men",
  "type": "keyword"
}
```

### Use cases

- 📊 **Market research.** Compare prices, ratings, and review volume across a category at scale.
- 🔍 **Competitor tracking.** Watch a shop's listings, sales, and admirer counts over time.
- 💬 **Review analysis.** Pull a shop's entire review history for sentiment and product feedback.
- 🧲 **Lead generation.** Surface shops with their team, sales, and profile details.
- 🔑 **SEO and listing optimization.** Mine Etsy's autosuggest for high-intent keywords.
- 🎁 **Trend spotting.** Track what is selling and what shoppers are searching for.
- 🗂️ **Catalog building.** Assemble structured product feeds from search and listing data.

### Limitations

- **Search depth.** A single search query returns up to a few hundred unique listings. To go wider, split by price range or category. When a run cannot reach your `maxItems`, the status says so plainly.
- **Currency on search cards.** Search results carry the price number; full currency and shop name come from listing mode.
- **Shop location.** Etsy does not publish a shop's city or country on the shop page, so `location` is null.
- **Review order.** Reviews sort by relevance or date only, eight per page.
- **Public data only.** The actor reaches what a logged-out visitor sees. Nothing behind a login.

### FAQ

#### How much does Etsy Scraper cost?

Etsy Scraper uses pay-per-result pricing. You pay **$3 for 1,000 results**. The Apify Free plan gives you $5 in usage credits a month, enough for around 1,600 results. If you run regularly, the $29/month Starter plan covers about 9,600 results.

No subscription lock-in. Pause whenever.

#### Is it legal to scrape Etsy?

Scraping public data is generally allowed in the US and most of the EU, as long as you do not collect personal data covered by GDPR or CCPA without a lawful basis. This actor only touches publicly accessible pages, but how you use the output is on you.

Apify's full breakdown: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

#### Can I integrate Etsy Scraper with other tools?

Push results into **Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive**, and more. Apify treats every actor as a webhook source, so anything that consumes webhooks or pulls from an API works.

Full list: [Apify integrations](https://docs.apify.com/platform/integrations).

#### Can I use Etsy Scraper with the Apify API?

Yes. Every run is available via the Apify REST API:

```bash
curl -X POST "https://api.apify.com/v2/acts/sourabhbgp~etsy-scraper/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "search", "searchQueries": ["leather wallet"]}'
```

Docs: [Apify API reference](https://docs.apify.com/api/v2).

#### Can I use Etsy Scraper through an MCP Server?

Yes. Apify ships an MCP server that exposes every actor as a tool, so Claude Desktop, Cursor, and any other MCP-capable client can call Etsy Scraper. Setup: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp).

### Your feedback

Bug, missing field, or odd behavior? Drop a note in the [Issues tab](https://console.apify.com/actors/5a5CiEshLJaau8ger/issues). Reports go to a human and fixes usually ship the same week.

# Actor input Schema

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

What to scrape. Each mode uses its own input field below; the others are ignored.

## `searchQueries` (type: `array`):

One or more search terms, e.g. "leather wallet". Used in Search mode.

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

Minimum listing price filter. Leave empty for no minimum.

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

Maximum listing price filter. Leave empty for no maximum.

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

Result ordering.

## `freeShippingOnly` (type: `boolean`):

Only return listings that ship free.

## `listingUrls` (type: `array`):

Etsy listing URLs (https://www.etsy.com/listing/<id>/...) or bare numeric listing IDs. Used in Listing mode.

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

Etsy shop names (e.g. Walletree) or shop URLs (https://www.etsy.com/shop/Walletree). Used in Shop mode.

## `reviewScope` (type: `string`):

Per-listing reviews, or every review across an entire shop.

## `reviewSources` (type: `array`):

For scope Listing: listing URLs or IDs. For scope Shop: shop names or shop URLs. Used in Reviews mode.

## `reviewSort` (type: `string`):

Review ordering.

## `keywords` (type: `array`):

Seed terms to get Etsy search suggestions / related keywords for. Used in Keyword mode.

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

Stop after this many result rows (across all inputs). Leave empty for no cap. Reviews mode counts each review as a row.

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

Etsy is DataDome-protected and requires residential proxies. Defaults to Apify residential in the US.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "leather wallet"
  ],
  "sortBy": "relevancy",
  "freeShippingOnly": false,
  "listingUrls": [
    "https://www.etsy.com/listing/993944520"
  ],
  "shopNames": [
    "Walletree"
  ],
  "reviewScope": "listing",
  "reviewSources": [
    "https://www.etsy.com/listing/993944520"
  ],
  "reviewSort": "relevancy",
  "keywords": [
    "leather wallet"
  ],
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

View the scraped records in the 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 = {
    "searchQueries": [
        "leather wallet"
    ],
    "listingUrls": [
        "https://www.etsy.com/listing/993944520"
    ],
    "shopNames": [
        "Walletree"
    ],
    "reviewSources": [
        "https://www.etsy.com/listing/993944520"
    ],
    "keywords": [
        "leather wallet"
    ],
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sourabhbgp/etsy-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 = {
    "searchQueries": ["leather wallet"],
    "listingUrls": ["https://www.etsy.com/listing/993944520"],
    "shopNames": ["Walletree"],
    "reviewSources": ["https://www.etsy.com/listing/993944520"],
    "keywords": ["leather wallet"],
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("sourabhbgp/etsy-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "leather wallet"
  ],
  "listingUrls": [
    "https://www.etsy.com/listing/993944520"
  ],
  "shopNames": [
    "Walletree"
  ],
  "reviewSources": [
    "https://www.etsy.com/listing/993944520"
  ],
  "keywords": [
    "leather wallet"
  ],
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call sourabhbgp/etsy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sourabhbgp/etsy-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Etsy Scraper - Listings, Shops, Reviews & Keywords",
        "description": "Scrape Etsy: search listings, get full product details, shop profiles, and every review per listing or shop-wide (thousands, not just the first page), plus keyword suggestions for Etsy SEO. Export to JSON, CSV, or Excel.",
        "version": "0.0",
        "x-build-id": "kXVTv4f84SkcV9Yk2"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sourabhbgp~etsy-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sourabhbgp-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sourabhbgp~etsy-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sourabhbgp-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sourabhbgp~etsy-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sourabhbgp-etsy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "search",
                            "listing",
                            "shop",
                            "reviews",
                            "keyword"
                        ],
                        "type": "string",
                        "description": "What to scrape. Each mode uses its own input field below; the others are ignored.",
                        "default": "search"
                    },
                    "searchQueries": {
                        "title": "Search queries (Search mode)",
                        "type": "array",
                        "description": "One or more search terms, e.g. \"leather wallet\". Used in Search mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "minPrice": {
                        "title": "Min price (Search mode)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum listing price filter. Leave empty for no minimum."
                    },
                    "maxPrice": {
                        "title": "Max price (Search mode)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum listing price filter. Leave empty for no maximum."
                    },
                    "sortBy": {
                        "title": "Sort by (Search mode)",
                        "enum": [
                            "relevancy",
                            "price_asc",
                            "price_desc",
                            "most_recent"
                        ],
                        "type": "string",
                        "description": "Result ordering.",
                        "default": "relevancy"
                    },
                    "freeShippingOnly": {
                        "title": "Free shipping only (Search mode)",
                        "type": "boolean",
                        "description": "Only return listings that ship free.",
                        "default": false
                    },
                    "listingUrls": {
                        "title": "Listing URLs or IDs (Listing mode)",
                        "type": "array",
                        "description": "Etsy listing URLs (https://www.etsy.com/listing/<id>/...) or bare numeric listing IDs. Used in Listing mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "shopNames": {
                        "title": "Shop names or URLs (Shop mode)",
                        "type": "array",
                        "description": "Etsy shop names (e.g. Walletree) or shop URLs (https://www.etsy.com/shop/Walletree). Used in Shop mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "reviewScope": {
                        "title": "Review scope (Reviews mode)",
                        "enum": [
                            "listing",
                            "shop"
                        ],
                        "type": "string",
                        "description": "Per-listing reviews, or every review across an entire shop.",
                        "default": "listing"
                    },
                    "reviewSources": {
                        "title": "Review sources (Reviews mode)",
                        "type": "array",
                        "description": "For scope Listing: listing URLs or IDs. For scope Shop: shop names or shop URLs. Used in Reviews mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "reviewSort": {
                        "title": "Review sort (Reviews mode)",
                        "enum": [
                            "relevancy",
                            "recency"
                        ],
                        "type": "string",
                        "description": "Review ordering.",
                        "default": "relevancy"
                    },
                    "keywords": {
                        "title": "Keywords (Keyword mode)",
                        "type": "array",
                        "description": "Seed terms to get Etsy search suggestions / related keywords for. Used in Keyword mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Stop after this many result rows (across all inputs). Leave empty for no cap. Reviews mode counts each review as a row."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Etsy is DataDome-protected and requires residential proxies. Defaults to Apify residential in the US.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
