# 👟 StockX Sneaker & Streetwear Market Data (`inexhaustible_glass/stockx-sneaker-market-data`) Actor

Live StockX price, bid/ask, sales history, and size-by-size market data by product URL or search keyword. Reads StockX's own internal market-data API, not scraped page text.

- **URL**: https://apify.com/inexhaustible_glass/stockx-sneaker-market-data.md
- **Developed by:** [Hitman studio](https://apify.com/inexhaustible_glass) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 👟 StockX Sneaker & Streetwear Market Data

Live price, bid/ask, sales history, and a full size-by-size breakdown for
any sneaker or streetwear item on StockX — by product URL or search
keyword. No login, no API key.

> Keywords: stockx scraper, stockx api, sneaker price api, sneaker resale
> data, stockx market data, sneaker bid ask, jordan price tracker, yeezy
> price tracker, sneaker reseller tool.

### 🌟 Why this one

StockX protects its pages with a real Cloudflare managed JS-challenge —
confirmed by direct testing: a plain HTTP request (even with full browser
headers) and even a stealth Firefox browser both get stuck on StockX's
"Just a moment..." interstitial. Most scrapers either give up here or lean
on an expensive paid residential proxy + CAPTCHA-solving service.

This Actor gets through using **CloakBrowser**, a free, open (MIT-licensed)
stealth-Chromium wrapper — confirmed by direct, repeated testing on the real
site. No paid proxy, no CAPTCHA-solving subscription.

- **Reads the real market-data API, not page text** — once past the
  challenge, this Actor doesn't scrape visible numbers off the page. It
  reads the exact internal GraphQL responses (`GetMarketData`,
  `GetProductListings`) that StockX's own frontend uses to render
  price/bid/ask/sales — the same numbers a logged-in buyer sees, straight
  from the source, not re-typed from the DOM.
- **Full size-by-size breakdown** — lowest ask, highest bid, last sale, and
  90-day average/count *per size*, not just one blended number for the
  whole product. Built by joining StockX's own variant IDs to their size
  labels — most scrapers skip this because it isn't on the surface of a
  single API call.
- **Search by keyword, not just by URL** — give it "air jordan 4" or "yeezy
  350" and it finds and fetches every matching product itself.
- **Honest about the one real limitation**: Cloudflare's challenge is
  probabilistic, not absolute — confirmed by repeated direct testing (most
  page loads pass immediately; occasionally one needs a retry). The Actor
  launches one browser session per run and reuses it for every item, so
  only the very first page in a run typically needs a retry — everything
  after that reuses the already-cleared session. A page that still can't
  clear it after retrying comes back as one clear error row, never a
  silent empty result.

### ⚙️ How it works

1. Launches a free, open-source stealth Chromium session (no proxy, no
   CAPTCHA solver).
2. For each search keyword, loads StockX's own search results page and
   pulls out every matching product's URL directly from the rendered page.
3. For each product (direct or found via search), loads its StockX page and
   captures the real `GetMarketData` + `GetProductListings` API responses
   StockX's own frontend fires to render the page.
4. Joins the per-size variant IDs to their size labels (from the listings
   response) and normalizes everything into one clean row per product.

### 🚀 Quick start

```json
{ "searchQueries": ["air jordan 4"], "maxResultsPerSearch": 10 }
```

Or by direct product URL:

```json
{ "productUrls": ["https://stockx.com/air-jordan-4-retro-black-cat-2025"] }
```

Or via the API, once published:

```bash
curl "https://api.apify.com/v2/acts/stockx-sneaker-market-data/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries": ["yeezy 350"], "maxResultsPerSearch": 5}'
```

### 📥 Input

| Field | Type | Default | Description |
|---|---|---|---|
| `productUrls` | array | `[]` | Full StockX URLs or bare slugs — one per line |
| `searchQueries` | array | `[]` | Keywords to search StockX for |
| `maxResultsPerSearch` | integer | `10` | Max products fetched per search (1–50) |
| `includeSampleListings` | boolean | `true` | Attach a sample of individual seller listings per product |

> ⚠️ **At least one of `productUrls` or `searchQueries` is required** — if
> both are empty, the Actor runs one example search ("air jordan 4") so a
> first run never comes back completely empty.

### 📤 Output

| Field | Description |
|---|---|
| `title`, `style_id`, `colorway`, `retail_price`, `release_date` | Product identity |
| `lowest_ask`, `highest_bid`, `number_of_asks`, `number_of_bids` | Current market state (blended across all sizes) |
| `last_sale`, `sales_last_72h`, `last_sale_change_pct` | Most recent sale |
| `avg_price_90d`, `sales_count_90d`, `avg_price_annual`, `sales_count_annual` | Trailing price/volume stats |
| `size_variants` | **Full per-size breakdown** — lowest ask, highest bid, last sale, 90-day avg/count, for every size StockX lists |
| `sample_listings` | A sample of individual seller listings (size, condition, price), when `includeSampleListings` is on |
| `product_url` | Direct link to the product on stockx.com |

```json
{
  "record_type": "product",
  "title": "Jordan 4 Retro Black Cat (2025)",
  "style_id": "FV5029-010",
  "colorway": "Black/Black/Light Graphite",
  "retail_price": 220,
  "lowest_ask": 259,
  "highest_bid": 542,
  "last_sale": 333,
  "avg_price_90d": 316,
  "sales_count_90d": 5963,
  "size_variants": [
    { "size": "9", "lowest_ask": 263, "highest_bid": 197, "last_sale": 357, "avg_price_90d": 310 }
  ],
  "product_url": "https://stockx.com/air-jordan-4-retro-black-cat-2025"
}
```

A product that fails outright (bad slug, or a challenge that never clears)
produces one `record_type: "error"` row with a real error message — never a
silent empty result.

### 🎯 Use cases

- **Reseller price tracking** — monitor lowest ask / last sale across a
  whole catalog of SKUs
- **Size-level arbitrage research** — spot which specific sizes are
  under/over-priced relative to the rest of the size run
- **Market research** — track 90-day/annual average price and sales volume
  by model or release
- **Drop monitoring** — run searches on a schedule to catch new releases
  and their opening market price

### 🔌 Integration examples

**Python (apify-client):**

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("stockx-sneaker-market-data").call(
    run_input={"searchQueries": ["air jordan 4"], "maxResultsPerSearch": 10}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["lowest_ask"], item["last_sale"])
```

**JavaScript (apify-client):**

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('stockx-sneaker-market-data').call({
    productUrls: ['https://stockx.com/air-jordan-4-retro-black-cat-2025'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### 📊 Performance & reliability

| Metric | Value (measured, not estimated) |
|---|---|
| Cost per product | ~$0.0001–0.0005 when no retry is needed; up to ~$0.006/product on a run where some items needed a retry (real cloud runs, tracked via Apify REST API) |
| Proxy required | No — confirmed by direct testing with a free, open stealth browser |
| CAPTCHA-solving service required | No |
| Login / API key required | No |
| Data source | StockX's own internal GraphQL API (the one stockx.com's own page calls) |
| Challenge handling | Up to 4 automatic retries per item; a sustained failure surfaces as one clear error row, never a silent gap |
| Typical time per item | ~5–10s once the run's first page has cleared Cloudflare (polls for data instead of a fixed wait) |

### ❓ FAQ

**Does this need a StockX login or API key?**
No — it reads the same public, logged-out market-data API StockX's own
product page calls.

**Is this affiliated with StockX?**
No. It's an independent tool reading the same public data StockX's own
website serves to any visitor — not an official StockX product.

**Why do I sometimes see an error row instead of data?**
StockX's Cloudflare challenge is probabilistic — most loads pass straight
through, but an occasional one needs a retry. The Actor retries
automatically; a row only comes back as an error if every retry failed
(e.g. the product slug doesn't exist).

**Can I place bids or offers with this?**
No. This Actor only reads public market data — it doesn't bid, buy, sell,
or touch your StockX account in any way.

### ⚖️ Notes

Reads only StockX's own public, already-listed market data — no login, no
bidding, no private account data.

# Actor input Schema

## `productUrls` (type: `array`):

Full StockX product URLs, or just the slug (e.g. "air-jordan-4-retro-black-cat-2025"). One per line.

## `searchQueries` (type: `array`):

Keywords to search StockX for (e.g. "air jordan 4", "yeezy 350"). Every matching product found is fetched.

## `maxResultsPerSearch` (type: `integer`):

How many products to fetch per search query (1-50).

## `includeSampleListings` (type: `boolean`):

Attach a sample of individual seller listings (condition, size, price) per product, not just the aggregate market data.

## Actor input object example

```json
{
  "productUrls": [
    "https://stockx.com/air-jordan-4-retro-black-cat-2025",
    "adidas-yeezy-boost-350-v2-onyx"
  ],
  "searchQueries": [
    "air jordan 4",
    "yeezy 350"
  ],
  "maxResultsPerSearch": 10,
  "includeSampleListings": true
}
```

# Actor output Schema

## `products` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "productUrls": [
        "air-jordan-4-retro-black-cat-2025"
    ],
    "searchQueries": [
        "air jordan 4"
    ],
    "maxResultsPerSearch": 10,
    "includeSampleListings": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("inexhaustible_glass/stockx-sneaker-market-data").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "productUrls": ["air-jordan-4-retro-black-cat-2025"],
    "searchQueries": ["air jordan 4"],
    "maxResultsPerSearch": 10,
    "includeSampleListings": True,
}

# Run the Actor and wait for it to finish
run = client.actor("inexhaustible_glass/stockx-sneaker-market-data").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "productUrls": [
    "air-jordan-4-retro-black-cat-2025"
  ],
  "searchQueries": [
    "air jordan 4"
  ],
  "maxResultsPerSearch": 10,
  "includeSampleListings": true
}' |
apify call inexhaustible_glass/stockx-sneaker-market-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,inexhaustible_glass/stockx-sneaker-market-data"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/oQLhBbqP52xQQUOh0/builds/54p6IoKGXuQ2TDmxF/openapi.json
