StockX Scraper - Ask, Bid, Last Sale by Size
Pricing
from $1.40 / 1,000 market records
StockX Scraper - Ask, Bid, Last Sale by Size
Scrape StockX market data by keyword, category or URL. Every row carries lowest ask, highest bid, last sale, bid ask spread, ask counts, 72 hour and 90 day sales volume, 12 month average price, volatility and premium over retail. Pick a size and every row becomes that size's own order book.
Pricing
from $1.40 / 1,000 market records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
StockX Scraper: Ask, Bid, Last Sale by Size
Pull live market data from StockX, the largest authenticated sneaker and streetwear resale marketplace. Search by keyword, browse a category, or paste StockX URLs, and get back the numbers a reseller actually prices against: lowest ask, highest bid, last sale, the bid/ask spread, how many asks are listed at each shipping speed, 72 hour and 90 day sales volume, 12 month average price, price volatility and the premium over retail.
Pick a size and every row becomes that size's own order book, which is the grain that decides whether a trade is worth doing.
Why this one
| This actor | Typical StockX actor | |
|---|---|---|
| Ask, bid and last sale | on every row, no surcharge | often behind a paid detail fetch |
| Per size ask, bid and last sale | first class row grain, and the full size table on every detailed row | usually a second, billed request per product, or absent |
| Per size sale history | individual completed sales with prices and timestamps, per size | usually absent, or an aggregate window only |
| Bid/ask spread | computed on the row | usually left for you to compute |
| Sales volume | 72 hours, 90 days and 12 months | usually 72 hours only, or none |
| Volatility and premium over retail | on every row | rare |
| Ask depth by shipping speed | standard, next day, expedited, standard express | rare |
| Filters | 16, all sent to StockX itself | usually 2 to 4 |
| Filter honesty | the run reports which filters StockX actually applied and warns when one is ignored | not checked |
| Ordering | 6 StockX orderings, each individually verified to reorder | often includes orderings that silently do nothing |
| Recurring monitoring | built in, with change types and expiry | rare |
| Resume | built in | rare |
On the per size numbers. There are two ways to get them and neither costs an extra request per size. Set a size scale and every row on the result page IS that size, so 40 sizes across 40 products come back for the price of one page. Turn on full product details and each row instead carries the WHOLE size table for its product, every size with its own order book and its own sale history, in one small request per product.
A note on size scales, because the numbers look wrong until you know it. StockX reports a
size on the scale that product publishes, and the men's and women's scales are offset: a US
men's 10 is a US women's 11.5. So a men's 10 search legitimately returns 11.5W for a
women's cut shoe, and a women's 8 search returns 6.5 for a men's cut one. It is the same
physical size. Every row therefore carries requestedSize (the size you asked for, in
StockX's own label) next to size (the size on that product's own scale) and
sizeConversions (the same size in six systems), so a mixed-scale column stays comparable.
What one row looks like
{"recordId": "019b334a-609c-724a-a3f3-c54a4e132b87","rowType": "variant","productId": "019b3346-4879-7c50-b34a-733667f8c741","variantId": "019b334a-609c-724a-a3f3-c54a4e132b87","title": "Nike Dunk Low Retro White Black Panda","brand": "Nike","model": "Nike Dunk Low Retro","urlKey": "nike-dunk-low-retro-white-black-2021","url": "https://stockx.com/nike-dunk-low-retro-white-black-2021","size": "10","sizeType": "us m","requestedSize": "US M 10","sizeConversions": [{ "size": "US M 10", "type": "us m" },{ "size": "UK 9", "type": "uk" },{ "size": "EU 44", "type": "eu" },{ "size": "CM 28", "type": "cm" },{ "size": "KR 280", "type": "kr" },{ "size": "US W 11.5", "type": "us w" }],"lowestAsk": 172,"lowestAskUpdatedAt": "2026-09-05T05:09:43Z","highestBid": 153,"highestBidUpdatedAt": "2026-09-02T05:24:31Z","lastSale": 173,"bidAskSpread": 19,"standardAskCount": 106,"standardLowestAsk": 172,"expressNextDayAskCount": 32,"expressNextDayLowestAsk": 194,"salesLast72Hours": 38,"salesLast90Days": 1364,"averagePriceLast90Days": 223,"salesLast12Months": 3659,"averagePriceLast12Months": 249,"priceVolatility": 0.115084,"currency": "USD","market": "US","pricePremium": 0.821,"releaseDate": "2021-03-10","gender": "men","productCategory": "sneakers","imageUrl": "https://images.stockx.com/images/Nike-Dunk-Low-Retro-White-Black-Product.jpg","scrapedAt": "2026-09-05T09:12:00Z"}
With Fetch full product details on, each row also carries styleId (the manufacturer
style code), colorway, retailPrice, restockDate, sizeConversionTypes, images, the
long product description, and the whole size table: availableSizes is every size the
product offers, and each entry carries that size's own lowestAsk, highestBid,
lastSale, bidAskSpread, askCount, 72 hour and 90 day volume, volatility, premium,
its size in six size systems, and saleHistory, a list of that size's individual completed
sales with a price and a timestamp on each. saleHistoryPoints counts how many recorded
sales the row carries in total.
"availableSizes": [{"size": "10", "sizeType": "us m", "variantId": "...","lowestAsk": 94, "highestBid": 78, "lastSale": 57, "bidAskSpread": 16,"askCount": 41, "salesLast72Hours": 3, "priceVolatility": 0.19,"saleHistory": [{ "price": 57, "soldAt": "2026-09-05T07:43:20.925Z" },{ "price": 97, "soldAt": "2026-08-31T17:18:40.924Z" }]}]
Two ways to start
Search mode. Give one or more search terms (air jordan 1, nike dunk low,
yeezy 350). Each term is walked independently. Leave the terms empty and the run browses
the category you picked instead, so "every Nike sneaker under $150 with a live bid" is a
valid scope with no search term at all.
URL mode. Paste StockX URLs. All of these work:
| URL | What happens |
|---|---|
https://stockx.com/search?s=jordan+1 | walked like a keyword search |
https://stockx.com/category/sneakers | walked like a category browse |
https://stockx.com/category/sneakers?page=3 | starts the walk at page 3 |
https://stockx.com/nike | recognised as a brand page and walked |
https://stockx.com/nike-dunk-low-retro-white-black-2021 | that single product, in full |
A brand landing page and a product page share the same URL shape on StockX, and brand slugs
are hyphenated too (aime-leon-dore), so no string rule can separate them. The actor asks
StockX which one it rendered rather than guessing.
The filters apply in both modes. A filter already present in a pasted URL wins for that URL only. A pasted product URL is the one exception: it always returns that single product.
Input parameters
Filters, all sent to StockX itself
| Parameter | What it does |
|---|---|
category | 15 StockX categories, top level (sneakers, apparel, collectibles) and sub level (lifestyle, performance, luxury, boots, cleats) |
brands | one or more brand slugs, combined with OR |
models | one or more model slugs (dunk, air-force-1, campus-00s), combined with OR |
productLines | one or more product line slugs (blazer, cortez, 860v2) |
gender | men, women, kids, unisex |
color | the 10 colours StockX indexes |
activity | running, basketball, skateboarding, soccer, hiking, golf, football |
shoeHeight | low, mid, high |
market | US, GB, DE, FR, CA, AU or JP. StockX runs a separate order book per country, in its own currency, and the prices genuinely differ. Picking one pins the connection's exit country. |
sizeScale + size | turns on per size rows |
minPriceUsd / maxPriceUsd | sent as one price range |
availableNow | only items with a live ask |
xpressShipOnly | only items StockX already holds and can ship fast |
belowRetailOnly | only items asking under retail |
Narrowings StockX has no filter for, applied to the rows the run reads
| Parameter | What it does |
|---|---|
minLastSaleUsd | drop rows whose most recent sale was below this |
minSalesLast72Hours | drop illiquid rows; the fastest way to find what is actually trading |
hasLiveAskOnly | drop rows with no ask |
hasLiveBidOnly | drop rows with no bid |
Ordering
| Parameter | What it does |
|---|---|
orderBy | asks StockX to order the whole catalogue: featured, most active, release date, lowest ask, highest bid, last sale. This changes which items you get. |
sortResultsBy | rearranges the rows this run collected, after they are read |
Every orderBy value was checked against StockX one at a time and kept only when the
returned order actually changed. StockX also accepts an ascending/descending switch and
ignores it, so this actor does not offer one rather than shipping a control that does
nothing.
Output and limits
| Parameter | Default | What it does |
|---|---|---|
fetchDetails | off | fetch each item's product page for the style code, colourway, retail price, release and restock dates, the full size run and the image set. Charged once per record. |
maxItems | 20 | the single cap on the run. 0 means unlimited. |
maxPages | 0 (unlimited) | optional safety bound per search term or URL |
Resume and recurring updates
| Parameter | What it does |
|---|---|
resumeFromRunId | continue ONE interrupted run without returning or billing what it already collected |
incrementalMode | for scheduled runs of the same search: return only what changed |
stateKey | name a monitoring campaign, or deliberately share one |
emitUnchanged | also return (and bill) rows that did not change |
emitExpired | also return (and bill) rows that disappeared |
In incremental mode each row carries changeType (NEW, UPDATED, REAPPEARED,
UNCHANGED, EXPIRED), changedFields, firstSeenAt and lastSeenAt. A price move
counts as a change: on a resale marketplace that is the signal, not noise. An ask that is
re-listed at the same amount does not, so a quiet market does not bill you a diff with no
difference in it.
EXPIRED is only produced after a run has scanned the tracked search all the way to the
end. A run that was capped, resumed, refused, page limited, or truncated by StockX's own
1000 result ceiling never marks anything expired, because it did not see enough of the
catalogue to know.
Honesty about what StockX returns
StockX returns at most 1000 results per search or category. When a scope hits that ceiling the run says so explicitly and tells you to narrow it. It never reports a truncated scope as a complete one.
Filters are checked, not assumed. StockX echoes back the filter set it resolved on every
result page. The run prints that echo (StockX applied: category=sneakers, color=black) and
warns loudly if a filter it sent was not applied, because a filter that fails open still
returns a full page of results and a large total: neither the row count nor the total can
tell you it was ignored.
A refused run fails, it does not return zero. "We returned nothing" and "we could not read anything" are tracked as two different things, and only their conjunction exits successfully. A connection problem ends the run with a message saying so, never with a green run and an empty dataset.
Promoted placements are dropped. Result pages carry sponsored cards. They are never emitted, so you are never billed for an advert.
Send results into your apps (MCP connectors)
Optionally pipe results into Notion, Linear, Airtable or Apify via MCP connectors, in the Export to your apps (MCP connectors, optional) section of the input. Each connector receives a condensed summary per record; the complete record always stays in the dataset, so nothing is lost if you leave this off.
mcpConnectors- the MCP connectors to export this run's records into (Notion, Linear, Airtable, Apify). Leave it empty and nothing is exported.notionParentPageUrl- Notion connector only: the page under which one child page per record is created. Required whenmcpConnectorsincludes Notion, ignored otherwise.maxNotifyListings- how many records are exported to each connector in one run, default 50. This caps the export only; it never changes what the dataset returns.
Export runs after the dataset is complete and is best effort: if a connector is unreachable the run still succeeds with a warning, and your records are still in the dataset.
What you are charged for
The Store page shows the current rates. What each charge means:
- Actor start, once per run.
- Market record, per row returned. With a size scale set, one row is one size.
- Full product details, once per record, and only when
fetchDetailsis on.
The details surcharge is charged after a record is successfully returned, never per request and never per retry, so the surcharge count can never exceed the number of rows you received. A run that returns nothing charges nothing beyond the start event.
Example inputs
The order book for one size, across a brand
{"mode": "search","searchTerms": ["nike dunk"],"sizeScale": "mens","size": "10","orderBy": "most-active","maxItems": 100}
Everything trading right now, under retail
{"mode": "search","category": "sneakers","belowRetailOnly": true,"minSalesLast72Hours": 5,"orderBy": "most-active","maxItems": 200}
Daily monitoring of one search
{"mode": "search","searchTerms": ["travis scott jordan 1"],"incrementalMode": true,"stateKey": "travis-scott-watch","maxItems": 0}
Paste URLs
{"mode": "url","urls": ["https://stockx.com/search?s=jordan+1","https://stockx.com/nike","https://stockx.com/nike-dunk-low-retro-white-black-2021"],"fetchDetails": true,"maxItems": 50}
Notes
- Prices are quoted in ONE market's currency, and every row states which:
marketandcurrency. The default is the US market in US dollars. StockX decides the market from the connection's exit country, so if no exit is available in the market you asked for, the run says so loudly and the rows still state what they were actually quoted in. pricePremiumis StockX's own ratio of market price to retail, so0.821means the item trades at about 82 percent above retail.priceVolatilityis StockX's own 12 month volatility figure.- Ask counts by shipping speed overlap: an item held by StockX is counted in both the express buckets and the standard one.
- Sponsored cards on result pages are dropped, so a page of 48 cards can yield fewer than 48 rows.