# Etsy Scraper (`parsebird/etsy-scraper`) Actor

Scrape Etsy listings by URL or ID: price, sale price and discount, variations with prices, images, tags, materials, favorites, category, stock and shop. Prices in 20 currencies. Export JSON, CSV or Excel.

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

## Pricing

from $2.49 / 1,000 listings

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?

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 Scraper

Etsy Scraper extracts full product details from [Etsy](https://www.etsy.com) listings: price and sale price, variations with the price of each option, all images, tags, materials, favorites, stock, category, when it was made and the shop that sells it. Paste listing URLs or IDs and get clean JSON, CSV or Excel.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Get 40+ fields per Etsy listing in any of 20 currencies, including the sale price and discount, the VAT-inclusive price for your buyer country, every option of every variation with its own price, full-size images, the seller's tags with their Etsy market links, and stock and availability. Hundreds of listings per minute, no proxy needed.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor or any other LLM to start using this Actor.

```
Use the Apify Actor "parsebird/etsy-scraper" (Etsy Scraper) to get product details of Etsy listings. Call it with the apify-client package: Python `ApifyClient("<APIFY_TOKEN>").actor("parsebird/etsy-scraper").call(run_input={...})`, or JavaScript `new ApifyClient({ token }).actor('parsebird/etsy-scraper').call({...})`, then read items from the run's default dataset. Inputs: startUrls (array of {url}: Etsy listing URLs like https://www.etsy.com/listing/1544000459/..., country versions like etsy.com/uk/listing/... and shop subdomain links like shopname.etsy.com/listing/... also work; search, category and shop pages are not supported), listingIds (array of listing ID strings), currency ("USD" default, "EUR", "GBP", "CAD", "AUD", "NZD", "CHF", "SEK", "DKK", "NOK", "PLN", "JPY", "INR", "MXN", "BRL", "HKD", "SGD", "ILS", "TRY", "MYR"), country (optional two-letter buyer country for VAT in priceDisplay, e.g. "DE"), includeDescription (bool, default true), includeVariations (bool, default true), maxItems (int, optional), proxyConfiguration (object, default no proxy). Each item has listingId, url, name, description, price (seller's price before VAT, in the chosen currency), priceMax (highest option price for listings with variation pricing), currency, priceDisplay (price as Etsy shows it to a buyer in that country, VAT included where it applies), priceInclVat, onSale, salePrice, discountPercent, priceUsd, salePriceUsd, hasVariationPricing, quantity, isAvailable, isSoldOut, state (active, sold_out, vacation), favorites, images (full-size URLs), imageCount, seller {name, url, shopId, userId, avatar}, shopSection, variations [{label, values, options [{value, price, available}]}], highlights, materials, whenMade, isDigital, isMadeToOrder, isBestseller, isTopRated, category, categoryPath, categoryId, tags, relatedSearches [{name, link}], shipsFrom, listedOn, listedAt, updatedAt, input, scrapedAt. Deleted or expired listings are skipped and not charged. Pricing: pay per listing saved. API docs: https://apify.com/parsebird/etsy-scraper/api. Get a token at https://console.apify.com/settings/integrations.
```

### What is Etsy Scraper?

**Etsy Scraper** turns [Etsy](https://www.etsy.com) listings into structured data. Give it the URLs or IDs of the listings you care about, such as your competitors' best sellers, your own shop's products or a list of items you track, and it returns each listing's **price, sale price and discount, variations, images, tags, materials, favorites, stock, category and shop**.

It works as an **Etsy API alternative** for product data: no Etsy developer account, API key or OAuth app is needed, and prices come back in any of 20 currencies.

To try it, open the Input tab and click **Start**. The prefill scrapes three listings: a leather watch band, an engraved cutting board and a digital planner download.

### What can Etsy Scraper do?

- 🛍️ **Full listing details**: title, description, price, stock quantity, favorites, state (active, sold out, shop on vacation), when it was made, materials, category, shipping country and listing dates.
- 🏷️ **Sale prices and discounts**: see whether a listing is on sale, the discounted price and the discount percentage.
- 🎨 **Variations with prices**: every option of every variation (size, color, material, personalization choice), with its own price and availability, plus the price range for listings with variation pricing.
- 🖼️ **All images**: full-size image URLs for every photo of the listing.
- 🔖 **Tags and related searches**: the seller's tags, each with its Etsy market page link, which is useful for Etsy SEO research.
- 💱 **20 currencies and VAT**: prices in USD, EUR, GBP, CAD, AUD, JPY and 14 more, plus the VAT-inclusive price Etsy shows to buyers in the country you choose.
- 🏪 **Shop details**: shop name, shop URL, shop and user IDs, avatar and the shop section the listing belongs to.
- ⚙️ **Built for automation**: [schedule runs](https://docs.apify.com/platform/schedules) to track prices, stock and favorites over time, call the Actor through the [Apify API](https://apify.com/parsebird/etsy-scraper/api), send results to [Make, Zapier, n8n, Google Sheets, Slack and more](https://apify.com/integrations), and export as JSON, CSV, Excel or HTML.

### What data can you extract from Etsy?

| Field | Description |
|-------|-------------|
| `listingId`, `url`, `name` | Etsy listing ID, listing URL and title |
| `description` | The seller's full description |
| `price`, `priceMax`, `currency` | Price before VAT in your currency, and the highest option price when options change the price |
| `priceDisplay`, `priceInclVat` | Price as Etsy shows it to a buyer in your country, with VAT where it applies (for example `€46.48` in France) |
| `onSale`, `salePrice`, `discountPercent` | Whether the listing is discounted, the discounted price and the discount |
| `priceUsd`, `salePriceUsd` | The same prices in US dollars |
| `quantity`, `isAvailable`, `isSoldOut`, `state` | Stock quantity, availability and state (`active`, `sold_out`, `vacation`) |
| `favorites` | Number of people who added the listing to their favorites |
| `images`, `imageCount` | Full-size image URLs |
| `seller` | Shop name, shop URL, shop ID, user ID and avatar |
| `shopSection` | The section of the shop the listing is in |
| `variations` | Each variation with its label, values and options (value, price, available) |
| `highlights`, `materials`, `whenMade` | Digital download, made to order or the period it was made in, and the materials |
| `isDigital`, `isMadeToOrder`, `isBestseller`, `isTopRated` | Etsy's flags for the listing |
| `category`, `categoryPath`, `categoryId` | Etsy category, such as `Home & Living > Kitchen & Dining > Cookware > Cutting Boards` |
| `tags`, `relatedSearches` | The seller's tags and their Etsy market page links |
| `shipsFrom` | Country the item ships from |
| `listedOn`, `listedAt`, `updatedAt` | Listing date (Etsy resets it when a listing is renewed) and last update |
| `input`, `scrapedAt` | The listing ID you asked for and the collection time |

### How to scrape Etsy listings

1. Open [Etsy Scraper](https://apify.com/parsebird/etsy-scraper) on Apify Store and go to the Input tab.
2. Paste Etsy listing URLs into **Etsy listing URLs**, or listing IDs into **Listing IDs**. Use **Bulk edit** to paste many URLs at once.
3. Choose a **Currency** and, optionally, a **Buyer country** for VAT-inclusive prices.
4. Turn off **Include description** or **Include variations** if you don't need them.
5. Click **Start**. When the run finishes, download the dataset as JSON, CSV, Excel or HTML, or read it with the [dataset API](https://docs.apify.com/api/v2/dataset-items-get).

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `startUrls` | array | — | Etsy listing URLs, including country versions (`etsy.com/uk/listing/...`) and shop subdomain links (`shopname.etsy.com/listing/...`) |
| `listingIds` | array | — | Etsy listing IDs, such as `1544000459` |
| `currency` | string | `USD` | One of 20 currencies: USD, EUR, GBP, CAD, AUD, NZD, CHF, SEK, DKK, NOK, PLN, JPY, INR, MXN, BRL, HKD, SGD, ILS, TRY, MYR |
| `country` | string | currency's home country | Two-letter buyer country, used for the VAT in `priceDisplay` and `priceInclVat` |
| `includeDescription` | boolean | `true` | Add the full description |
| `includeVariations` | boolean | `true` | Add variations and option prices |
| `maxItems` | integer | all | Maximum listings to save |
| `proxyConfiguration` | object | no proxy | Optional proxy. The Actor works without one |

Example input:

```json
{
    "startUrls": [
        { "url": "https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch" },
        { "url": "https://www.etsy.com/listing/1436683539/personalized-cutting-board-customized" }
    ],
    "currency": "EUR",
    "country": "FR"
}
```

### Output example

A listing with a sale and variation pricing, in euros for a buyer in France (the description and lists are shortened):

```json
{
    "listingId": 1436683539,
    "url": "https://www.etsy.com/listing/1436683539/personalized-cutting-board-customized",
    "name": "Personalized cutting board, Customized engraved cutting board, Gift for couple, wedding, birthday, anniversary, housewarming | CNM1",
    "description": "Hello! We're a family-run business in Canada that specializes in crafting beautiful cutting boards...",
    "price": 38.73,
    "priceMax": 111.54,
    "currency": "EUR",
    "priceDisplay": "€46.48",
    "priceInclVat": 46.48,
    "onSale": true,
    "salePrice": 33.34,
    "discountPercent": 14,
    "priceUsd": 43.38,
    "salePriceUsd": 37.34,
    "hasVariationPricing": true,
    "quantity": 88,
    "isAvailable": true,
    "isSoldOut": false,
    "state": "active",
    "favorites": 3,
    "images": [
        "https://i.etsystatic.com/40491098/r/il/a58e03/4909363935/il_fullxfull.4909363935_fjnw.jpg"
    ],
    "imageCount": 7,
    "seller": {
        "name": "Peeekabooo",
        "url": "https://www.etsy.com/shop/Peeekabooo",
        "shopId": 40491098,
        "userId": 741516312,
        "avatar": "https://i.etsystatic.com/site-assets/images/avatars/default_avatar.png?width=75"
    },
    "variations": [
        {
            "label": "Choose the board size and material",
            "values": ["Small Maple", "Small Walnut", "Medium Maple", "Medium Walnut", "Large Maple", "Large Walnut", "Block Maple w/j", "Block Walnut w/j"],
            "options": [
                { "value": "Small Maple", "price": 38.73, "available": true },
                { "value": "Block Walnut w/j", "price": 111.54, "available": true }
            ]
        }
    ],
    "highlights": ["Made to order", "Materials: Wood"],
    "materials": ["Wood"],
    "whenMade": "Made to order",
    "isDigital": false,
    "isMadeToOrder": true,
    "isBestseller": false,
    "isTopRated": false,
    "category": "Cutting Boards",
    "categoryPath": ["Home & Living", "Kitchen & Dining", "Cookware", "Cutting Boards"],
    "categoryId": 1038,
    "shipsFrom": "CA",
    "listedOn": "Sep 02, 2026"
}
```

### Use Etsy Scraper from Python or JavaScript

Install the client with `pip install apify-client` or `npm install apify-client`, and get your API token from [Apify Console](https://console.apify.com/settings/integrations).

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("parsebird/etsy-scraper").call(run_input={
    "listingIds": ["1544000459", "285428763", "1880766496"],
    "currency": "USD",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"][:50], item["price"], item["salePrice"], item["favorites"], item["quantity"])
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('parsebird/etsy-scraper').call({
    startUrls: [{ url: 'https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch' }],
    currency: 'GBP',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((l) => console.log(l.name, l.priceDisplay, l.tags.join(', ')));
```

### Use cases

- **Competitor price tracking**: [schedule](https://docs.apify.com/platform/schedules) daily runs on your competitors' listings and follow their prices, sales, stock and favorites.
- **Etsy SEO research**: collect the titles and tags (up to 13 per listing) of top listings in your niche to find the keywords sellers use.
- **Product research**: compare materials, variations, price ranges and favorites before you launch a product.
- **Shop monitoring**: watch your own listings for stock running out, expired listings or changes.
- **International pricing**: see what buyers in Germany, the UK, Japan or Canada pay, with VAT included.
- **Catalog and feed building**: feed listing data and images into spreadsheets, dashboards or price comparison tools.

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

Etsy Scraper uses pay-per-event pricing: you pay for each listing saved to the dataset. Compute and proxy costs are included in the event price, so they aren't billed separately.

| Event | Free | Bronze | Silver | Gold |
|-------|------|--------|--------|------|
| Listing scraped | $3.99 / 1,000 | $3.49 / 1,000 | $2.99 / 1,000 | **$2.49 / 1,000** |

At Free plan prices, 100 listings cost about $0.40 and 10,000 listings cost $39.90. Deleted or expired listings aren't saved and aren't charged. To control spending, set **Max listings**. The run also stops when it reaches the maximum cost per run you set in Apify Console.

### Is it legal to scrape Etsy?

Etsy Scraper only collects listing information that Etsy shows publicly to any visitor. It doesn't log in and doesn't access buyer accounts, orders or messages. Listings can include personal data such as a seller's name or shop avatar. If you store or use that data, you're responsible for complying with the GDPR and other privacy laws, and with [Etsy's Terms of Use](https://www.etsy.com/legal/terms-of-use). Consult a lawyer if you're unsure. For more background, read Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

### Other e-commerce scrapers from ParseBird

| Actor | What it does |
|-------|--------------|
| [Redbubble Scraper](https://apify.com/parsebird/redbubble-scraper) | Redbubble products by keyword, category or artist shop |
| [Shopify Products Scraper](https://apify.com/parsebird/shopify-products-scraper) | Full product catalog of any Shopify store |
| [Faire Scraper](https://apify.com/parsebird/faire-scraper) | Wholesale brands, supplier leads and products from Faire |
| [Depop Scraper](https://apify.com/parsebird/depop-scraper) | Depop listings, shops, sellers and reviews |
| [Vinted Scraper](https://apify.com/parsebird/vinted-scraper) | Vinted listings from search, category or seller pages |
| [Mercari US Scraper](https://apify.com/parsebird/mercari-us-scraper) | Mercari US listings with price, brand, condition and seller |
| [eBay Sold Listings Scraper](https://apify.com/parsebird/ebay-sold-listings-scraper) | eBay sold listings with real transaction prices |
| [Amazon Search Scraper](https://apify.com/parsebird/amazon-search-scraper) | Amazon search results in 18 marketplaces |

### FAQ

**Can I scrape Etsy search results, categories or whole shops?**
Not at the moment. Etsy blocks automated access to its search, category and shop pages with bot protection, so Etsy Scraper takes listing URLs or IDs. If you paste a search, category or shop URL, the run log tells you it was skipped. To scrape a set of listings, collect their URLs first, for example from your browser, a spreadsheet or a Google search.

**Does it return reviews, ratings or the shop's sales count?**
No. Those numbers aren't part of the listing data Etsy Scraper reads. You get favorites, stock quantity and Etsy's Bestseller and Top Rated flags instead.

**Why is `price` lower than `priceDisplay`?**
`price` is the seller's price converted into your currency, before VAT. `priceDisplay` is what Etsy shows to a buyer in your **Buyer country**, which includes VAT in countries like Germany, France or the UK. For buyers in the US, both are the same. Variation option prices are before VAT, like `price`.

**How is the sale price worked out?**
When a seller runs a sale, Etsy shows a discounted price next to the original one. Etsy Scraper reads the discounted price in US dollars (`salePriceUsd`) and applies the same discount to the price in your currency (`salePrice`). `discountPercent` is the discount, rounded.

**Why do some listings have no price in my currency?**
Sold-out listings only come with a US dollar price. For them, `price` is in USD and `currency` is `USD`.

**What happens with deleted or expired listings?**
Etsy no longer returns them, so they are skipped, listed in the run's status message and not charged.

**Is `listedOn` the date the listing was first created?**
Not always. Etsy updates that date when a seller renews a listing, so for older listings it's usually the date of the latest renewal.

**Do I need a proxy?**
No. The Actor runs without a proxy by default. In our tests on Apify, it handled 200 listing IDs in about 6 seconds. If Etsy starts refusing requests, add an Apify proxy in the Advanced section.

**Can I run it on a schedule or from my own code?**
Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) for daily or weekly runs, the [Apify API](https://apify.com/parsebird/etsy-scraper/api) or the Python and JavaScript clients shown above, and [integrations](https://apify.com/integrations) to send results to Google Sheets, Slack, Make, Zapier or n8n.

**Something doesn't work or a field is missing. What should I do?**
Open an issue on the Actor's [Issues tab](https://apify.com/parsebird/etsy-scraper/issues) with your input and run ID, and we'll look into it.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/etsy-scraper/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Etsy listing URLs, such as https://www.etsy.com/listing/1544000459/leather-watch-bands. Country versions (etsy.com/uk/listing/...) and shop subdomain links (shopname.etsy.com/listing/...) work too. Search, category and shop pages aren't supported.

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

Etsy listing IDs (the number after /listing/ in the URL), such as 1544000459. Use this or the URLs above, or both.

## `currency` (type: `string`):

Currency of the prices. Etsy converts the seller's price into this currency.

## `country` (type: `string`):

Optional two-letter country code, such as US, DE, FR or GB. It sets which VAT Etsy adds to the displayed price (priceDisplay). Leave empty to use the currency's home country (US for USD, DE for EUR).

## `includeDescription` (type: `boolean`):

Add the seller's full listing description.

## `includeVariations` (type: `boolean`):

Add the listing's options (sizes, colors, personalization choices) with the price of each option.

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

Maximum number of listings to save. Leave empty to save every listing in the input.

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

Optional proxy. The Actor works without one.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch"
    },
    {
      "url": "https://www.etsy.com/listing/285428763/custom-hardwood-cutting-board"
    },
    {
      "url": "https://www.etsy.com/listing/1880766496/digital-download-printable-planner-page"
    }
  ],
  "currency": "USD",
  "includeDescription": true,
  "includeVariations": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "startUrls": [
        {
            "url": "https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch"
        },
        {
            "url": "https://www.etsy.com/listing/285428763/custom-hardwood-cutting-board"
        },
        {
            "url": "https://www.etsy.com/listing/1880766496/digital-download-printable-planner-page"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/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 = { "startUrls": [
        { "url": "https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch" },
        { "url": "https://www.etsy.com/listing/285428763/custom-hardwood-cutting-board" },
        { "url": "https://www.etsy.com/listing/1880766496/digital-download-printable-planner-page" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("parsebird/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 '{
  "startUrls": [
    {
      "url": "https://www.etsy.com/listing/1544000459/leather-watch-bands-watch-bands-watch"
    },
    {
      "url": "https://www.etsy.com/listing/285428763/custom-hardwood-cutting-board"
    },
    {
      "url": "https://www.etsy.com/listing/1880766496/digital-download-printable-planner-page"
    }
  ]
}' |
apify call parsebird/etsy-scraper --silent --output-dataset

```

## MCP server setup

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