Etsy Scraper: Listings, Prices, Variations & Reviews avatar

Etsy Scraper: Listings, Prices, Variations & Reviews

Pricing

from $1.00 / 1,000 listing results

Go to Apify Store
Etsy Scraper: Listings, Prices, Variations & Reviews

Etsy Scraper: Listings, Prices, Variations & Reviews

Scrape Etsy listings by keyword, category, or URL. Extract titles, shops, prices, discounts, availability, images, categories, and variations. Optional detail mode adds descriptions, materials, shipping origin, and item-level reviews. Supports incremental monitoring.

Pricing

from $1.00 / 1,000 listing results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Etsy Marketplace Scraper

Scrape listings from Etsy (etsy.com) — the handmade, vintage and craft marketplace. Search by keyword and/or category, or paste links directly. Every listing comes back as one flat record with title, shop, price, was‑price/ discount, availability, images, category and variations; enable details to add the full description, materials, shipping origin, rating breakdown and item‑level reviews.

What you can do

  • Search by keyword and/or category — e.g. handmade necklace, or scope to a category path like jewelry/necklaces — with Etsy's own price, on‑sale, free‑shipping and personalizable filters, plus sorting.
  • Paste links — mix listing links, category/search links and shop links in one list and let the actor route each entry. Listing links return full detail; category/search/shop links are walked across their result pages.
  • Resume & recurring updates — turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED listings on every scheduled run, or resume one specific interrupted crawl with resumeFromRunId.

Input

FieldDescription
Modesearch or url.
Search keywordsKeywords to search (search mode). Each is searched separately. Leave empty and set only Category path to browse a whole category.
Category pathOptional Etsy category path to scope the search or browse to, e.g. jewelry/necklaces (search mode).
Etsy linksListing links, bare listing ids, category/search links, or shop links to scrape directly, mixed freely (url mode). Listing links return full detail.
Sort byRelevancy, price ↑/↓, newest first, or highest reviews first.
On sale onlyKeep only listings currently on sale.
Free shipping onlyKeep only listings with free shipping.
Personalizable onlyKeep only listings that can be personalized.
Min / Max price (USD)Keep only listings within a price range.
Ships toTwo-letter country code to only show listings that ship there.
Fetch listing detailsAdd description, materials, category breadcrumbs, extra images, shipping origin, variations, rating breakdown and item-level reviews. On by default.
Max listingsThe run's cap on how many listings to return. Default 20; 0 = unlimited.
Max pages per keyword / linkResult pages walked per keyword / category / link. Default 0 = unlimited — walks every page until Max listings is hit or a page repeats no new listings.
Resume from a previous runContinue one specific previous run/dataset: listings already collected there are skipped, so this run only appends new listings. For recurring daily monitoring of the same search, use Incremental mode instead — see "Resume & recurring updates" below.
Incremental changes for scheduled runsDaily/recurring monitoring of this same search. First run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED by default. See "Resume & recurring updates" below.
State keyOptional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your search/detail settings when left empty.
Emit unchanged listingsIncremental mode only. Also return listings unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have.
Emit expired listingsIncremental mode only. Also return listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search (not capped, not a resume). Adds and bills extra synthetic rows.
ProxyApify Proxy — a residential exit recommended (see below).
mcpConnectorsOptional MCP connectors to export results into (Notion, Linear, Airtable, Apify).
notionParentPageUrlNotion connector only: page under which item pages are created.
maxNotifyListingsCap on items exported to each connector per run. Does not affect the dataset.

Output

One record per listing. With details off you get the search-card fields; with details on you also get description, materials, category, shipping origin, variations, rating breakdown and item-level reviews. Example (illustrative values):

{
"listingId": "4530068104",
"title": "Example personalized initial keychain",
"shopId": "14528878",
"shopName": "ExampleCraftStudio",
"shopUrl": "https://www.etsy.com/shop/ExampleCraftStudio",
"categoryPath": ["Accessories", "Keychains & Lanyards", "Keychains"],
"price": 16.0,
"currency": "USD",
"originalPrice": null,
"discountPercentage": null,
"onSale": false,
"availability": "in_stock",
"quantityAvailable": 38,
"images": ["https://i.etsystatic.com/example/il_fullxfull.example.jpg"],
"videoUrl": null,
"description": "Full listing description...",
"materials": ["Cotton", "Felt"],
"shippingOrigin": { "addressCountry": "US", "addressRegion": "MI" },
"rating": 5.0,
"reviewCount": 5,
"ratingBreakdown": { "itemQuality": 5.0, "shipping": 5.0, "customerService": 5.0, "buyersRecommend": 100.0 },
"reviews": [
{
"reviewId": "5150597893",
"author": "exampleBuyer",
"rating": 5,
"date": "Jul 27, 2026",
"body": "Great quality, exactly as described!",
"photos": [],
"helpfulCount": null,
"variantContext": null
}
],
"variations": [
{ "name": "Primary color", "options": [{ "variationId": "6788604158", "label": "citron/blue" }] }
],
"url": "https://www.etsy.com/listing/4530068104/example-listing-slug",
"searchMode": "search",
"scrapedAt": "2026-01-01T00:00:00Z"
}

Was-price & sale detection. originalPrice/discountPercentage/onSale reflect a seller's own sale badge against their own prior price on that same listing — never a comparison against a different listing. Full-price listings carry originalPrice: null.

Reviews are item-level. They come from the listing's own page, not a shop-wide review feed. A listing with no reviews returns reviews: [] and rating/reviewCount as null. Some review fields (helpfulCount, variantContext) are included for completeness but are not exposed on every listing — they come back null when the listing's page doesn't carry them.

Incremental mode only. When incrementalMode is on, every returned record also carries:

FieldDescription
changeTypeNEW | UPDATED | UNCHANGED | REAPPEARED | EXPIRED
changedFieldsTop-level fields that changed since last seen; non-empty only for UPDATED
firstSeenAtWhen this listing was first observed by this monitoring campaign
lastSeenAtWhen this listing was last observed

Resume & recurring updates

There are two different things here — pick the one that matches what you're doing:

NeedUse
A crawl stopped and should continueresumeFromRunId / automatic checkpoint recovery
Run the same search every day and receive only changesincrementalMode
Keep separate daily campaigns for similar searchesdistinct stateKey values
Run a normal full snapshotleave both off

Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips listings already collected there, returning only the remaining new listings. An automatic same-run checkpoint also protects against platform migrations/Resurrects without any input needed.

Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED listings by default — duplicates and unchanged listings are suppressed (and not charged). Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per search/URL and detail-mode setup automatically; set stateKey to name or deliberately share a monitoring campaign.

Scheduled-run example — same search, run daily:

Day 1 (first run ever for this search):

{ "mode": "search", "queries": ["handmade necklace"], "incrementalMode": true }

→ every listing comes back with "changeType": "NEW".

Day 2 (the schedule fires again, identical input):

{ "mode": "search", "queries": ["handmade necklace"], "incrementalMode": true }

→ listings whose price/availability/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new listings come back as "changeType": "NEW", listings that vanished and came back come back as "changeType": "REAPPEARED" — and listings that are still there, unchanged, are not returned at all (suppressed, not charged) unless emitUnchanged is on.

Proxy & connection

Apify Proxy is recommended for reliable results; a residential connection is the default. On the Free plan (no residential proxy access) results may be less reliable — enable Apify Proxy or upgrade your plan at https://apify.com/pricing.

Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the mcpConnectors field. Each connector receives a condensed, human-readable summary per listing (title plus key fields), while the complete record always stays in the Apify dataset. For Notion, set notionParentPageUrl to the page the item pages should be created under. Supported connectors: Notion, Linear, Airtable, and Apify. Leave the field empty to skip; it never changes the dataset output.

Notes

  • Search and category result pages are walked forward one page at a time until Max listings is reached, the site runs out of pages, or (with the default unlimited Max pages) a page repeats no new listings.
  • Long runs survive an Apify server migration or a manual Resurrect: progress is checkpointed, so a resumed run continues without re-scraping or double-charging listings already collected.
  • searchMode on each record reports how it was found: search, browse (a pasted category/search/shop link), or listing when it came from a pasted listing link or id.
  • Prices are in USD.
  • Duplicate listings (same id) are returned once per run.