# Etsy Product Listings and Shop Scraper (`scrapers_lat/etsy-scraper`) Actor

Scrape Etsy product listings by search query, shop name or listing URL. Get title, price, sale price, currency, shop, rating, reviews, sales, tags, categories, images and description. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers\_lat/etsy-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (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 $18.91 / 1,000 listing results

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

[![Etsy Product Listings and Shop Scraper](https://scrapers.lat/banners/etsy-scraper.png)](https://console.apify.com/actors/LD0qQJsb5cOQgQOxx/input)

## Etsy Product Listings and Shop Scraper

Here is one real result, with every field the actor returns (arrays trimmed for space):

```json
{
  "listingId": "1241528786",
  "listingUrl": "https://www.etsy.com/listing/1241528786/personalized-leather-rfid-wallet",
  "listingTitle": "Personalized Leather RFID Wallet, Engraved Genuine Leather Custom Wallet, Anniversary Gift For Him, Husband, Boyfriend, Men, Father, Dad",
  "price": 28,
  "currency": "USD",
  "salePrice": null,
  "onSale": false,
  "rating": 4.9,
  "reviewCount": 7750,
  "itemSales": 40152,
  "shopName": "PremiumEngrave",
  "shopUrl": "https://www.etsy.com/shop/PremiumEngrave",
  "tags": ["Leather Wallet", "Personalized Wallet", "Engraved Wallet", "Mens Wallet", "RFID Leather Wallet", "Gift For Him"],
  "categories": ["Bags & Purses", "Wallets & Money Clips", "Wallets"],
  "images": ["https://i.etsystatic.com/35016605/r/il/a5f633/4007318605/il_fullxfull.4007318605_mj36.jpg"],
  "imageCount": 10,
  "primaryImage": "https://i.etsystatic.com/35016605/r/il/a5f633/4007318605/il_fullxfull.4007318605_mj36.jpg",
  "description": "This Personalized Leather RFID Wallet is the perfect Engraved Genuine Leather Custom Wallet...",
  "isDigital": false,
  "freeShipping": true,
  "shopLocation": "United States",
  "shopFoundedYear": 2021,
  "shopTotalListings": 214,
  "shopSalesTotal": 40152,
  "shopAnnouncement": null,
  "shopPolicies": null,
  "aiCategory": "Wallets",
  "aiMaterials": ["Genuine Leather", "Argentinian Leather", "Nylon (RFID blocking)"],
  "aiTargetBuyer": "Someone buying a personalized gift for a man",
  "aiSeoKeywords": ["personalized wallet", "rfid wallet", "engraved wallet", "mens leather wallet", "anniversary gift for him"],
  "source": "etsy.com",
  "observedAt": "2026-08-20T03:15:00.000Z"
}
```

The most complete Etsy listing scraper available. Search by keyword, pull a whole shop, or pass listing URLs, and get a clean record per product with title, price, sale price, currency, rating, review count, shop sales, tags, category breadcrumb, all image URLs, description, and digital and free shipping flags. Shop level trust signals (shop sales and rating) and the seller's own tags come standard, so you can compare products and sellers, not just prices.

**📥 [Input](https://apify.com/scrapers_lat/etsy-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/etsy-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/etsy-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/etsy-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-Etsy-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

Give the actor a search query, a shop name, or a list of listing URLs and it returns a normalized record per product. Each record has the listing title, current price and currency, sale price when discounted, the listing rating and review count, the shop name and URL, the shop sales count, the seller's tags, the category breadcrumb, every product image URL, the full description, and flags for digital downloads and free shipping. You can filter a keyword search by minimum and maximum price and choose the sort order.

Two optional add-ons enrich each listing when you turn them on. Shop details fetches the seller's shop page to add location, the year the shop opened, total active listings, total sales, the shop announcement and policy text. The AI listing summary infers the product category, likely materials, the ideal target buyer and high intent SEO keywords. Everything is handled for you: you never configure logins, headers or anything else. Numbers are parsed, missing values are returned as `null`, and each record carries the `listingUrl` and an `observedAt` timestamp.

### Quickstart

Open the actor, paste this into the input, and press Run. It returns leather wallet listings with prices, ratings and shops.

```json
{
  "searchQuery": "leather wallet",
  "minPrice": 15,
  "maxPrice": 80,
  "sortBy": "Top Reviews",
  "maxResults": 25
}
```

You can also pull a whole shop, or target exact listings by URL:

```json
{
  "shopName": "PremiumEngrave",
  "shopDetails": true,
  "maxResults": 50
}
```

```json
{
  "listingUrls": ["https://www.etsy.com/listing/1241528786/personalized-leather-rfid-wallet"]
}
```

### Input reference

| Name | Type | Required | Description | Example |
|---|---|---|---|---|
| `searchQuery` | string | one input required | Keyword to search Etsy for. | `"leather wallet"` |
| `shopName` | string | one input required | An Etsy shop name (the part after etsy.com/shop/). All of that shop's listings are collected. | `"PremiumEngrave"` |
| `listingUrls` | array of strings | one input required | Full Etsy listing URLs to scrape directly. | `["https://www.etsy.com/listing/1241528786/..."]` |
| `minPrice` | integer | no | Keep only listings priced at or above this amount. | `15` |
| `maxPrice` | integer | no | Keep only listings priced at or below this amount. | `80` |
| `sortBy` | string | no | Result order for keyword searches: Relevance, Lowest Price, Highest Price, Most Recent, Top Reviews. | `"Top Reviews"` |
| `maxResults` | integer | no | Maximum listings to collect per run. Free plans are capped at 10. | `25` |
| `shopDetails` | boolean | no | Paid add-on. Add shop location, founding year, total listings, total sales, announcement and policies. Default `false`. | `true` |
| `aiListingSummary` | boolean | no | Paid add-on. Add an AI category, materials, target buyer and SEO keywords. Default `false`. | `false` |

Provide at least one of `searchQuery`, `shopName` or `listingUrls`.

### Output reference

| Name | Type | Description |
|---|---|---|
| `listingId` | string | Etsy listing id |
| `listingUrl` | string | Etsy listing page URL |
| `listingTitle` | string | Listing title |
| `price` | number | Current price (the original price when the listing is on sale) |
| `currency` | string | Currency code |
| `salePrice` | number | Discounted sale price when the listing is on sale |
| `onSale` | boolean | Whether the listing is on sale |
| `rating` | number | Listing star rating |
| `reviewCount` | integer | Number of reviews |
| `itemSales` | integer | Shop sales count |
| `shopName` | string | Shop name |
| `shopUrl` | string | Shop page URL |
| `tags` | array | The seller's listing tags |
| `categories` | array | Category breadcrumb |
| `images` | array | Listing image URLs |
| `imageCount` | integer | Number of images |
| `primaryImage` | string | First image URL |
| `description` | string | Listing description |
| `isDigital` | boolean | Whether the item is a digital download |
| `freeShipping` | boolean | Whether free shipping is offered |
| `shopLocation` | string | Shop location (shop details add-on) |
| `shopFoundedYear` | integer | Year the shop opened (shop details add-on) |
| `shopTotalListings` | integer | Active listings in the shop (shop details add-on) |
| `shopSalesTotal` | integer | Total shop sales (shop details add-on) |
| `shopAnnouncement` | string | Shop announcement (shop details add-on) |
| `shopPolicies` | string | Shop policy summary (shop details add-on) |
| `aiCategory` | string | AI inferred product category (AI add-on) |
| `aiMaterials` | array | AI inferred materials (AI add-on) |
| `aiTargetBuyer` | string | AI inferred target buyer (AI add-on) |
| `aiSeoKeywords` | array | AI inferred SEO keywords (AI add-on) |
| `source` | string | Data source |
| `observedAt` | string | ISO timestamp collected |

### Run via API and CLI

Start a run with the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~etsy-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"leather wallet","minPrice":15,"maxResults":25}'
```

Or with the Apify CLI:

```bash
apify call scrapers_lat/etsy-scraper \
  --input '{"searchQuery":"leather wallet","sortBy":"Top Reviews"}'
```

### Fetch results

Download the dataset items once the run finishes:

```bash
curl "https://api.apify.com/v2/acts/scrapers_lat~etsy-scraper/runs/last/dataset/items?token=YOUR_TOKEN&format=json"
```

Swap `format=json` for `csv` or `xlsx` to export to a spreadsheet.

### Billing and limits

This actor is billed pay per result. You are charged one primary `result` event per listing returned. Optional add-ons are billed separately and only when they actually return data: `shop_details` is charged only when the shop page yields real data, and `ai_listing_summary` is charged only when a usable AI summary is returned. A one time `apify-actor-start` event covers run initialization.

- Failed or empty lookups are never charged. A listing that cannot be loaded is skipped and never billed.
- Free Apify plans are capped at 10 results per run, and the paid add-ons are disabled on free plans. Upgrade for higher volumes.
- Set a spend limit with `maxTotalChargeUsd` and the actor stops returning billable results once that limit is reached.

### FAQ and troubleshooting

**How do I search Etsy?** Put a keyword in `searchQuery`, a shop name in `shopName`, or paste listing URLs in `listingUrls`. You can combine a search with price filters and a sort order.

**Can I scrape a full shop?** Yes. Set `shopName` to the shop's handle and the actor collects that shop's listings up to `maxResults`.

**What are the shop trust signals?** Every record includes the shop name, shop URL and the shop sales count so you can gauge seller reliability. The shop details add-on adds location, founding year, total listings and total sales.

**Do I need an Etsy login or any keys?** No. You only provide a search query, shop name or listing URLs.

**Why is a field null?** Etsy does not publish that value for that listing. Missing values are returned as `null` so the record shape stays consistent.

**Empty result?** Confirm the search query, shop name or listing URLs are correct. Listings that cannot be loaded are skipped and are not billed.

### More scrapers at scrapers.lat

- [Yelp Business Leads & Reviews Scraper](https://apify.com/scrapers_lat/yelp-scraper)
- [Glassdoor Company Ratings, Reviews & Salary Scraper](https://apify.com/scrapers_lat/glassdoor-scraper)
- Browse the full catalog at [scrapers.lat](https://scrapers.lat)

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Etsy.

# Actor input Schema

## `searchQuery` (type: `string`):

A keyword to search Etsy for, for example 'leather wallet', 'personalized necklace' or 'wedding invitation'. Leave empty if you are scraping a specific shop or listing URLs.

## `shopName` (type: `string`):

An Etsy shop name (the part after etsy.com/shop/, for example 'BeadboatSupplies'). All listings from that shop will be collected.

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

One or more full Etsy listing URLs (https://www.etsy.com/listing/123456789/...) to scrape directly.

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

Only keep listings priced at or above this amount (in the listing currency). Leave empty for no minimum.

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

Only keep listings priced at or below this amount (in the listing currency). Leave empty for no maximum.

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

Result order for keyword searches.

## `maxResults` (type: `integer`):

Maximum number of listings to collect in the run. Free Apify plans are capped at 10 per run.

## `shopDetails` (type: `boolean`):

Fetch each listing's shop page to add shop location, founding year, total active listings, total sales, announcement and policies. Charged only when real shop data is found. Disabled on free plans.

## `aiListingSummary` (type: `boolean`):

Use AI to infer product category, likely materials, ideal target buyer and high-intent SEO keywords for each listing. Charged only when a usable summary is returned. Disabled on free plans.

## Actor input object example

```json
{
  "searchQuery": "leather wallet",
  "listingUrls": [],
  "sortBy": "Relevance",
  "maxResults": 10,
  "shopDetails": false,
  "aiListingSummary": false
}
```

# Actor output Schema

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "leather wallet",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/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 = {
    "searchQuery": "leather wallet",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/etsy-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 '{
  "searchQuery": "leather wallet",
  "maxResults": 10
}' |
apify call scrapers_lat/etsy-scraper --silent --output-dataset

```

## MCP server setup

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