Tony Wang6 min readHow to Scrape Etsy in 2026 (API & Python)
Scrape Etsy in 2026 — listing, shop, and review data — DIY, no-code, or a structured API, plus what Etsy's official API v3 actually gates.
The fastest way to scrape Etsy in 2026 is to call a structured API that returns normalized JSON for listings, shops, and reviews — instead of parsing Etsy's product pages yourself or waiting on an app-review queue. Etsy is unusual in this series: it does publish an official Open API v3, but getting a working key means an approval process, and its Terms of Use separately prohibit scraping outright. This guide covers all three approaches, what each returns, and where the official API's gates actually sit.
Why scrape Etsy?
Etsy's listing, shop, and review data powers:
- Pricing and trend research — track how handmade/vintage categories price against demand, by keyword or niche.
- Seller and shop monitoring — watch a shop's catalog, sold count, and rating move over time.
- Competitive product research — see what's selling in a niche before launching a shop or product line.
- Review and reputation analytics — aggregate rating and review volume across listings or a whole shop.
- Marketplace aggregation — combine Etsy inventory with other marketplaces for a cross-platform handmade/vintage view.
Is it legal to scrape Etsy?
Option 1: DIY in Python (and why it breaks)
Etsy's listing and shop pages render from embedded JSON rather than plain, stable markup, so a DIY scraper has to parse that blob out of the page:
import requests
from bs4 import BeautifulSoup
resp = requests.get(
"https://www.etsy.com/listing/1044347578/",
headers={"User-Agent": "Mozilla/5.0 (compatible; research-bot/1.0)"},
)
soup = BeautifulSoup(resp.text, "html.parser")
# Price, quantity, and shop data live inside a server-rendered
# state blob, not selectable markup — you parse JSON out of a <script> tag
It demos and then breaks:
- The ToS is explicit. Etsy's Terms of Use name crawling, scraping, and spidering directly, and its
robots.txtblocks crawling the search-results URL pattern (/search?*q=) for unlisted user agents — this isn't an ambiguous case. - The sanctioned path has its own gate. Etsy's Open API v3 exists, but a Personal App needs approval (typically 24-48 hours) before it works at all, and anything beyond your own shop — a research tool, an aggregator — needs a separately-reviewed Commercial Access request on top of that.
- A hard daily ceiling even once approved. The official API caps a standard app at 10,000 requests and 10 queries/second per day by default; going higher means emailing Etsy's developer team with a use-case writeup and a QPD/QPS estimate.
- Recent privacy tightening on buyer data. Etsy has restricted what buyer-linked fields (e.g. full buyer email) third-party apps can pull via the official API, on top of the existing per-app review — a trend that makes ad hoc DIY access to that data riskier, not easier.
- No stable markup, either way. Listing pages ship as server-rendered JSON in a script tag; the shape shifts with redesigns, breaking a parser without warning.
Option 2: No-code tools
Marketplace scraper actors exist for one-off Etsy pulls and skip the app-approval wait, but they inherit the same ToS exposure as DIY and don't solve the ongoing-monitoring problem — you're re-running a point tool instead of calling a stable endpoint.
Option 3: A structured Etsy API
For a repeatable workflow, an Etsy scraping API returns normalized JSON for listings, shops, and reviews with no app-review wait and no page parsing. Search by keyword:
curl "https://api.crawlora.net/api/v1/etsy/search?q=handmade+mug" \
-H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"query": "handmade mug",
"offset": 0,
"count": 112886,
"results": [
{
"listing_id": "4474501681",
"title": "Custom Mermaid Mug, Crystal Handle, Mothers Day Gift",
"shop_id": "7894049",
"shop_name": "MerakiDesigned",
"price": "5371901",
"price_int": 5371901,
"currency": "VND",
"url": "https://www.etsy.com/listing/4474501681/handmade-ceramic-mermaid-mug-gold",
"quantity": 7,
"is_sold_out": false
}
]
}
}
Note currency reflects the request's render locale (VND above, not USD) — read it per result rather than assuming a currency. Pull listing detail, shop profile, and reviews in Python:
import requests
h = {"x-api-key": "YOUR_API_KEY"}
base = "https://api.crawlora.net/api/v1/etsy"
hits = requests.get(f"{base}/search", headers=h, params={"q": "handmade mug"}).json()["data"]["results"]
listing_id = hits[0]["listing_id"]
shop_id = hits[0]["shop_id"]
listing = requests.get(f"{base}/listing/{listing_id}", headers=h).json()["data"]
reviews = requests.get(f"{base}/listing/{listing_id}/reviews", headers=h, params={"offset": 0}).json()["data"]
shop = requests.get(f"{base}/shop/{shop_id}", headers=h).json()["data"]
shop_listings = requests.get(f"{base}/shop/{shop_id}/listings", headers=h, params={"limit": 25}).json()["data"]
Listing detail is normalized JSON (real fields — check the docs):
{
"code": 200,
"msg": "OK",
"data": {
"listing_id": "1044347578",
"title": "Handmade Ceramic Mug",
"price": "$29.99",
"price_int": 2999,
"currency": "USD",
"shop_id": "87654321",
"shop_name": "gaguatelier",
"is_sold_out": false,
"category_name": "Mugs",
"materials": ["Ceramic", "Glaze"],
"quantity": 4,
"favorites": 812,
"views": 15230,
"when_made": "made_to_order",
"state": "active"
}
}
Shop profile returns rating and sold-count fields for seller monitoring:
{
"data": {
"shop_id": "87654321",
"shop_name": "gaguatelier",
"seller_name": "Victoria",
"average_rating": 4.9,
"reviews_count": 363,
"sold_count": 1900,
"is_star_seller": true
}
}
Reviews (both /etsy/listing/{id}/reviews and /etsy/shop/{id}/reviews) return avg_rating, total_rating_count, and a paginated reviews array carrying buyer_name, rating, and text per entry — the same first name and text Etsy shows publicly beside each review. Store one row per listing (or per shop) and re-run on a schedule to track price, quantity, and rating drift.
What you can collect
Public listing and shop data: search results (listing_id, title, shop, price, currency, quantity, sold-out status); full listing detail (category, description, materials, tags, favorites, views, when_made, images); shop profiles (seller name, average rating, reviews count, sold count, star-seller status, headline); shop catalogs via /shop/{id}/listings; shop discovery via /shop/search (name, location, active listing count); and paginated reviews with rating, text, and buyer first name for both listings and shops. Public marketplace data only.
Limitations and common challenges
- Currency isn't fixed.
price/price_int/currencyreflect the request's render locale — readcurrencyper result instead of assuming USD. - Reviewer names are personal data.
buyer_nameis a real (if partial) identity — use it for display-consistent aggregation, not for building a contactable buyer list, and honor GDPR/CCPA-style deletion requests if you store it. - No official third-party bulk export. Etsy's own Open API v3 is the sanctioned route for anyone building a production integration at scale; this API is best suited to research-scale, read-only pulls rather than replacing an approved commercial integration.
- Ratings and quantity move fast for popular shops. Best sellers restock or sell out within days — re-pull on a schedule rather than trusting a snapshot.
- Public data only. This is listing- and shop-page data, not a way to reach a seller's private contact details or bypass Etsy's own buyer-messaging system.
Where this gets used
- Pricing research — track how a niche or keyword prices across active listings.
- Shop monitoring — watch a competitor or supplier shop's rating, sold count, and catalog size over time.
- Review analytics — aggregate rating trends per listing or shop for reputation tracking.
Sources
Start collecting
Try it first, free: run any public URL through the Free Web Scraper, or check whether a site blocks bots with the Anti-Bot Checker — no signup.
Test the search, listing, and shop endpoints in the Playground, check the schema in the API docs, and review pricing. Etsy is the handmade and vintage counterpart to the built-on-Shopify storefronts covered in how to scrape Shopify stores and the cross-merchant discovery layer in how to scrape Shop app — pair all three for a fuller independent-commerce picture. For the resale side of the same handmade/secondhand market, see how to scrape eBay; for the peer-to-peer local-listings version of secondhand goods, see how to scrape Facebook Marketplace; and for the retail-fashion counterpart across 25 European markets, see how to scrape Zalando. See also how to choose a web scraping API and is web scraping legal.
Part of our how-to-scrape guide series — every platform we cover, in one index.
Frequently asked questions
Does Etsy have an official API?
Yes — Etsy's Open API v3 is a real, documented API, but it requires an approved app (Personal App approval, then a manually-reviewed Commercial Access tier for anything beyond your own shop) and caps standard apps at 10,000 requests/day.
Is it legal to scrape Etsy?
Etsy's Terms of Use explicitly prohibit crawling, scraping, or spidering its pages without permission, and its robots.txt blocks crawling the search-results URL pattern for general crawlers. Public facts aren't copyrightable, but automated collection outside the official API carries real ToS risk — see is web scraping legal for the general framework.
How do I search Etsy listings with an API?
Send a keyword to a /etsy/search endpoint and get back normalized listing cards (listing_id, title, shop, price, currency, quantity) as JSON — no HTML parsing required.
What does Etsy listing detail include?
Title, price, currency, quantity, category, description, materials, tags, favorites, views, when_made, and sold-out status, keyed by listing_id.
Can I pull an Etsy shop's full catalog?
Yes — /etsy/shop/{id}/listings returns a shop's listing catalog in the same normalized listing-card shape as search results, and /etsy/shop/search finds shops by name.
Are Etsy reviews included, and is that personal data?
Both /etsy/listing/{id}/reviews and /etsy/shop/{id}/reviews return rating, review text, and a buyer_name field — the same first name Etsy shows publicly. Treat buyer_name as personal data under GDPR/CCPA and use it for aggregate rating analysis, not for building a contactable buyer list.
Does currency vary by request?
Yes — price, price_int, and currency reflect the request's render locale (for example VND instead of USD), so read the currency field per result rather than assuming a fixed currency.