Metadata-Version: 2.4
Name: apify-stockx-client
Version: 0.1.1
Summary: Python client for the rl1987/stockx-api-scraper Apify Actor — StockX resale market data (lowest ask, highest bid, last sale).
Author-email: rl1987 <rimantas@keyspace.lt>
License: MIT
Project-URL: Homepage, https://apify.com/rl1987/stockx-api-scraper
Project-URL: Source, https://apify.com/rl1987/stockx-api-scraper
Keywords: apify,web-scraping,api-client
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Dynamic: license-file

# apify-stockx-client

**StockX resale market data — lowest ask, highest bid, last sale — by keyword search or category browse.**

Python client for the [`rl1987/stockx-api-scraper`](https://apify.com/rl1987/stockx-api-scraper) [Apify](https://apify.com) Actor. No local scraping, no proxy management, no anti-bot maintenance — the Actor runs on Apify's infrastructure and this package just starts it, waits, and hands you back the dataset as plain Python dicts.

[Install](#install) · [Quickstart](#quickstart) · [Getting an API token](#getting-an-api-token) · [Input reference](#input-reference) · [Output fields](#output-fields) · [Error handling](#error-handling) · [Pricing](#pricing) · [Async / long-running runs](#advanced-longer-timeouts--polling) · [Links](#links)

## Install

```bash
pip install apify-stockx-client
```

Requires Python 3.9+. Only dependency is [`requests`](https://pypi.org/project/requests/).

## Quickstart

```python
from apify_stockx_client import StockXClient

client = StockXClient(api_token="apify_api_...")  # see "Getting an API token" below
items = client.run({"q": "Jordan 1 Retro High", "includeDetails": True, "maxItems": 20})

for item in items:
    print(item)
```

Real output from the example above (trimmed to a few fields):

```python
{"title": "Jordan 1 Retro High OG Chicago Lost and Found", "brandName": "Jordan", "lowestAsk": 154, "highestBid": 286, "productUrl": "https://stockx.com/air-jordan-1-retro-high-og-chicago-reimagined-lost-and-found"}
```

`run()` blocks until the Actor finishes (usually a few seconds to ~30s depending on `maxItems`) and returns a plain `list[dict]` — the Actor's dataset, one dict per result row.

## Getting an API token

1. Sign up for a free account at [console.apify.com](https://console.apify.com).
2. Go to **Settings → Integrations** and copy your **Personal API token**.
3. Pass it to the client: `StockXClient(api_token="...")`, or read it from an environment variable:

   ```python
   import os
   client = StockXClient(api_token=os.environ["APIFY_TOKEN"])
   ```

Never hardcode the token in source control — use an environment variable or secrets manager.

## Input reference

`run()` takes a single `dict` matching the Actor's input schema. Full/authoritative schema: the **Input** tab on [the Actor's Apify page](https://apify.com/rl1987/stockx-api-scraper).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `q` | str | `""` | Search keyword, e.g. `"Jordan 1 Retro High"`. |
| `category` | str | — | One of `sneakers`, `streetwear`, `watches`, `handbags`, `electronics`, `collectibles`, `trading-cards`. Provide `q`, `category`, or both. |
| `includeDetails` | bool | `False` | Fetch PDP fields: description, release date, per-size `variantSizes`. |
| `maxItems` | int | `100` | Maximum products to scrape. `0` = no limit. |

## Output fields

Each dict in the returned list is one row from the Actor's dataset. Common fields:

`title`, `brandName`, `model`, `colorway`, `styleId`, `retailPrice`, `currency`, `lowestAsk`, `highestBid`, `lastSale`, `productUrl`, `thumbUrl`, `images`; plus `description`, `releaseDate`, `variantSizes` when `includeDetails=True`.

Exact field availability can vary by input flags (see table above) — treat unfamiliar/missing keys as optional and use `.get()` rather than `[...]` indexing.

## Error handling

```python
from apify_stockx_client import StockXClient, ApifyActorError
import requests

client = StockXClient(api_token="...")

try:
    items = client.run({"q": "Jordan 1 Retro High", "includeDetails": True, "maxItems": 20})
except ApifyActorError as e:
    # The Actor run itself failed, timed out, or was aborted on the Apify side.
    print(f"Actor run did not succeed: {e}")
except requests.HTTPError as e:
    # Bad token, malformed input, rate limiting, etc. — an HTTP-level error
    # calling the Apify API (not the Actor run).
    print(f"Apify API request failed: {e}")
```

`ApifyActorError` is raised when the run reaches a terminal non-success status (`FAILED`, `TIMED-OUT`, `ABORTED`) or doesn't finish within `timeout_secs` (default 300s — raise it for `run()` calls with a large `maxItems`, e.g. `StockXClient(api_token="...", timeout_secs=900)`).

## Pricing

Pay-per-event: $0.00075/product row, plus $0.00075/product enriched with detail-page data when `includeDetails=True`. No subscription — see the [Actor's pricing tab](https://apify.com/rl1987/stockx-api-scraper) for current rates. Apify also includes a free monthly usage tier that covers light use.

## Advanced: longer timeouts & polling

```python
client = StockXClient(api_token="...", timeout_secs=900)  # allow up to 15 min
items = client.run(actor_input, poll_interval_secs=3.0)   # poll less aggressively
```

## Links

- [StockX API Scraper on Apify](https://apify.com/rl1987/stockx-api-scraper) — Actor page, input schema, pricing
- [PyPI package](https://pypi.org/project/apify-stockx-client/)
- [Apify API reference](https://docs.apify.com/api/v2) — what this client wraps under the hood

## License

MIT
