Etsy
Etsy Scraper: Product Research With Real Etsy Sales Data
Scrape Etsy search results and shops for product research: cart counts, 24h sales, tags, shop sales and reviews. Input JSON, sample output and API code.
Etsy
Scrape Etsy search results and shops for product research: cart counts, 24h sales, tags, shop sales and reviews. Input JSON, sample output and API code.
Most Etsy research tools guess. They model per-listing sales from reviews or favorites, and two tools will often give you two very different numbers for the same product. An Etsy scraper takes a different route: it collects the numbers Etsy itself shows, like how many shoppers have a listing in their cart right now, the “bought in the last 24 hours” message, all 13 tags, favorites and the shop’s total sales count.
This guide covers two actors that work together. The Etsy Scraper turns any keyword search into a spreadsheet of listings, with search rank and ad slots. The Etsy Shop Scraper goes deep on known shops: their full catalog, profile and reviews. Neither needs an Etsy account, API key or browser extension.
The Etsy Scraper returns one row per listing in a search. Search-card data comes on every row; the rest is added when Include listing details (includeDetails) is on, which is the default.
| Group | Fields |
|---|---|
| Search position | query, searchRank, page, pagePosition, isAd |
| Price | price, salePrice, discount, currency, minPrice, maxPrice, variations |
| Demand | inCartCount, boughtLast24h, demandMessage, lastSaleAt, favorites, quantity, isScarce |
| SEO | tags, materials, category, categoryPath, description, whenMade |
| Reputation | listingRating, listingReviewCount, isBestseller, isTopRated, isEtsysPick |
| Shop | shopName, shopSales, shopSalesHiddenOnSite, shopRating, shopFollowers, shopActiveListings, shopCountryCode, isStarSeller |
| Fulfillment | hasFreeShipping, shippingCost, minProcessingDays, maxProcessingDays, shipsFromCountryCode |
Two fields matter most for product research. inCartCount is a live demand signal, and shopSales is the shop’s total sales counter, returned even for shops that hide it on their page (shopSalesHiddenOnSite tells you which). Etsy does not publish sales per listing, so neither does the scraper. To get sales over a period, you compare shopSales between scheduled runs, covered below.
Etsy caps every search at about 1,000 results. The actor gets around that by splitting large searches into price ranges, so a broad keyword can return several thousand unique listings.
queries). Use short phrases a shopper would type, such as ceramic mug. An Etsy search URL also works.maxResultsPerQuery). Start with 20 to check the output; 0 means no limit.sortBy, minPrice / maxPrice (USD), shipTo, shopLocation, and toggles like digitalOnly, onSaleOnly or personalizableOnly.This input pulls up to 300 organic listings per keyword, with full details:
{
"queries": ["halloween sweatshirt", "ghost mug", "fall wreath"],
"maxResultsPerQuery": 300,
"includeAds": false
}
Sort the result by inCartCount or boughtLast24h. Listings with high cart counts and a recent createdAt are new products that are already selling, which is the pattern you want to find before a niche gets crowded.
{
"queries": ["digital planner", "budget spreadsheet"],
"maxResultsPerQuery": 100,
"digitalOnly": true
}
Open the Tags & SEO view and count which tags the top-ranked listings share. Tags that appear on most of the first 20 results are the ones Etsy’s search clearly associates with the keyword.
For rank tracking you don’t need listing details, which makes runs faster and cheaper. Turn off deduplication so each keyword keeps its full list:
{
"queries": ["personalized leather wallet", "custom family ornament"],
"maxResultsPerQuery": 200,
"includeDetails": false,
"dedupeAcrossQueries": false
}
searchRank is the position among organic results. Ads get isAd: true with their page and pagePosition, so the same run shows which competitors are paying for the keyword.
A trimmed record with details:
{
"listingId": 1549249672,
"title": "14K Gold Initial Necklace with Birthstone",
"url": "https://www.etsy.com/listing/1549249672/14k-solid-gold-initial-necklace-with",
"price": 42.71,
"salePrice": 29.9,
"discount": "(30% off)",
"currency": "USD",
"query": "necklace",
"searchRank": 2,
"isAd": false,
"inCartCount": 1005,
"boughtLast24h": 19,
"favorites": 23468,
"isBestseller": true,
"tags": ["personalized jewelry", "gift for her", "birthstone necklace"],
"category": "Monogram & Name Necklaces",
"createdAt": "2023-09-10T13:26:20.000Z",
"shopName": "StellaGoldJewelry",
"shopSales": 33989,
"shopSalesHiddenOnSite": true,
"shopCountryCode": "TR",
"scrapedAt": "2026-10-01T12:00:00.000Z"
}
Prices are in US dollars. boughtLast24h is only filled when Etsy shows its “In demand” message, so null there means no message rather than zero sales.
Once a search has surfaced the shops worth watching, switch to the Etsy Shop Scraper. It accepts shop URLs, shop names or numeric shop IDs in shops, and runs in one of three modes:
mode |
One row is | Highlights |
|---|---|---|
listings |
An active listing | Price, sale price, shopPrice in the shop’s currency, inCartCount, lastSaleAt, flags, processing time |
profiles |
A shop | soldCount, rating and sub-ratings, followerCount, activeListingCount, sections, policies, isStarSeller |
reviews |
A review | date, rating, text, sellerResponse, listingTitle, buyer photo or video |
Pull a competitor’s whole catalog, newest first, with tags and 24-hour sales:
{
"shops": ["https://www.etsy.com/shop/CaitlynMinimalist"],
"mode": "listings",
"listingsSortOrder": "date_desc",
"includeListingDetails": true,
"maxResultsPerShop": 0
}
Or read what buyers complain about. Filters are applied by Etsy, so you only pay for matching reviews:
{
"shops": ["CaitlynMinimalist"],
"mode": "reviews",
"reviewsRatings": ["1", "2"],
"reviewsTopic": "shipping",
"maxResultsPerShop": 200
}
Low-star reviews of a top competitor are a cheap source of product ideas: every repeated complaint about sizing, packaging or slow shipping is a gap you can sell into.
Schedule a profiles run (or a search with details) daily. Today’s soldCount (or shopSales) minus yesterday’s is the shop’s actual number of sales for that day, straight from Etsy’s own counter. Save the input as a task in Apify Console, attach a schedule such as 0 0 * * *, and connect Google Sheets in the task’s Integrations tab so every run lands in a sheet.
Run a search and get the dataset back in one request:
curl -X POST "https://api.apify.com/v2/acts/epicscrapers~etsy-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["linen apron"], "shipTo": "GB", "maxResultsPerQuery": 50}'
Python with apify-client, ranking listings by live demand:
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("epicscrapers/etsy-scraper").call(run_input={
"queries": ["ceramic mug", "pottery planter"],
"maxResultsPerQuery": 200,
"includeAds": False,
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
items.sort(key=lambda x: x.get("inCartCount") or 0, reverse=True)
for it in items[:20]:
print(it["inCartCount"], it["price"], it["shopName"], it["title"])
Every row carries listingId, shopId and scrapedAt, so joining runs to track price changes, rank movement or new competitors is a simple merge.
Product research. Search a niche, sort by inCartCount, boughtLast24h and favorites, and filter for recent createdAt dates to find products that sell without years of reviews behind them.
Etsy SEO. Collect the tags, titles and categoryPath of the listings that rank on page one for your target keywords, then compare them with your own.
Pricing. Use minPrice / maxPrice and the onSaleOnly filter to map price bands and discount habits in a niche before you set your own price.
International markets. Run the same keyword with shipTo set to GB, DE or another country, optionally with shopLocation, to see how competition and prices differ. Prices stay in USD for easy comparison.
Competitor monitoring. Track a competitor’s catalog with the Shop Scraper and use createdAt to spot new launches the day they go live.
If you also sell on other marketplaces, the same research approach works on eBay; see our eBay scraper guide and the eBay sold listings guide for confirmed sale prices.
Yes, Etsy’s Open API, but it needs an approved developer app and does not expose search ranking, ad placements, cart counts or “bought in 24 hours”. The scraper returns what a shopper sees in search, plus those signals.
No. shopSales, soldCount, inCartCount, boughtLast24h and favorites are Etsy’s own numbers at the time of the run. For sales over a period, compare the shop counter between scheduled runs.
The actors collect publicly visible listing, shop and review data. You are responsible for how you use it, including Etsy’s terms and data protection laws like GDPR. Reviews contain buyer names, so don’t use them for profiling or unsolicited contact. This isn’t legal advice.
Etsy personalizes results for signed-in shoppers, rotates ads and varies results by country. The actor searches as a signed-out shopper in the shipTo country, so compare ranks between runs of the same task rather than against your own browser.
Neither actor takes listing URLs. Use a keyword search, or the Shop Scraper’s listingsSearchQuery to narrow a shop’s catalog to a keyword.
Pick the keyword you most want to rank for, run it through the Etsy Scraper with maxResultsPerQuery set to 50, and sort by inCartCount. When you find shops worth following, load them into the Etsy Shop Scraper and put both on a schedule. Pricing is pay-per-event; check the Pricing tab on each actor page.