# Etsy Listings Scraper (`usestring/etsy-listings`) Actor

Collect Etsy search listings - numeric price, currency, shop name, shop rating, shipping and badges.

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

## Pricing

from $1.50 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Listings Scraper — numeric price, shop rating and badges

This Actor scrapes Etsy search listings. Give it a search term such as `handmade jewelry` and the
Etsy Listings Scraper returns each listing with a **numeric price** and its currency code, the shop
name, the shop's rating and review count, and the Bestseller and free-shipping flags as booleans.

No Etsy account, login or cookies are used — this reads what a logged-out visitor sees. **12 listings
per Etsy search page**, up to 240 per search term.

### What it returns

| Field | Type | Notes |
| --- | --- | --- |
| `listingId` | string | Etsy's own listing ID — stable across runs, use it to de-duplicate |
| `title` | string | The listing title |
| `price` | number | `24.99`, not `"$24.99"` |
| `currency` | string | ISO code Etsy priced the page in, e.g. `USD` |
| `shopName` | string | The shop's Etsy handle |
| `shopRating` | number | The shop's stars out of 5, e.g. `4.8` |
| `shopReviewCount` | number | `12403`, not `"12.4k"` |
| `isBestseller` | boolean | `true` when the card carries Etsy's Bestseller badge |
| `freeShipping` | boolean | `true` when the card advertises free shipping |
| `imageUrl` | string | The listing's card image |
| `listingUrl` | string | Direct link to the Etsy listing |
| `searchTerm`, `sourceUrl`, `collectedAt` | string | Provenance for every row |

`shopRating` and `shopReviewCount` describe the **shop**, which is what an Etsy search card shows —
they are not a per-listing review score.

### Input

```json
{ "searches": ["handmade jewelry", "leather wallet"], "maxItems": 1000 }
```

| Field | Description |
| --- | --- |
| `searches` | Search terms, e.g. `"handmade jewelry"`. Required, 1–50. |
| `maxItems` | Cap on dataset items. Default 1000. Free plans stop at 250 requests and 250 results — see below. |
| `concurrency` | Search pages fetched in parallel. Default 5, maximum 10. |

`maxItems` also decides how deep each term is paged: the budget is split evenly across the search
terms, in whole pages of 12, up to Etsy's own ceiling of 20 pages per search.

### Use cases

- Product and niche research before sourcing or launching a shop
- Competitor price monitoring across a category, on numbers rather than display strings
- Tracking which listings hold the Bestseller badge over time
- Building a keyword-to-price-band map for a market
- Feeding a merchandising or pricing dashboard on a schedule

### Reliability

Listings are read from Etsy's server-rendered search grid, which carries strictly more than the
page's schema.org block — that block is a promotional subset of the cards and omits the rating, the
review count, the badges and shipping entirely. Each card is isolated before its fields are read, so
a "Free shipping" filter option in the sidebar is never mistaken for a shipping promise on a listing
that makes none.

Measured at **11.67 listings per request** after de-duplication. A search page that cannot be read is
recorded in the run's `SUMMARY` under `failures` rather than silently returning fewer rows, and a run
where every page failed exits with an error.

There are no retries by design: the String Unblocker owns proxy rotation and anti-bot solver
selection, so a retry loop here would only re-roll the same block.

### Frequently asked questions

**How do I scrape Etsy listings?** Run the Etsy Listings Scraper with one or more search terms, then
export the dataset as CSV, JSON or Excel. Every row carries the listing ID, title, numeric price,
currency, shop name, shop rating, review count and both badge flags.

**How many Etsy listings does it return per search?** 12 per search page — the number Etsy
server-renders — and it pages up to 20 pages, so 240 listings per search term is the ceiling. Raise
`maxItems` to page deeper.

**Does it page through results?** Yes, up to 20 pages per search term. Etsy silently re-serves page 1
past its own twentieth page, so paging stops there rather than collecting duplicates.

**Do I need an Etsy account, API key or cookies?** No. The Etsy Listings Scraper reads public Etsy
search pages as a logged-out visitor and never signs in.

**Is the price a number?** Yes. `price` is numeric (`24.99`) and `currency` carries the ISO code Etsy
priced the page in, so no string cleaning is needed.

**Can I scrape a single shop or a listing page?** No. This Actor works from search terms and reads
search results only; it does not open individual listing or shop pages.

### Limitations

Search results only: no listing detail pages, so no description, variations, materials, stock level,
processing time or per-listing reviews, and no shop pages. Etsy prices a page in the viewer's own
currency, so `currency` reflects that rather than a currency you choose. Promoted listings repeat
within a grid and across a search's pages; they are de-duplicated per search term, but the same
listing under two different search terms is returned for each.

### Free plan limit

Runs started from an Apify **free plan** stop at **250 requests and 250 results**, and the run
reports that it reached the limit. Any paid plan runs the full input and `maxItems` you set.

The limit exists because this Actor fetches through our own infrastructure, which Apify does not
cover for free-plan runs. It binds on requests as well as results so that a large input list cannot
spend those fetches for rows the run will not return.

# Actor input Schema

## `searches` (type: `array`):

What to search Etsy for.

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

Global cap on dataset items. Runs started from an Apify free plan stop at 250 requests and 250 results; any paid plan runs the full amount.

## `concurrency` (type: `integer`):

Targets fetched in parallel.

## Actor input object example

```json
{
  "searches": [
    "handmade jewelry"
  ],
  "maxItems": 1000,
  "concurrency": 5
}
```

# Actor output Schema

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

Collect Etsy search listings - numeric price, currency, shop name, shop rating, shipping and badges.

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

Item count, failure count and every target that failed, with its error.

# 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 = {
    "searches": [
        "handmade jewelry"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("usestring/etsy-listings").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 = { "searches": ["handmade jewelry"] }

# Run the Actor and wait for it to finish
run = client.actor("usestring/etsy-listings").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 '{
  "searches": [
    "handmade jewelry"
  ]
}' |
apify call usestring/etsy-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,usestring/etsy-listings"
        }
    }
}

```

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/xLGK4RHqKl3EWc2NB/builds/yl0Z3EKaPD1LsPC0f/openapi.json
