# AliExpress Product Scraper & Price Monitor (`luminar/aliexpress-product-scraper-price-monitor`) Actor

Search AliExpress by keyword, pull exact products by URL or ID, or track factual price and stock changes. Localized prices as numbers, parsed sold counts, and an explicit coverage state on every run.

- **URL**: https://apify.com/luminar/aliexpress-product-scraper-price-monitor.md
- **Developed by:** [Luka](https://apify.com/luminar) (community)
- **Categories:** E-commerce, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 aliexpress product results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

Search AliExpress by keyword and get clean product rows with localized prices, discounts, ratings and sold counts — or turn the same run into a factual price-change monitor.

Prices arrive as numbers in the currency you asked for, sold counts are parsed into integers you can sort by, and a keyword that genuinely matches nothing says so instead of returning unrelated cards.

### 🚀 Quick start

Type one keyword, press Start. That is the whole first run.

```json
{
  "workflow": "search_products",
  "searchQueries": ["wireless earbuds"],
  "shipTo": "US",
  "currency": "USD",
  "maxProductsPerQuery": 60
}
```

Pick your **Ship-to country** first if you are not selling into the US: prices, currency and availability all follow it. Then open the **Products** view for sortable prices and sold counts.

![AliExpress product rows with localized prices, parsed sold counts and explicit coverage](https://api.apify.com/v2/key-value-stores/DJgPR6wwS2tIaLDQW/records/aliexpress_product_price_monitor--aeea1063b7628255-product-dataset.png)

Every run also writes a truthful **coverage row**: `COMPLETE`, `CAPPED`, `PARTIAL`, `BLOCKED`, `FAILED`, or `EMPTY_CONFIRMED`. A blocked or partial run never pretends to be empty.

### 🎯 Workflows

| Workflow | Returns |
|---|---|
| **Search products** | Current products per keyword: numeric prices, original price, discount %, currency, rating, sold count, image, sponsored flag, selling points. |
| **Get exact products** | One row per product URL or numeric ID. |
| **Track product changes** | First run stores a quiet baseline. Later runs emit factual `NEW`, `UPDATED`, and confirmed `ENDED` rows; unchanged products cost nothing. |

### 📦 Output

One flat row per product (JSON/CSV/Excel), for example:

```json
{
  "recordType": "product",
  "productId": "3256811621288203",
  "title": "2025 Air Pro Wireless Bluetooth Earphones TWS Headset HiFi Earbuds",
  "productUrl": "https://www.aliexpress.com/item/3256811621288203.html",
  "salePrice": 0.99,
  "originalPrice": 20.15,
  "discountPercent": 95,
  "currencyCode": "USD",
  "rating": 4.9,
  "soldText": "4,000+ sold",
  "soldCount": 4000,
  "productType": "natural",
  "isSponsored": false,
  "sellingPoints": ["Free shipping"],
  "shipTo": "US",
  "searchQuery": "wireless earbuds",
  "scrapedAt": "2026-09-01T21:50:36.881Z"
}
```

`soldCount` is always a sortable number parsed from the source's display text; `salePrice` is always numeric with its `currencyCode`. Prices and availability vary by ship-to country, promotion, and time — pin one market for comparable rows.

### 🎛️ Input guide

- **Search keywords** (up to 10) — one search target each.
- **Search URLs** — paste a URL you already filtered on AliExpress; it is used exactly as-is.
- **Exact product URLs / IDs** — for the exact-products workflow.
- **Ship-to country / currency / language** — localization for the whole run.
- **Result order** — best match, most orders, price low-to-high / high-to-low, newest.
- **Minimum / maximum price** and **free shipping only** — deterministic filters.
- **Maximum products per keyword** (1–1000) — hard ceiling; coverage becomes `CAPPED` when the source has more.
- **Monitoring tracks at most 5,000 products per namespace.** A monitoring run has to remember every product it watches, so a wider scope is capped to that and reported as `CAPPED` rather than silently dropped.
- **Maximum spend for this run (USD)** — the run stops before exceeding it.

### 💰 Pricing

Pay-per-event, only for verified results:

| Event | Price | When charged |
|---|---|---|
| Verified search target | $0.0055 | Once per keyword that returns a trustworthy result. |
| Product result | $0.0008 | Per unique product or verified change row. |
| Verified detail target | $0.0058 | Once per exact product that yields a useful row. |
| Verified monitoring target | $0.005 | Once per trustworthy monitoring scan. |

A default run (1 keyword × 60 products) costs about **$0.054**. Blocked and failed runs are free. Coverage rows, summaries, and unchanged monitoring snapshots are free. A keyword that genuinely matches nothing returns EMPTY\_CONFIRMED with no product rows, and only the search target is charged.

### ✅ Coverage

- `COMPLETE` — every requested target finished within your limits.
- `CAPPED` — a declared row/page/spend guard stopped the run first.
- `PARTIAL` — at least one target failed; rows are a truthful partial prefix.
- `BLOCKED` — the source blocked the run; never reported as empty.
- `FAILED` — a source or parser failure; never reported as empty.
- `EMPTY_CONFIRMED` — the result page loaded and confirmed zero matches.
- `ENDED` in monitoring means the product was absent in two consecutive comparable scans — disappearance alone is never reported as deletion.

### 🔌 API / automation

Schedule a daily run with the same **Monitoring namespace** and compare `scrapedAt` across runs, or read changes directly:

```js
const { ApifyClient } = require('apify-client');
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('luminar/aliexpress-product-scraper-price-monitor').call({
  workflow: 'track_product_changes',
  searchQueries: ['wireless earbuds'],
  monitorStoreName: 'earbuds-watch',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Set `APIFY_TOKEN` in your environment before running the example.

### ⚠️ Not yet supported

- Variant/SKU-level detail (per-variant price and stock) is not included in search rows.
- Full product-detail fields (shipping matrix, seller metrics, review text) are not part of the exact-products row.
- Reviews scraping is a separate job, not part of this Actor.

### ❓ FAQ / support

**Is the price really per product row?** Yes — $0.0009 per delivered product row, nothing for blocked or empty targets, and no platform-usage pass-through.

**Can I monitor price changes?** Yes. Use **Track product changes** with a stable **Monitoring namespace** on a schedule. The first run is a baseline; later runs emit `NEW`, `UPDATED`, and confirmed `ENDED` rows only.

**Why do prices differ from what I see locally?** AliExpress localizes by ship-to country. Pin the same **Ship-to country**, **currency**, and **language** on every run for comparable rows.

# Actor input Schema

## `workflow` (type: `string`):

Search returns current products. Exact mode resolves specific URLs or IDs. Monitoring keeps a baseline, then emits factual NEW, UPDATED, or confirmed ENDED rows after two comparable absences.

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

Up to 10 phrases. Each keyword is a separate search target with keyword-fidelity checks.

## `searchUrls` (type: `array`):

Optional. Paste AliExpress search result URLs you already filtered on the site; they are scraped exactly as-is.

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

Exact mode: public AliExpress item URLs. Resolved anonymously; non-AliExpress hosts are rejected.

## `productIds` (type: `array`):

Optional. Numeric AliExpress product IDs without the URL.

## `shipTo` (type: `string`):

Localizes results: shippable items, prices, and currency follow the selected market.

## `currency` (type: `string`):

Currency requested from the public storefront. Reported only when the source confirms it.

## `language` (type: `string`):

Storefront language for titles and labels.

## `sortBy` (type: `string`):

Source-native ordering. Most orders surfaces best sellers; Newest surfaces recent listings.

## `minPrice` (type: `number`):

Keep rows at or above this price.

## `maxPrice` (type: `number`):

Keep rows at or below this price.

## `freeShipping` (type: `boolean`):

Keep only products marked with free shipping in the source listing.

## `maxProductsPerQuery` (type: `integer`):

Hard ceiling per keyword. Coverage becomes CAPPED when more source rows remain. On monitoring runs the whole scope is additionally capped at 5,000 products, because monitoring has to remember every product it tracks.

## `maxBuyerChargeUsd` (type: `number`):

The run stops before exceeding this total charge.

## `monitorStoreName` (type: `string`):

Use the same name on every scheduled run of one watch. The first run creates the baseline; later runs return factual NEW, UPDATED, and confirmed ENDED rows.

## Actor input object example

```json
{
  "workflow": "search_products",
  "searchQueries": [
    "wireless earbuds"
  ],
  "shipTo": "US",
  "currency": "USD",
  "language": "en",
  "sortBy": "default",
  "freeShipping": false,
  "maxProductsPerQuery": 60,
  "maxBuyerChargeUsd": 30
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open every product, change, and coverage row.

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

Open product rows with price and demand columns selected.

## `changes` (type: `string`):

Open NEW, UPDATED, and ENDED rows with changed fields visible.

## `coverage` (type: `string`):

Open the truthful per-target coverage rows.

## `runSummary` (type: `string`):

Open the sanitized coverage, state, and billing summary.

# 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 = {
    "workflow": "search_products",
    "searchQueries": [
        "wireless earbuds"
    ],
    "shipTo": "US",
    "currency": "USD",
    "language": "en",
    "sortBy": "default",
    "freeShipping": false,
    "maxProductsPerQuery": 60,
    "maxBuyerChargeUsd": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("luminar/aliexpress-product-scraper-price-monitor").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 = {
    "workflow": "search_products",
    "searchQueries": ["wireless earbuds"],
    "shipTo": "US",
    "currency": "USD",
    "language": "en",
    "sortBy": "default",
    "freeShipping": False,
    "maxProductsPerQuery": 60,
    "maxBuyerChargeUsd": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("luminar/aliexpress-product-scraper-price-monitor").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 '{
  "workflow": "search_products",
  "searchQueries": [
    "wireless earbuds"
  ],
  "shipTo": "US",
  "currency": "USD",
  "language": "en",
  "sortBy": "default",
  "freeShipping": false,
  "maxProductsPerQuery": 60,
  "maxBuyerChargeUsd": 30
}' |
apify call luminar/aliexpress-product-scraper-price-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luminar/aliexpress-product-scraper-price-monitor"
        }
    }
}

```

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/epd3KXg805qM2DTua/builds/hDscXbXw27gFHFTN7/openapi.json
