Curtsy Fashion Resale Scraper - Listings, Sellers & Reviews avatar

Curtsy Fashion Resale Scraper - Listings, Sellers & Reviews

Pricing

from $1.10 / 1,000 listing records

Go to Apify Store
Curtsy Fashion Resale Scraper - Listings, Sellers & Reviews

Curtsy Fashion Resale Scraper - Listings, Sellers & Reviews

Scrape Curtsy, the US secondhand fashion marketplace: listings with brand, size, list vs original retail price, condition, photos and seller profile. Keyword and brand search, category browse, item and closet links, seller reviews, incremental monitoring, resume, MCP export.

Pricing

from $1.10 / 1,000 listing records

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Share

Curtsy Scraper: Secondhand Fashion Listings, Sellers & Reviews

Curtsy Scraper turns Curtsy (curtsyapp.com), the US secondhand fashion marketplace, into a clean product data API. Collect listings across 1000+ brands (Lululemon, Free People, Zara and more) with brand, size, list price vs original retail price, condition, photos and seller profile. Search by keyword or brand, browse a category, paste item, closet or collection links, attach seller review entries and listing comments, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

Why This Scraper?

  • Three ways in. Keyword search, brand or category browse, or paste item, closet and collection links. No need to build URLs by hand.
  • List vs retail pricing. Every record carries the list price, the original retail price and the suggested price, so resale margins are computable straight from the dataset.
  • Seller trust signals. Seller name, sales and purchase counts, positive rating percentage, response time, time to ship and state, plus seller review entries (rating, date, text) and listing comments.
  • Detail depth on demand. Switch the detail record, seller reviews and comments on or off per run, and pay only for what you use.
  • Built for schedules. Incremental mode returns only new and changed listings on recurring runs, and a refused run fails loudly instead of returning an empty dataset.
  • Full photo sets. Every listing ships the complete photo gallery, not just the cover thumbnail.

Use Cases

  • Resale arbitrage and sourcing: track list prices against original retail across brands and categories to find underpriced listings early.
  • Market and pricing research: build price histories per brand, category or size for fashion-resale analytics.
  • Inventory monitoring: watch a seller's closet or a collection and get only the new or changed listings on each scheduled run.
  • Trend and demand analysis: correlate heart counts, review volume and time-on-market by brand, color and category.
  • App and dashboard builders: feed clean listing records into your own tooling through the API or MCP connectors.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
id"Ab12Cd34Ef"
title"Sample Midi Dress"
brand"Sample Brand"
category"Dresses"
size / sizeCategory"M" / "women"
condition"New with tags" or "Pre-owned"
price35
retailPrice98
suggestedPrice40
priceWithFees37.75
sold / availablefalse / true
loves12
freeShipping / isSteal / hot / isNewtrue / false / false / true
imageUrl / imageUrls / numImagesfull gallery URLs / 4
sellerId / sellerName"k8mbYd8Xuj" / "Seller Name"
sellerPositiveRatings"98%"
sellerSales / sellerPurchases22 / 54
sellerResponseTime / sellerTimeToShip"1 day" / "2.4 days"
postedAt"2026-01-01T00:00:00.000Z"
descriptionseller description (with details on)
userSizingseller sizing note (with details on)
sellerReviewsrating, date, text, reviewer avatar
commentsauthor, text, date, type
urllisting link

Closet runs also resolve the seller profile behind the closet; collection runs walk the whole collection feed.

How to Use

  1. Pick a mode: search (keyword, brand or category) or URL mode (paste links).
  2. Fill in the fields for that mode, and switch on details, reviews and the filters you need.
  3. Set Max items to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV or Excel, or read it through the API.

Browse a brand:

{
"mode": "search",
"brand": "Lululemon",
"maxItems": 50
}

Keyword search with detail records:

{
"mode": "search",
"query": "yellow dress",
"fetchDetails": true,
"fetchReviews": true,
"maxItems": 50
}

Category browse with price filters:

{
"mode": "search",
"category": "dresses",
"priceMin": 20,
"priceMax": 80,
"color": "floral",
"maxItems": 100
}

Paste item, closet or collection links:

{
"mode": "url",
"startUrls": [
"https://curtsyapp.com/item/sample-route/Ab12Cd34Ef",
"https://curtsyapp.com/closet/SampleId1"
],
"fetchDetails": true,
"maxItems": 50
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("abotapi/curtsy-app-scraper").call(run_input={
"mode": "search",
"brand": "Lululemon",
"maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_dataset_items():
print(item)

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('abotapi/curtsy-app-scraper').call({
mode: 'search',
brand: 'Lululemon',
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

You can also export the dataset to JSON, CSV, Excel, or integrate it with Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Tips

  • Max items is the only cap that stops a run early. Pages walk forward until the cap is reached or listings run out; Max pages exists as an optional extra guard and defaults to no cap.
  • Details and reviews cost extra reads. With Read listing details on, every listing is billed once as detail enrichment. Each delivered review and comment is billed individually. Turn them off for a leaner run.
  • Resume a large pull. Paste a previous run ID into Resume from a previous run to continue where it stopped without returning the same listings.
  • Schedule incremental runs. Turn on incremental mode and the actor remembers what it already delivered: the first run returns every matching listing as NEW, later runs return only NEW and UPDATED. Heart counts and relative time labels never mark a listing UPDATED; a price, retail price, status, seller-stat or review-count change does.

Send results into your apps (MCP connectors)

Results can be piped straight into the apps you already use through Apify MCP connectors. Authorize a connector under Apify, Settings, API & Integrations, then select it in the input. Notion receives a rich page-per-listing export; other connectors receive a best-effort write or digest. This is optional: leave the field empty and the run is unchanged.

ParameterTypeDefaultDescription
mcpConnectorsarrayemptySelect one or more authorized MCP connectors.
notionParentPageUrlstringemptyURL or id of the Notion page under which listing pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchSearch and browse, or paste item, closet and collection links.
querystringemptyFree-text search across titles, brands and descriptions.
brandstringemptyBrand name, e.g. Lululemon or Free People; normalized to the marketplace's own brand feed.
categorystringemptyBrowse one category, e.g. dresses, tops, shoes, handbags.
colorstringemptySingle color word applied to the browse feed.
priceMinintegeremptyKeep listings listed at or above this price.
priceMaxintegeremptyKeep listings listed at or below this price.
freeShippingOnlybooleanfalseKeep only listings the seller ships for free.
nwtOnlybooleanfalseKeep only listings marked New With Tags (evaluated per listing).
startUrlsarraysampleURL mode: listing links, closet links, collection links or bare listing ids.
urlsarrayemptyAlias accepted under the name other Apify actors use for URL mode.
fetchDetailsbooleantrueMerge the detail record: description, sizing note, fees, full photos, seller stats. Billed as detail enrichment per enriched listing.
fetchReviewsbooleantrueAttach seller review entries and listing comments. Requires Read listing details. Each delivered entry is billed individually.
maxReviewsinteger20Cap the review entries attached per listing; 0 skips reviews.
maxItemsinteger20The one cap that stops a run early.
maxPagesinteger0Optional page cap; zero means no page cap.
proxyConfigurationobject{'useApifyProxy': True}Connection settings; Residential is recommended for large or frequent runs.
resumeFromRunIdstringemptyContinue one specific interrupted run from its run or dataset ID.
incrementalModebooleanfalseReturn only NEW and UPDATED listings on recurring runs.
stateKeystringemptyName a monitoring campaign to keep its state stable across config edits.
emitUnchangedbooleanfalseAlso return, and bill, unchanged listings.
emitExpiredbooleanfalseAlso return, and bill, listings no longer found once a run fully scanned the search.
ignoreFieldsForChangesarrayemptyExtra fields excluded from change detection on top of the defaults.
mcpConnectorsarrayemptyMCP connectors; see the section above.
notionParentPageUrlstringemptyNotion parent page for the page-per-listing export.
maxNotifyListingsinteger50Connector write cap per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

One listing record with details and reviews:

{
"id": "Ab12Cd34Ef",
"title": "Sample Midi Dress",
"brand": "Sample Brand",
"category": "Dresses",
"size": "M",
"sizeCategory": "women",
"condition": "Pre-owned",
"price": 35,
"retailPrice": 98,
"suggestedPrice": 40,
"priceWithFees": 37.75,
"sold": false,
"loves": 12,
"isNWT": false,
"freeShipping": false,
"imageUrl": "https://assets.example.com/tr:f-webp,w-180/sample-photo.jpg",
"imageUrls": ["https://assets.example.com/tr:f-webp,w-180/sample-photo.jpg"],
"numImages": 4,
"description": "Full seller description text appears here when details are on.",
"userSizing": "Seller is 5'6\", 130lbs",
"sellerId": "SampleId2",
"sellerName": "Seller Name",
"sellerPositiveRatings": "98%",
"sellerSales": 22,
"sellerPurchases": 54,
"sellerTimeToShip": "2.4 days",
"postedAt": "2026-01-01T00:00:00.000Z",
"sellerReviews": [
{
"reviewRating": 5,
"reviewText": "Great seller, fast shipping!",
"reviewDate": "2026-07-02",
"reviewerAvatar": "https://assets.example.com/sample-avatar.jpg"
}
],
"sellerReviewsCount": 27,
"comments": [],
"commentsCount": 0,
"url": "https://curtsyapp.com/item/sample-route/Ab12Cd34Ef",
"detailUrl": "https://curtsyapp.com/item/sample-route/Ab12Cd34Ef",
"changeType": "NEW",
"changedFields": [],
"firstSeenAt": "2026-01-01T00:00:00.000Z",
"lastSeenAt": "2026-01-01T00:00:00.000Z"
}

Plan Requirement

This actor uses Apify's pay-per-event pricing: each listing record, each detail-enriched listing, each delivered review entry and each delivered comment entry is billed per the Pricing tab. Connection usage is billed by Apify as usual.

FAQ

How much does it cost?

You pay per event: one charge per listing record, one per detail-enriched listing, one per delivered review entry and one per delivered comment entry, plus the usual Apify compute and connection usage. See the Pricing tab for the exact per-event prices; Max items bounds a run's size and cost.

This actor collects only publicly available listing data. You are responsible for using it in line with the site's terms of use, applicable privacy law (GDPR, CCPA) and your own regulations; listings carry personal data (seller names, review authors), so have a lawful basis before processing it.

Can I get only new or changed listings on a schedule?

Yes. Turn on Incremental changes for scheduled runs: the first run returns everything as NEW, later runs return only NEW and UPDATED listings, and optionally EXPIRED ones with Emit expired records. Use State key to keep a monitoring campaign stable across configuration edits.

Why did a run return fewer results than Max items?

Searches and filters can legitimately match fewer listings than the cap, and keyword searches return a fixed-size result set (the marketplace caps them), so a keyword run stops once that set is delivered. Raise Max items or widen the filters to collect more.

Why did my run fail instead of returning an empty dataset?

If the marketplace refuses every read (a connection problem rather than an empty search), the run fails loudly with a message instead of pretending nothing matched. Re-run it shortly; transient connection problems usually clear on their own.

Can I use it with AI agents or MCP?

Yes. The actor ships an MCP connector surface: authorize a connector under Apify, Settings, API & Integrations, select it in the input, and results are written to your app after every run. The dataset is also readable through the API for any agent framework.

🔗 Want more classifieds data?

Pair this actor with these related scrapers from the same team:

🏷️ Poshmark Scraper
Scrape Poshmark fashion-resale listings: keyword search, brand and category browse, sold...
🏷️ Vinted Multi-Country Scraper
Scrape Vinted across 27 country marketplaces: keyword search with brand, price and...
🏷️ ThredUp Scraper
Scrape ThredUp resale listings by keyword, department, brand, size, condition, price or...
👗 Showpo Scraper
Scrape Showpo women's fashion by keyword, collection or URL. Extract product prices...
🏷️ Vinted.fr
Scrape Vinted.fr, France's C2C second-hand fashion marketplace: search with...
👗 24S Scraper
Scrape 24S luxury fashion by category, filters, or URL. Extract brand, name, price...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.