# Wholesale Trends Product Finder (`stellaboost/wholesale-trends-product-finder`) Actor

Find winning wholesale products on Faire.com automatically. Scores products 0-100 using review velocity, restock signals, and satisfaction ratio. Scan entire categories or specific product URLs. B2B product research made data-driven.

- **URL**: https://apify.com/stellaboost/wholesale-trends-product-finder.md
- **Developed by:** [Stellaboost](https://apify.com/stellaboost) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Stats:** 5 total users, 2 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 product scanneds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

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

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Wholesale Trends Product Finder — Faire.com Winner Scanner

Find wholesale products that are **already selling** on Faire.com — before you commit to a minimum order.
Scans any category or product list, scores every product on a **Winner Score /100** built from real buyer signals, and returns only the ones worth stocking.

<h2>What it does</h2>

Give it a Faire category URL (or a list of specific product URLs) — it returns a clean dataset of scored products:

- ✅ Winner Score /100 — one number combining 4 independent demand signals
- ✅ Review velocity — is this product getting attention *right now*?
- ✅ Restock detection — buyers reordering is the strongest signal of real demand
- ✅ Barrier-to-entry scoring — favors products with an accessible minimum order
- ✅ Satisfaction-weighted — filters out high-volume but poorly-rated products
- ✅ Bilingual review parsing — correctly handles English and French dates/ratings
- ✅ Direct product URL mode — skip category scanning, test specific products instantly
- ✅ Similar-product discovery — auto-queues related products found during scanning

https://www.youtube.com/watch?v=mzDwhDqvR14

<h2>Two phases — one Actor</h2>

| Phase | When | What it does |
|---|---|---|
| **Directory** | You give a category/listing URL | Paginates through category pages, collects candidate product URLs |
| **Detail** | Always runs after Directory (or directly if `directProductUrls` is set) | Opens each product page, extracts direct reviews, computes the Winner Score |

Set `directProductUrls` to skip the Directory phase entirely and score specific products only.

<h2>Usage examples</h2>

<h3>Example 1 — Scan a category for winners</h3>

```json
{
  "startUrls": [{ "url": "https://www.faire.com/category/kids-baby" }],
  "maxProductsToScan": 300,
  "minProductReviewsThreshold": 5,
  "winnerScoreThreshold": 70,
  "velocityWindowDays": 60,
  "useApifyProxy": true,
  "maxConcurrency": 3
}
````

**What happens:** the Actor pages through the Kids & Baby category, collects up to 300 product URLs, visits each product page, scores it, and saves every product scoring 70+ to the dataset.

**Expected output:** on a category of ~270–300 products, typically 4–15 winners depending on category maturity.

***

<h3>Example 2 — Test specific products directly</h3>

```json
{
  "directProductUrls": [
    "https://www.faire.com/product/p_xxxxxxx",
    "https://www.faire.com/product/p_yyyyyyy"
  ],
  "minProductReviewsThreshold": 1,
  "winnerScoreThreshold": 50,
  "useApifyProxy": false
}
```

**What happens:** the Directory phase is skipped entirely — only the listed products are opened, scored, and saved. Useful for re-checking a shortlist or testing changes to scoring parameters without a full category run.

***

<h3>Example 3 — Wide net, low threshold (exploration mode)</h3>

```json
{
  "startUrls": [{ "url": "https://www.faire.com/category/jewelry" }],
  "maxProductsToScan": 500,
  "minProductReviewsThreshold": 3,
  "winnerScoreThreshold": 50,
  "velocityWindowDays": 365,
  "useApifyProxy": true,
  "maxConcurrency": 3
}
```

**What happens:** a longer `velocityWindowDays` and a lower `winnerScoreThreshold` surface more borderline candidates — useful when exploring a new category for the first time rather than hunting only for top performers.

***

<h3>Example 4 — Fast, targeted run with custom restock keywords</h3>

```json
{
  "startUrls": [{ "url": "https://www.faire.com/category/home-decor" }],
  "maxProductsToScan": 150,
  "winnerScoreThreshold": 75,
  "restockKeywords": ["reorder", "restock", "sold out", "flew off the shelf", "selling like crazy"],
  "maxConcurrency": 3,
  "maxRequestsPerMinute": 60
}
```

**What happens:** a smaller scan with a stricter threshold and an extended restock keyword list to catch informal demand language that the default list misses.

<h2>Configuration</h2>

<h3>Core settings</h3>

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | Array | Home Decor category | Faire category/listing URLs to scan. Ignored when Direct product URLs is set |
| `directProductUrls` | Array | 2 sample product URLs | Bypass the Directory phase — score specific product URLs directly. Clear this array to run a full category scan via `startUrls` instead |
| `maxProductsToScan` | Integer | 5 | Max product URLs collected during the Directory phase. Also caps total DETAIL-phase requests (including similar-product discovery) at 3x this value as a safety limit — raise this for a full production scan (e.g. 300–500) |
| `useApifyProxy` | Boolean | true | Use Apify Proxy (recommended to avoid rate limiting) |
| `proxyGroups` | Array | `["RESIDENTIAL"]` | Proxy group used. Residential is set by default for reliability (near-zero blocking observed in testing); switch to `[]` for the cheaper datacenter proxy on large production scans if you're not hitting blocks |
| `maxConcurrency` | Integer | 1 | Concurrent browser sessions. Raise to 3–5 for faster large scans once you've confirmed your proxy setup holds up |
| `maxRequestsPerMinute` | Integer | 60 | Request rate limit |

> The out-of-the-box defaults are intentionally small (2 sample products, `maxProductsToScan: 5`) so a first run finishes in about a minute and reliably returns results. For a real category scan, clear `directProductUrls`, set `startUrls` to your target category, and raise `maxProductsToScan` to 300–500.

<h3>Scoring settings</h3>

| Parameter | Type | Default | Description |
|---|---|---|---|
| `minProductReviewsThreshold` | Integer | 3 | Minimum direct reviews required before a product is scored |
| `winnerScoreThreshold` | Integer | 50 | Minimum Winner Score for a product to be saved to the dataset |
| `velocityWindowDays` | Integer | 365 | Review recency window used for the Velocity Score |
| `restockKeywords` | Array | see below | Customizable list of restock/reorder signal phrases |

**Default restock keywords:**
`reorder`, `restock`, `sold out`, `ordered again`, `back in stock`, `sold on the first`, `sell well`, `selling fast`

<h2>Output</h2>

```json
{
  "productUrl": "https://www.faire.com/product/p_xxxxxxx",
  "productName": "Example Product Name",
  "brandName": "Example Brand",
  "msrp": 24.00,
  "minimumOrder": 150,
  "productReviewsCount": 42,
  "winnerScore": 78,
  "velocityScore": 32,
  "restockIndex": 24,
  "barrierToEntry": 10,
  "satisfactionRatio": 12
}
```

<h3>Winner Score breakdown (/100)</h3>

| Signal | Max points | What it measures |
|---|---|---|
| **Velocity Score** | 40 | Share of reviews posted within the recent window — is demand fresh? |
| **Restock Index** | 30 | Share of reviews mentioning restock/reorder language, plus a bonus for multiple distinct keywords |
| **Barrier to Entry** | 15 | Rewards lower minimum order values (≤$100 scores highest, ≤$300 mid, above scores lowest) |
| **Satisfaction Ratio** | 15 | Weighted balance of 5★ reviews vs. 1–2★ reviews |

Only **direct product reviews** are used for scoring — reviews for similar products from the same brand are detected and excluded from the score (though their URLs are still queued for scanning).

<h2>How it works</h2>

**Directory phase** — pages through Faire category listings, extracts product IDs from result links, and collects canonical product URLs up to `maxProductsToScan`.

**Detail phase** — for each product:

1. Opens the product page and scrolls to the "Ratings and reviews" section
2. Separates **direct product reviews** from **"reviews for similar products from this brand"** — only direct reviews count toward the score
3. Paginates through review pages to collect enough signal
4. Computes the Winner Score from recency, restock language, price, and rating distribution
5. Saves the product if it clears `winnerScoreThreshold`, and queues any similar products discovered along the way

**Bilingual handling** — Faire serves review dates and star ratings in the visitor's browser locale regardless of request headers. The Actor parses both English and French date formats and star-rating labels so scoring stays accurate no matter which locale a run happens to hit.

<h2>Feature comparison</h2>

| Feature | Wholesale Trends Product Finder | Manual browsing |
|---|---|---|
| Combines review velocity + restock + price + rating into one score | ✅ | ❌ |
| Detects restock/reorder language automatically | ✅ | ⚠️ Manual reading only |
| Separates direct reviews from same-brand "similar product" reviews | ✅ | ❌ Easy to miss |
| Bilingual (EN/FR) review parsing | ✅ | ⚠️ Depends on browser locale |
| Auto-discovers and queues similar products | ✅ | ❌ |
| Test specific products without a full category scan | ✅ | N/A |
| Customizable restock keyword list | ✅ | N/A |

<h2>Pricing</h2>

Pay per event, plus platform usage — you pay for what the Actor delivers, and for the underlying Apify compute/proxy it consumes to get there.

| Event | Price | What it means |
|---|---|---|
| **Product Scanned** | $0.005 / product ($5.00 / 1,000) | Charged for every product opened and analyzed in the Detail phase — win or not |
| **Winner Found** | $0.15 / product ($150.00 / 1,000) | Charged only for products that clear the Winner Score threshold and get saved to the dataset |
| Actor start | $0.00005 | Charged once per run |
| **Platform usage** | Variable, cheaper on higher Apify plans | Apify compute + proxy costs, billed directly to your account on top of the events above |

> Unlike scrapers that charge only per raw result, this pricing has two tiers on purpose: **Product Scanned** covers the cost of the review analysis performed on every product (whether or not it becomes a winner), and **Winner Found** reflects the extra value of a product that actually clears the bar. Platform usage is billed separately so the price you see per event stays constant regardless of proxy choice — running with the default `RESIDENTIAL` proxy costs more in platform usage than the datacenter proxy, but is far more reliable against blocking.

<h3>Real run costs (reference)</h3>

| Category tested | Products scanned | Winners found | Duration | Platform cost\* |
|---|---|---|---|---|
| Home Decor | 280 | 16 | 16 min | $0.91 |
| Kids & Baby | 270 | 15 | 16 min | $0.91 |

\* These reference figures were measured on the datacenter proxy, before platform usage was split out as a separate billed line — treat them as a rough guide to relative cost between categories, not your exact bill. Your own run's platform usage cost depends on your Apify plan and the proxy group selected.

> Residential proxies (`proxyGroups: ['RESIDENTIAL']`, the default) eliminate blocking almost entirely but cost noticeably more in platform usage than the default datacenter proxy — switch to `proxyGroups: []` for large production scans once you've confirmed the datacenter proxy isn't getting blocked on your target category.

<h2>Tips</h2>

**More winners:**

- Lower `winnerScoreThreshold` to 50–60 for exploration mode in a new category
- Increase `velocityWindowDays` to 180–365 for slower-moving categories like Home Decor
- Extend `restockKeywords` with informal phrases ("flew off the shelf," "selling like crazy") to catch signals the default list misses

**Faster / cheaper runs:**

- Use `directProductUrls` to re-check a shortlist instead of rescanning a whole category
- Switch `proxyGroups` from `["RESIDENTIAL"]` to `[]` (datacenter proxy) once you've confirmed your target category isn't triggering blocks — it's noticeably cheaper in platform usage
- Raise `maxConcurrency` to 3–5 for large scans once your proxy setup is confirmed stable

**Avoid rate limiting:**

- The default `proxyGroups: ["RESIDENTIAL"]` and `maxConcurrency: 1` are tuned for reliability out of the box — near-zero blocking observed in testing, at the cost of a slower, more expensive run
- If you switch to the datacenter proxy (`proxyGroups: []`) for cost reasons, keep `maxConcurrency` at 3 and `maxRequestsPerMinute` at 60 as a starting point, and watch for 429/403 warnings in the log before pushing higher

<h2>Use cases</h2>

- 🎯 **Wholesale buyers** sourcing new products without guessing which ones will actually sell
- 📦 **Dropshippers** validating demand before committing to a minimum order
- 🔍 **Brand scouts** spotting suppliers gaining traction before they go mainstream
- 📊 **Market researchers** tracking category-level demand trends on Faire over time

<h2>Limitations</h2>

- Wholesale pricing is hidden behind a Faire buyer account and is not scraped — only publicly visible MSRP and minimum order values are used
- Very new products with few reviews may be under-scored — raise `minProductReviewsThreshold` accordingly, or lower it for exploration mode
- Review pagination is currently capped per product; extremely well-reviewed products may not have every review counted toward the score

<h2>Legal</h2>

This Actor extracts only **publicly available** information visible on Faire.com without requiring a buyer account.
Always comply with Faire's Terms of Service and applicable data protection laws.
The user is solely responsible for how extracted data is used.

# Actor input Schema

## `startUrls` (type: `array`):

Faire category/listing/search URLs to scan for products.

## `directProductUrls` (type: `array`):

Optional: skip the DIRECTORY phase and score these exact product URLs directly. Useful for debugging a specific product.

## `maxProductsToScan` (type: `integer`):

Maximum number of unique product URLs to collect during the DIRECTORY phase. Ignored when Direct product URLs is set, but still caps total DETAIL-phase requests (including similar-product discovery) at 3x this value as a safety limit.

## `minProductReviewsThreshold` (type: `integer`):

Products with fewer direct product reviews than this are skipped (insufficient signal).

## `winnerScoreThreshold` (type: `integer`):

Minimum Winner Score (out of 100) required for a product to be saved.

## `restockKeywords` (type: `array`):

Keywords searched in review text to detect reorder/restock signals.

## `velocityWindowDays` (type: `integer`):

Reviews newer than this many days count as 'recent' for the Velocity Score.

## `useApifyProxy` (type: `boolean`):

Strongly recommended to avoid IP-based blocking.

## `proxyGroups` (type: `array`):

Optional Apify proxy groups, e.g. RESIDENTIAL. Leave empty for default datacenter proxy.

## `maxConcurrency` (type: `integer`):

Maximum number of product pages processed in parallel. Use 3-5 with proxy enabled, keep at 1 without proxy.

## `maxRequestsPerMinute` (type: `integer`):

Rate limit for the DETAIL phase to reduce blocking risk.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.faire.com/category/Home%20Decor"
    }
  ],
  "directProductUrls": [
    "https://www.faire.com/product/p_ng852dgfws",
    "https://www.faire.com/product/p_cb72jqmgaj"
  ],
  "maxProductsToScan": 5,
  "minProductReviewsThreshold": 3,
  "winnerScoreThreshold": 50,
  "restockKeywords": [
    "reorder",
    "restock",
    "sold out",
    "ordered again",
    "back in stock",
    "sold on the first",
    "sell well",
    "selling fast"
  ],
  "velocityWindowDays": 365,
  "useApifyProxy": true,
  "proxyGroups": [
    "RESIDENTIAL"
  ],
  "maxConcurrency": 1,
  "maxRequestsPerMinute": 60
}
```

# Actor output Schema

## `winners` (type: `string`):

All scanned products that cleared the Winner Score threshold, with score breakdown, MSRP, minimum order, and review stats.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.faire.com/category/Home%20Decor"
        }
    ],
    "directProductUrls": [
        "https://www.faire.com/product/p_ng852dgfws",
        "https://www.faire.com/product/p_cb72jqmgaj"
    ],
    "proxyGroups": [
        "RESIDENTIAL"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("stellaboost/wholesale-trends-product-finder").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 = {
    "startUrls": [{ "url": "https://www.faire.com/category/Home%20Decor" }],
    "directProductUrls": [
        "https://www.faire.com/product/p_ng852dgfws",
        "https://www.faire.com/product/p_cb72jqmgaj",
    ],
    "proxyGroups": ["RESIDENTIAL"],
}

# Run the Actor and wait for it to finish
run = client.actor("stellaboost/wholesale-trends-product-finder").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.faire.com/category/Home%20Decor"
    }
  ],
  "directProductUrls": [
    "https://www.faire.com/product/p_ng852dgfws",
    "https://www.faire.com/product/p_cb72jqmgaj"
  ],
  "proxyGroups": [
    "RESIDENTIAL"
  ]
}' |
apify call stellaboost/wholesale-trends-product-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=stellaboost/wholesale-trends-product-finder",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Wholesale Trends Product Finder",
        "description": "Find winning wholesale products on Faire.com automatically. Scores products 0-100 using review velocity, restock signals, and satisfaction ratio. Scan entire categories or specific product URLs. B2B product research made data-driven.",
        "version": "1.0",
        "x-build-id": "7oLRS4bhx1DEDFmu1"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stellaboost~wholesale-trends-product-finder/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stellaboost-wholesale-trends-product-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/stellaboost~wholesale-trends-product-finder/runs": {
            "post": {
                "operationId": "runs-sync-stellaboost-wholesale-trends-product-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/stellaboost~wholesale-trends-product-finder/run-sync": {
            "post": {
                "operationId": "run-sync-stellaboost-wholesale-trends-product-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Faire category/listing/search URLs to scan for products.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "directProductUrls": {
                        "title": "Direct product URLs (debug)",
                        "type": "array",
                        "description": "Optional: skip the DIRECTORY phase and score these exact product URLs directly. Useful for debugging a specific product.",
                        "default": [
                            "https://www.faire.com/product/p_ng852dgfws",
                            "https://www.faire.com/product/p_cb72jqmgaj"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxProductsToScan": {
                        "title": "Max products to scan",
                        "type": "integer",
                        "description": "Maximum number of unique product URLs to collect during the DIRECTORY phase. Ignored when Direct product URLs is set, but still caps total DETAIL-phase requests (including similar-product discovery) at 3x this value as a safety limit.",
                        "default": 5
                    },
                    "minProductReviewsThreshold": {
                        "title": "Minimum product reviews",
                        "type": "integer",
                        "description": "Products with fewer direct product reviews than this are skipped (insufficient signal).",
                        "default": 3
                    },
                    "winnerScoreThreshold": {
                        "title": "Winner Score threshold",
                        "type": "integer",
                        "description": "Minimum Winner Score (out of 100) required for a product to be saved.",
                        "default": 50
                    },
                    "restockKeywords": {
                        "title": "Restock keywords",
                        "type": "array",
                        "description": "Keywords searched in review text to detect reorder/restock signals.",
                        "default": [
                            "reorder",
                            "restock",
                            "sold out",
                            "ordered again",
                            "back in stock",
                            "sold on the first",
                            "sell well",
                            "selling fast"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "velocityWindowDays": {
                        "title": "Velocity window (days)",
                        "type": "integer",
                        "description": "Reviews newer than this many days count as 'recent' for the Velocity Score.",
                        "default": 365
                    },
                    "useApifyProxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Strongly recommended to avoid IP-based blocking.",
                        "default": true
                    },
                    "proxyGroups": {
                        "title": "Proxy groups",
                        "type": "array",
                        "description": "Optional Apify proxy groups, e.g. RESIDENTIAL. Leave empty for default datacenter proxy.",
                        "default": [
                            "RESIDENTIAL"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency (DETAIL phase)",
                        "type": "integer",
                        "description": "Maximum number of product pages processed in parallel. Use 3-5 with proxy enabled, keep at 1 without proxy.",
                        "default": 1
                    },
                    "maxRequestsPerMinute": {
                        "title": "Max requests per minute (DETAIL phase)",
                        "type": "integer",
                        "description": "Rate limit for the DETAIL phase to reduce blocking risk.",
                        "default": 60
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
