Grailed Scraper at a glance
Grailed Scraper is a ready-to-run Apify actor from abotapi for collecting web data. Its documented output includes id, row kind, listing, designer and ask price, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.30 per 1,000 results on the Apify Free plan and from $1.90 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Web data
- Pricing
- $2.30 per 1,000 results (Free plan), from $1.90 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 30 options
Scrape Grailed by keyword, category, designer, condition, size or URL. Extract prices and price history, descriptions, measurements, shipping, seller profiles and reviews. Includes change tracking to monitor new, updated and removed listings.
What Grailed Scraper can do
- Four ways to find listings. Search by keyword, walk any combination of the store's own facets (department, category, designer, condition, size, price), watch named sellers, or paste store URLs directly.
- Ask price and ask history on every row. Each listing carries the store's own record of every prior asking price, so a price cut is visible, not just the current number.
- Listing detail on demand. Switch on Fetch listing details for the description, measurement table, photo set and deeper seller fields, only when you need them, billed only then.
- Sellers, reviews and closets. Read a seller's profile, pull their reviews as their own rows, or walk their whole on-sale closet like a normal search.
- Built for monitoring. Incremental mode returns only new, updated and reappeared listings on repeat runs, treats an ask price move as a real change (not noise), and a refused run fails loudly instead of returning an empty dataset.
- URL mode for direct control. Paste a single listing, a category, a designer, a search page or a seller profile URL and it is read exactly as scoped, with page and price filters still applying.
Choose what to collect
These inputs let you configure Grailed Scraper - Listings, Prices, Sellers & Reviews. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | How to start the scrape. 'search' runs store searches. 'url' processes the store URLs you paste: a listing URL is fetched as a single listing in full, a category or designer URL is paged like a search, and a seller profile URL reads the seller. The price and ordering filters below apply in BOTH modes; search terms, sellers and the catalogue facets (categories, designers, conditions, sizes) apply in search mode only. |
searchTermsarray | One or more things to search the marketplace for, for example 'varsity jacket', 'cargo pants', 'band tee'. Each term is scraped as its own scope with the catalogue facets below applied. Search mode ONLY: in URL mode the pasted URLs decide their own scope instead. |
sellerUsernamesarray | One or more Grailed usernames to read as sellers. Each produces a seller profile row; turn on the two toggles below to also read the seller's reviews or their on-sale listings. Search mode ONLY: in URL mode, paste seller profile URLs instead. |
fetchSellerReviewsboolean | Read each seller's reviews and emit them as their own rows (rowType 'review'), with the rating, the note, the tags and the listing the review refers to. Each review is a dataset row of its own and is billed as one. Applies to sellers named in Seller usernames and to seller profile or feedback URLs pasted in URL mode, not to listings found by search or browse. |
maxReviewsPerSellerinteger | Stop reading a seller's reviews after this many review rows. Leave empty for no per-seller limit (all of a seller's reviews, bounded only by Max items). Applies only when 'Fetch seller reviews' is on, and each seller counts separately. Applies to sellers named in Seller usernames and to seller profile or feedback URLs pasted in URL mode. In Incremental mode with Emit expired records, a seller whose reviews were cut by this limit never marks reviews EXPIRED. |
includeSellerListingsboolean | After the profile row, walk the seller's on-sale listings through the store's own feed, as normal product rows (the Max items cap applies to them like any other row). Applies to sellers named in Seller usernames and to seller profile or feedback URLs pasted in URL mode. |
categoriesarray | Only browse these categories. Accept a whole section ('tops', 'footwear'), a subcategory name from a category page URL ('long-sleeve-t-shirts'), or the store's own feed path ('tops.short_sleeve_shirts'). A name the store does not serve stops the run with a clear message rather than walking a wider scope. Search mode ONLY: in URL mode the pasted URL decides its own scope. |
Show 23 more inputs
| Input | What it controls |
|---|---|
designersarray | Only browse these designers, by the name the store itself uses on designer pages and on the rows, for example 'Rick Owens' or 'Our Legacy'. Each name narrows the feed; a name the store does not serve simply matches nothing. Search mode ONLY: in URL mode the pasted URL decides its own scope. |
conditionsarray | Only browse listings in these conditions, as the store grades them: 'new', 'gently used', 'used' or 'worn'. Search mode ONLY: in URL mode the pasted URL decides its own scope. |
sizesarray | Only browse listings in these sizes, exactly as the store labels them: letter sizes ('s', 'm', 'l', 'xl'), waist sizes ('30', '32'), or 'one size'. Search mode ONLY: in URL mode the pasted URL decides its own scope. |
urlsarray | Paste store listing URLs (https://www.grailed.com/listings/12345678), search page URLs (https://www.grailed.com/shop/search?query=jacket), category URLs (https://www.grailed.com/categories/footwear or https://www.grailed.com/categories/womenswear/tops), designer URLs (https://www.grailed.com/designers/designer-name) designer plus category URLs (https://www.grailed.com/designers/designer-name/footwear), or seller profile and seller feedback URLs (https://www.grailed.com/username). A sort= value of price_asc, price_desc or newest on a pasted URL sets the row ordering when the Order the returned rows by field is left at the store ranking. Browse, collections and shop curation pages are skipped with a warning. Left untouched, the field scrapes one example of each supported page type. Add ?page=3 to any browse URL to start walking from that page. A pasted URL decides its own scope: the price and ordering filters below still narrow browse scopes, while the catalogue facets (categories, designers, conditions, sizes) are search mode only. A pasted listing URL returns that single listing in full. |
departmentstring | Which storefront department to read. Applies in BOTH search mode and URL mode: search mode sends it with every request, and in URL mode it fills in only when a pasted URL does not name a department of its own. |
minPriceUsdinteger | Only keep listings whose current ask price is at least this many US dollars. The store applies this at the feed itself, so a filtered run reads a narrowed feed. Applies in BOTH search mode and URL mode (a pasted single-listing URL always returns its listing in full). |
maxPriceUsdinteger | Only keep listings whose current ask price is at most this many US dollars. The store applies this at the feed itself, so a filtered run reads a narrowed feed. Applies in BOTH search mode and URL mode (a pasted single-listing URL always returns its listing in full). |
sortResultsBystring | Arranges the rows this run collected, after they are read. The store serves one ranking of its own; the alternatives are a local tidy up of one run's output, not a catalogue wide ordering. Applies in BOTH search mode and URL mode. |
fetchDetailsboolean | Fetch each listing's own page for the description, the measurement table, the photo set and the deeper seller fields. Slower, and charged once per record. Leave off for a fast crawl: the ask price, the ask history, the condition, the size and the seller's score card are included either way. |
maxItemsinteger | The single cap on this run: stop after collecting this many records (listings, sellers and reviews together) across all search terms, sellers and URLs. Set 0 for unlimited. |
maxPagesinteger | Safety bound on how many feed pages to walk per search term, seller or URL. Leave empty (0) for no page limit: the run then stops at Max items, or at the store's own per-scope page bound, not here. Does not impose a separate cap below Max items. |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for records already collected there. Use this after an interrupted or capped run. For recurring monitoring of the same search, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or weekly recurring monitoring of the same search, for example a price watch. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. What is compared: every field of the record, including the ask price, original price, price history, sold state and sold price, title, description, size, condition, category, designers, badges and seller details, so an ask-price move is reported as UPDATED (on a resale marketplace it is the signal, not noise). What is excluded: only the scrape time by default; name any field that turns out to be noisy in Ignore fields when detecting changes (it stays in the row, it just never triggers UPDATED), or limit changes to price and sold state with What counts as a change. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately per search, URL, seller and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search terms, URLs, sellers and filters, so two different searches never mix state. |
emitUnchangedboolean | Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want a full snapshot every run. |
emitExpiredboolean | Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search: not when Max items capped it, not when a per-seller review limit cut a seller's reviews, not when Resume was used, and not when the run was refused. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking. |
changeScopestring | All fields (default): any change to the listing record, except the scrape time and the fields you list under Ignore fields for changes, returns an UPDATED row. Price and sold state only: only a change to the ask price, original price, price history, sold flag, sold date or sold price returns an UPDATED row; edits to the description, badges, size, seller details or other fields never do. Seller and review rows are always compared in full. Changing this option keeps the saved baseline; the next run compares against it under the new rule. |
compactUpdatesboolean | Off by default. When on, UPDATED rows (and EXPIRED rows) are short: listing id, url, title, designer, size, current price and sold state, plus priceChanges showing the old and new value of each moved price or sold field. NEW rows always carry the complete record. Compact rows do not carry the listing description or measurements, so the listing details fee is not charged for them. |
expireAfterMissedScansinteger | Only used with Emit expired records. A listing is marked EXPIRED only after it has been missing from this many full scans in a row (default 1). Raise it (for example 3) so a listing that briefly drops out of the search results is not reported as gone. A listing that comes back resets the count. EXPIRED means the listing is no longer found in the search; without opening the listing it cannot tell a sold or removed listing from one that only dropped out of the results, so use the sold fields for sale status. |
ignoreFieldsForChangesarray | Optional. Field names to exclude from UPDATED change detection, in addition to the scrape time, which is always ignored. Use this if a field turns out to be noisy in your setup, for example followerCount, bumpedAt, heat or coverPhoto. Use a dotted name such as shipping.other to ignore a key inside a nested block (or inside every element of a list) while the rest of it stays compared. The ignored fields stay in the returned rows. |
mcpConnectorsarray | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, not the full record; the complete record always stays in the dataset. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL or id of the Notion page under which record pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on records written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
recordIdID (text)rowTypeRow kind (text)titleListing (text)designerDesigner (text)priceAsk price (number)originalPriceOriginal ask (number)askHistoryAsk history (array)sizeSize (text)conditionLabelCondition (text)categoryCategory (text)departmentDepartment (text)soldSold (text)Show 64 more fields
soldPriceSold price (number)sellerUsernameSeller (text)sellerRatingSeller rating (number)sellerRatingCountSeller ratings (number)sellerSalesSeller sales (number)coverPhotoPhoto (image)shippingUsUS shipping (number)descriptionDescription (text)ratingReview rating (number)reviewNoteReview note (text)reviewListingUrlReviewed listing (link)urlURL (link)changeTypeChange type (incremental mode) (text)changedFieldsChanged fields (incremental mode) (array)firstSeenAtFirst seen (incremental mode) (date)lastSeenAtLast seen (incremental mode) (date)subcategorySubcategory (text)colorColor (text)locationLocation (text)soldAtSold at (text)buyNowBuy now (text)makeOfferMake offer (text)createdAtCreated at (text)bumpedAtBumped at (text)photoCountPhoto count (number)heatHeat (number)followerCountFollower count (number)scrapedAtScraped at (text)prettySizePretty size (text)exactSizeExact size (text)measurementsMeasurements (array)measurementCountMeasurement count (number)photosPhotos (array)stylesStyles (array)badgesBadges (array)wasDigitallyAuthenticatedWas digitally authenticated (text)shippingShipping (object)detailCarriedForwardDetail carried forward (text)usernameUsername (text)sellerUrlSeller url (link)sellerAvatarUrlSeller avatar url (image)locationAbbreviationLocation abbreviation (text)countryCodeCountry code (text)totalBoughtAndSoldTotal bought and sold (number)listingsForSaleListings for sale (number)ratingAverageRating average (number)ratingCountRating count (number)salesCountSales count (number)ratingTagsRating tags (array)purchasesPurchases (number)wouldSellToAgainWould sell to again (number)trustedSellerTrusted seller (text)verifiedVerified (text)quickResponderQuick responder (text)speedyShipperSpeedy shipper (text)powerSellerGroupPower seller group (text)reviewIdReview id (text)reviewTagsReview tags (array)reviewCreatedAtReview created at (text)reviewListingIdReview listing id (text)reviewListingDesignerReview listing designer (text)reviewListingDescriptionReview listing description (text)priceChangesPrice changes (object)variantChangesVariant changes (array)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"recordId": "00000001",
"rowType": "product",
"listingId": "00000001",
"url": "https://www.grailed.com/listings/00000001-sample-designer-sample-wool-sweater",
"title": "Sample Designer Sample Wool Sweater",
"designer": "Sample Designer",
"designers": [
"Sample Designer"
],
"price": 210,
"originalPrice": 260,
"askHistory": [
260,
235,
210
],
"sold": false,
"size": "m",
"condition": "is_gently_used",
"conditionLabel": "Gently Used",
"categoryPath": "tops.sweaters_knitwear",
"department": "menswear",
"buyNow": true,
"makeOffer": true,
"coverPhoto": "https://images.example.com/sample-sweater.jpg",
"shippingUs": 12,
"sellerUsername": "sample_seller_00",
"sellerUrl": "https://www.grailed.com/sample_seller_00",
"sellerRating": 4.9,
"sellerRatingCount": 32,
"sellerSales": 64,
"scrapedAt": "2026-01-01T00:00:00Z"
}Ways to use this data
- Resale price research: track ask price moves and the store's own price-drop history across designers and categories to spot markdowns and value.
- Sourcing and reselling: monitor specific categories, designers or sizes for new listings the moment they post.
- Seller and reputation research: pull a seller's profile, rating average, rating tags and reviews before buying or partnering.
- Marketplace analytics: build historical datasets of listings, prices and conditions for trend and demand analysis.
- Personal shopping alerts: schedule Incremental mode against a saved search and get only what is new or changed.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Grailed Scraper return?
The documented output for Grailed Scraper includes id, row kind, listing, designer, ask price, original ask, ask history and size. Availability of each field depends on the source page and the selected mode.
How much does Grailed Scraper cost?
It costs $2.30 per 1,000 results on the Apify Free plan and from $1.90 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you turn on Emit unchanged. Unchanged listings still count toward each source's share of Max items, so give a monitoring run a Max items above the size of the search (or 0), otherwise listings ranked below that slice are never checked.
Why did a run with several search terms return fewer rows than I expected?
Every search term, seller and URL in one run shares a single Max items budget and a single dedup check. When the budget caps a walk mid-page, every row on that page is marked as handled, even the ones the cap left no room to keep. A later, overlapping search term or seller scope in the same run then treats those rows as already collected and does not offer them again, so the total can land below Max items even though the store still has matching listings. Run heavily overlapping searches on their own, or raise Max items so a shared page clears before the run moves on.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
