← Back to blogTutorial

How to Find Trending Etsy Products Before They Peak

· 11 min read

Every Etsy seller eventually faces the same question: what should I make next? The answer lives in the search page. When listings created in the last few weeks already rank on the first page of a relevance-sorted search, that category is heating up — buyers are gravitating to a new aesthetic, the supply side has not yet flooded in, and the early entrants are still being rewarded by the algorithm. The hard part is spotting this window before the market peaks. This guide walks the full discovery loop: scraping search results, filtering by listing recency and review velocity, comparing snapshots week-over-week, and using a competitor shop's new releases as a validated trend signal.

Why the Search Page Is the Right Signal

The cleanest source of truth for what is trending on Etsy is the search result set sorted by relevance. Etsy's relevance algorithm blends recency, conversion rate, favorites velocity, review quality, and listing freshness. A listing only ranks highly if real shoppers are clicking, favoriting, and buying it — and those signals are accumulated by Etsy in real time. By scraping the top results for a seed query, sellers get the algorithm's own composite assessment of what is working right now, distilled into a ranked list of forty listings per page.

The same data exists nowhere else in a useful form. Etsy publishes no public "trending products" feed, the affiliate API restricts what you can query and stores no historical state, and third-party trend dashboards (eRank, Marmalead, Alura) are themselves derived from the same public listing data — just packaged with a subscription. Scraping the source directly gives a research team raw access to the same underlying signal those tools resell, with no caps on which categories they can analyze and no ceiling on historical retention.

The other reason the search page beats every alternative is the listing creation date. When that field is present in the markup, it is the closest thing Etsy ships to a public "this product is new" flag. Combined with rank position, it answers the question every seller actually has: "is something brand new already winning, and what does it look like?"

What Etsy Search Actually Returns

Per listing on a search-page scrape, the result includes:

FieldExample
listing_id1547892304
titleCottagecore Soy Candle, Lavender & Sage, Hand-Poured
urlhttps://www.etsy.com/listing/1547892304/cottagecore-soy-candle
price18.50
currencyUSD
original_price24.00
shopTheWildwoodCo
shop_urlhttps://www.etsy.com/shop/TheWildwoodCo
imagehttps://i.etsystatic.com/.../il_794xN.1547892304_xyz.jpg
favorites412
rating4.9
reviews38
is_bestsellertrue
free_shippingfalse
listed_at2026-05-04T00:00:00Z

Two of those fields carry the trend signal. The listed_at date tells you the listing's age in days. The reviews count tells you how much purchase momentum it has gathered. The ratio of the two is the metric the cleaning section below computes.

What the search page does not include is the listing's full description, full image gallery, materials, or variations — for those, a downstream call to the product endpoint per shortlisted listing is required.

Building the Search URL

Etsy search URLs are easy to construct manually because the parameters live in the query string. The two parameters that matter for trend research are q (the search query) and order (the sort).

  1. Open etsy.com in a browser.
  2. Search for a seed term — cottagecore candle, birth flower necklace, mushroom phone case.
  3. The URL now looks like https://www.etsy.com/search?q=cottagecore+candle. This is sort-by-relevance by default, which is what trend research wants.
  4. Optionally add &order=most_recent for a recency-first view (useful for spotting which new listings exist at all, regardless of whether they have traction yet).

Three example URLs to test with:

https://www.etsy.com/search?q=cottagecore+candle
https://www.etsy.com/search?q=birth+flower+necklace
https://www.etsy.com/search?q=mushroom+phone+case&order=most_recent

The first two are relevance-sorted (what the algorithm currently rewards). The third is recency-sorted (what is being listed right now). Run both for each seed and the difference between the two result sets is itself a useful signal — listings that appear in both are newly-listed items already winning on relevance, which is the textbook definition of a rising star.

The API Call

Every LogPose Etsy endpoint is asynchronous — submit a job, poll until done, fetch the result. Submit with curl first to confirm the URL works:

curl -G "https://api.logposervices.com/api/v1/ecommerce/etsy/search" \
  -H "X-API-Key: lp_xxxxxxx" \
  --data-urlencode "url=https://www.etsy.com/search?q=cottagecore+candle" \
  --data-urlencode "pages=3"
# → {"job_id": "etsy_a91c..."}

curl -H "X-API-Key: lp_xxxxxxx" \
  "https://api.logposervices.com/api/v1/jobs/etsy_a91c?wait=true&timeout=60"

curl -H "X-API-Key: lp_xxxxxxx" \
  https://api.logposervices.com/api/v1/jobs/etsy_a91c/result

Etsy returns about 40 listings per page, so pages=3 is roughly 120 listings — enough to see the top of the category clearly without overpaying for ranking noise further down. Most 3-page jobs finish in 30–60 seconds.

The Python Pipeline

This is the script most product researchers end up running on a weekly cron. It takes one seed search URL, pulls three pages, computes review velocity, and writes a CSV sorted by the trend signal:

import os, time, csv, requests
from datetime import datetime, timezone

API_KEY = os.environ["LOGPOSE_API_KEY"]
BASE = "https://api.logposervices.com/api/v1"
HEADERS = {"X-API-Key": API_KEY}


def submit_and_wait(path: str, params: dict, timeout_s: int = 180) -> dict:
    r = requests.get(f"{BASE}/{path}", params=params, headers=HEADERS, timeout=30)
    r.raise_for_status()
    job_id = r.json()["job_id"]
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        s = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=15).json()
        if s["status"] == "completed":
            break
        if s["status"] == "failed":
            raise RuntimeError(s.get("error", "unknown failure"))
        time.sleep(2)
    else:
        raise TimeoutError(f"job {job_id} did not finish in {timeout_s}s")
    return requests.get(f"{BASE}/jobs/{job_id}/result", headers=HEADERS, timeout=15).json()


def days_since(iso_ts: str | None) -> int | None:
    if not iso_ts:
        return None
    dt = datetime.fromisoformat(iso_ts.replace("Z", "+00:00"))
    return max(1, (datetime.now(timezone.utc) - dt).days)


def scrape_to_csv(search_url: str, pages: int, out_path: str) -> int:
    data = submit_and_wait(
        "ecommerce/etsy/search",
        {"url": search_url, "pages": pages},
    )
    rows = []
    for i, r in enumerate(data["listings"], start=1):
        age = days_since(r.get("listed_at"))
        reviews = r.get("reviews") or 0
        rows.append({
            "rank": i,
            "title": r.get("title"),
            "shop": r.get("shop"),
            "price": r.get("price"),
            "favorites": r.get("favorites"),
            "reviews": reviews,
            "rating": r.get("rating"),
            "age_days": age,
            "review_velocity": round(reviews / age, 3) if age else None,
            "url": r.get("url"),
        })

    with open(out_path, "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
        w.writeheader()
        w.writerows(rows)
    return len(rows)


if __name__ == "__main__":
    n = scrape_to_csv(
        "https://www.etsy.com/search?q=cottagecore+candle",
        pages=3,
        out_path="cottagecore_candles.csv",
    )
    print(f"wrote {n} listings")

Run it once and you have a ranked snapshot of the category. Run it weekly with the same seed URL and you can compute deltas — which is where the actual trend signal lives.

Raw output from one 3-page job is usually 110–125 rows. Four cleaning steps turn that into a usable trend report:

import pandas as pd

df = pd.read_csv("cottagecore_candles.csv")

# 1. Drop listings with no creation date — can't compute velocity
df = df[df["age_days"].notna()]

# 2. Drop listings under 7 days old — too little data to score
df = df[df["age_days"] >= 7]

# 3. Drop listings with fewer than 3 reviews — noise floor
df = df[df["reviews"] >= 3]

# 4. Filter to listings created in the last 90 days — the trend window
recent = df[df["age_days"] <= 90].copy()

# 5. Sort by review velocity desc — the actual trend metric
recent = recent.sort_values("review_velocity", ascending=False)

recent.head(20).to_csv("cottagecore_candles_trending.csv", index=False)

The age_days <= 90 filter is the highest-leverage step. It strips out the established bestsellers that dominate any relevance-sorted result set and isolates the listings that are new but already converting. The top 20 rows after this filter are the working list — products created in the last three months that are already gathering reviews faster than the category baseline. For most seed queries, between 5 and 15 listings will pass all four filters; those are the rising stars worth studying in detail.

Comparing Snapshots Week-Over-Week

A single snapshot is a stock metric. The actual trend signal is the delta between two snapshots. The pattern is straightforward — save each week's results under a dated filename, then diff by listing ID:

import pandas as pd

last_week = pd.read_csv("cottagecore_candles_2026-05-21.csv")
this_week = pd.read_csv("cottagecore_candles_2026-05-28.csv")

# Listings that appeared net-new in this week's top 120
new_arrivals = this_week[~this_week["listing_id"].isin(last_week["listing_id"])]

# Listings present in both — compute rank movement
both = this_week.merge(
    last_week[["listing_id", "rank"]].rename(columns={"rank": "rank_last_week"}),
    on="listing_id",
)
both["rank_change"] = both["rank_last_week"] - both["rank"]
risers = both[both["rank_change"] >= 10].sort_values("rank_change", ascending=False)

print(f"{len(new_arrivals)} net-new listings on page 1")
print(f"{len(risers)} listings that jumped 10+ ranks")

Net-new arrivals on page one are listings the algorithm has just promoted — a strong leading indicator. Listings that jumped 10+ ranks week-over-week are existing items gaining momentum. Combined, the two lists are a focused weekly view of where the category's energy is moving.

The technique generalizes to any e-commerce search page where the result order encodes a popularity signal. The same pattern appears in How to monitor Amazon competitor pricing daily for a price-focused variant.

Tracking a Competitor Shop's New Releases

A high-revenue Etsy shop has already done the trend validation work — when they release a new variant, the research behind that decision is implicit in the listing. Riding that signal is the most-undervalued move in Etsy research, and the shop endpoint makes it trivial:

shop_data = submit_and_wait(
    "ecommerce/etsy/shop",
    {"shop": "TheWildwoodCo", "pages": 5},
)
current_ids = {l["listing_id"] for l in shop_data["listings"]}

# Compare against last week's snapshot
import json
with open("wildwood_2026-05-21.json") as f:
    previous_ids = set(json.load(f))

new_releases = current_ids - previous_ids
print(f"{len(new_releases)} new listings since last week")

Snapshot the shop weekly, diff by listing ID, and the delta is the seller's net-new releases. Five pages typically covers a shop's full active inventory unless they have several hundred items. The signal is high-quality because it filters out everything except the products a proven seller is actively betting on this week.

Scaling Beyond a Single Seed Query

One seed query gives you one micro-trend. To cover a broader market, run a portfolio of seeds — typically the 10–20 phrases your target buyer types into the search bar. Two patterns work in production.

Cron-driven portfolio. Maintain a YAML or JSON file listing your seed queries, run the pipeline against each one on a weekly schedule, save snapshots by date, and ship the trending-this-week summary as a Sunday-night digest to whoever owns product roadmap decisions.

Bulk submission. Instead of running each seed sequentially, submit the whole portfolio in one bulk request and let the platform parallelize across the proxy pool:

requests.post(
    "https://api.logposervices.com/api/v1/ecommerce/etsy/search/bulk",
    headers={"X-API-Key": os.environ["LOGPOSE_API_KEY"]},
    json={
        "targets": [
            {"url": "https://www.etsy.com/search?q=cottagecore+candle", "pages": 3},
            {"url": "https://www.etsy.com/search?q=birth+flower+necklace", "pages": 3},
            {"url": "https://www.etsy.com/search?q=mushroom+phone+case", "pages": 3},
            {"url": "https://www.etsy.com/search?q=stanley+cup+accessories", "pages": 3},
            {"url": "https://www.etsy.com/search?q=witchy+desk+decor", "pages": 3},
        ],
    },
).raise_for_status()

Bulk submission runs in parallel up to your concurrency cap, which cuts a 20-seed portfolio from 15 minutes sequential to 2–3 minutes wall-clock. For sellers running discovery across multiple niches simultaneously, this is the only practical approach.

For sellers operating across multiple marketplaces, the same weekly-diff pattern applies to Amazon (where BSR replaces review velocity as the primary signal) — see How to track Amazon BSR over time for the cross-channel playbook.

Legality and Ethics

Etsy listing data is public — every field used by this guide is visible to any logged-out shopper browsing etsy.com. Scraping public marketplace listings for competitive research is on settled legal ground in the US (CFAA does not apply to public data per hiQ v. LinkedIn) and is broadly compliant in the EU under the legitimate-interest basis for B2B competitive intelligence. What Etsy's Terms of Service prohibit is automated access to the internal Etsy API without a partnership, and republishing the scraped data as a competing storefront. Researching a category to inform your own product roadmap is not the activity the terms target.

The ethical line is downstream. Copying a specific competitor's listing wholesale — same title, same photos, same product — is both an Etsy policy violation and a trademark/copyright concern. Using the trend data to identify what aesthetic or theme is winning and then producing your own original work in that direction is exactly what every seller in the category is doing simultaneously; that is normal market behavior, not a violation.

Common Mistakes

  • Trusting page-one rank as a stand-alone signal. Rank is a composite of factors that include the shop's overall sales history, not just the listing's recent performance. A page-one listing from a 10-year-old shop tells you about the shop, not the trend. Always combine rank with age_days to isolate genuinely new winners.
  • Filtering too aggressively on review count. Setting reviews >= 20 cuts out the listings that are most interesting — recent items mid-rise. A listing two weeks old with 4 reviews is a stronger trend signal than one with 200. Use 3 as the noise floor, not 20.
  • Scraping daily. Etsy's relevance ranking does not move meaningfully day-to-day. Daily snapshots produce noise that swamps the actual week-over-week signal. Weekly is the right cadence; running tighter than that wastes compute and proxy traffic without adding information.
  • Skipping the recency sort cross-check. Relevance-sorted results show what is winning; recency-sorted results show what was just listed. The interesting items are the ones that appear in both — that overlap is the working definition of a rising star, and you only see it if you scrape both sort orders.
  • Ignoring the Cloudflare 100-second edge timeout. api.logposervices.com sits behind Cloudflare, so any single HTTP call that takes 100+ seconds returns a 524 to the client even though the job continues server-side. Always poll for status; never expect a synchronous response on a big page count.

Get Started

  1. Sign up at logposervices.com and generate an API key under Tool → API Keys.
  2. export LOGPOSE_API_KEY=lp_xxxxxxx
  3. Pick a seed search URL from the Etsy UI and run the Python script above against it.

Related reading: How to monitor Amazon competitor pricing daily for the same diff pattern applied to price tracking, Apify alternative for e-commerce scraping for the broader managed-vs-DIY comparison, and Best Amazon scraper APIs in 2026 for the cross-marketplace tooling landscape.

External: Etsy, hiQ Labs v. LinkedIn.

Frequently asked questions

Is it legal to scrape Etsy listings?
Etsy listings are public pages — title, price, image, shop name, favorites count, and reviews are visible to anyone without authentication. US case law (hiQ Labs v. LinkedIn, 9th Cir. 2022) confirms that scraping public web data is not a CFAA violation, and EU/UK precedent broadly treats public marketplace listings as lawful to collect for legitimate business purposes such as competitive research. Etsy's Terms of Service forbid automated access to their internal API without a partnership and prohibit republishing the data as a competing storefront. For trend research — pulling listing metadata into a private analysis pipeline — the scrape is on solid ground; reselling the data or building a clone marketplace is where actual legal risk begins.
How do I know a product is trending versus just popular?
Popularity is a stock metric — total favorites, total reviews, total sales over the shop's lifetime. Trend is a flow metric — favorites gained this week, reviews gained this week, listings created in the last 30 days that already rank on page one. A handmade ceramic mug shop with 50,000 lifetime sales is popular; a category where five listings created in the past three weeks all have 40+ reviews is trending. The discovery loop in this guide measures the second signal by re-scraping the same search URL weekly and computing deltas. Stock metrics tell you what already won; flow metrics tell you what is winning right now.
What fields does Etsy return per listing?
A search-page scrape returns the listing title, listing URL, listing ID, price (and discounted price if on sale), currency, shop name, shop URL, primary image URL, favorites count (the heart icon counter), star rating, review count, free-shipping flag, bestseller badge, and listing creation date when present in the markup. The product endpoint adds the full description, all photos, variations, listing tags, materials, processing time, and the full shop's other listings. The shop endpoint returns the shop's full active inventory keyed by listing ID, which is what you compare week-over-week to detect new releases from a competitor.
How often should I re-scrape the same category?
Weekly is the right cadence for most niche research. Etsy's search ranking is recomputed continuously but does not shift meaningfully day-to-day for a stable category — running a daily scrape mostly produces noise. Run the same seed search every Sunday night, diff against the previous week's snapshot keyed by listing ID, and the rising stars are the listings that either appeared net-new on page one or moved up substantially in rank. Faster than weekly is wasted compute and proxy traffic; slower than monthly and you miss the early-rise window that the whole exercise is supposed to catch.
Can I track a competitor shop's new listings?
Yes — scrape the shop endpoint instead of the search endpoint. The shop endpoint returns the full inventory of a given seller keyed by listing ID, which is exactly the shape needed for a new-listing diff. Snapshot once, snapshot again seven days later, and the set difference on listing ID is the shop's net-new releases for the week. This is the most-undervalued signal in Etsy research: when a high-revenue seller releases a new variant, they have already done the trend validation work, and you can ride the same wave without running the same analysis from scratch. The pattern generalizes to any shop URL.
What is the right signal — favorites, reviews, or days-since-listed?
Reviews per day since first listed is the single best composite signal. Favorites are cheap (one click, no purchase) so they overweight casual interest; raw review count favors old listings that have had years to accumulate. Reviews divided by listing age — call it review velocity — captures both purchase intent and recency in one number. A listing two weeks old with 12 reviews is a stronger trend signal than a two-year-old listing with 80 reviews, even though the absolute review counts say the opposite. The cleaning pipeline in this guide computes review velocity as the primary sort key for exactly this reason.

Related posts

Tutorial

How to Monitor Amazon BuyBox Changes (and Get Alerted When You Lose It)

9 min read
Tutorial

How to Track Amazon Competitor Prices Daily (Export to CSV and Google Sheets)

10 min read
Tutorial

How to Enrich Business Leads with Emails, Phones, and Socials

12 min read