# Made-in-China Scraper & Supplier Price Monitor - MOQ, Prices (`neverempty/made-in-china-products-monitor`) Actor

Made-in-China.com product search by keyword: US$ price range, minimum order quantity (MOQ), supplier company, business type, member level, audited flag, province and product certifications. Monitor mode returns only new products and price drops. No login. Export as JSON, CSV or Excel. Unofficial.

- **URL**: https://apify.com/neverempty/made-in-china-products-monitor.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 product returneds

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?

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

## Made-in-China Scraper & Supplier Price Monitor - MOQ, Prices

Get products from **Made-in-China.com** search results by keyword: title, **US$ price range**, **minimum order quantity (MOQ)** and unit, **supplier company name**, business type (manufacturer or trading company), member level, **audited supplier** flag, **province**, supplier rating, product certifications (CE, RoHS and others shown on the card), image and link. **Monitor mode** returns only products that are new in the results and **price drops** since the last check, so a sourcing team can run it on a schedule and see only what changed.

Unofficial. Reads public search pages only, without logging in. Not affiliated with Made-in-China.com or Focus Technology.

### What makes this one different

- **Built for sourcing.** Each row has the supplier's price range split into `priceMin` and `priceMax`, the MOQ split into a number and a unit (`100` and `Meters`), and the supplier's company name, business type, member level, audited flag and province, so you can sort and filter in a spreadsheet without cleaning text.
- **No fake "new" products.** The first products on page 1 are rotating top slots: in our tests on 2026-10-09, 7 to 8 of those 10 changed between two visits a few minutes apart, while 28 to 30 of the other 30 products stayed the same. Every row has `placementType`, and monitor mode leaves the rotating slots out by default (`includeTopRankSlots`), so rotation is not reported as new products.
- **Price changes say what changed.** Monitor mode compares the lower end of the price range first, then the upper end. `priceChangeBasis` says which one moved, with the previous value next to the new one.
- **The count you ask for is the count you get**, up to 300 per search (30 per page, up to 10 pages). If there were more results than you got, a free row says so. Products that appear on two pages are returned once.
- **No personal contact data.** Only the public company details shown on the search page are returned. No names of people, phone numbers or e-mail addresses.

### Output fields

| Field | What it is |
|---|---|
| `productId`, `url` | Made-in-China.com product ID and product page |
| `title` | Product title |
| `priceMin`, `priceMax`, `currency`, `priceText` | Supplier's price range in US$ as shown on the search page (`US$ 0.99 - 3.99` gives 0.99 and 3.99; a single price gives the same number twice) |
| `priceNote` | Why a price is empty, in plain words (null when there is a price) |
| `minOrderQuantity`, `minOrderUnit`, `minOrderText` | Minimum order quantity (MOQ), its unit, and the text as shown (`100 Meters`) |
| `supplierName`, `supplierUrl` | Supplier company name and its Made-in-China.com showroom |
| `supplierBusinessType` | For example `Manufacturer/Factory & Trading Company` or `Trading Company` (null when the card does not show it) |
| `supplierMemberLevel`, `auditedSupplier` | Member level shown on the card (`Diamond Member`, `Gold Member`) and whether the card shows the Audited Supplier mark |
| `supplierProvince`, `supplierCountry`, `supplierLocation` | Province (for example `Guangdong`), country, and the location text as shown |
| `supplierRating`, `supplierRatingLabel` | Rating out of 5 and its label (`Fast Delivery`) as shown on the card, when shown |
| `productCertifications` | Certifications shown on the product card, for example `["CE", "RoHS"]` (empty when none are shown) |
| `placementType`, `adsTypeCode` | Raw placement codes from the page (`topRank` = rotating top slots of page 1) |
| `titleMatchesSearch` | Whether the title contains every search word |
| `imageUrl`, `page`, `positionOnPage` | Main image, results page and position on it |
| `changeType`, `previousPriceMin`, `previousPriceMax`, `priceChange`, `priceChangePercent`, `priceChangeBasis` | Monitor mode only (see below) |
| `charged` | `true` when the row was charged, `false` when it was returned free (a product without a price) |
| `searchQuery`, `searchUrl`, `searchUnderstoodAs`, `watchName`, `checkedAt` | Which search the row came from and when |
| `status`, `note` | `ok` for products; otherwise a free row that says why nothing (or not everything) was returned |

In our tests on 2026-10-09 (7 searches, 210 products), every product had a US$ price, an MOQ, a supplier name, a member level and a province; 127 of 210 showed a business type, 147 a supplier rating and 31 at least one product certification.

### Input

| Field | What it does |
|---|---|
| `searchQueries` | English search terms, for example `LED light`, `solar panel`, `stainless steel pipe`. Empty (with no `searchUrls`) runs the example `LED light`. |
| `searchUrls` | Search pages copied from your browser (`https://www.made-in-china.com/products-search/hot-china-products/LED_Light.html`). Only the search words are used. |
| `maxResultsPerSearch` | Most products per search, 1 to 300 (default 30). |
| `maxPages` | Results pages per search, 1 to 10 (30 products each). Default: just enough for `maxResultsPerSearch`. |
| `includeTopRankSlots` | Include the rotating top slots of page 1. Default: yes in a normal search, no in monitor mode. |
| `onlyMatchingTitles` | Leave out products whose title does not contain every search word (off by default). |
| `onlyNew` | Monitor mode (see below). |
| `priceChangeAlerts` | Monitor mode: `drops` (default), `any` or `off`. |
| `watchName` | Monitor mode: a name to keep separate memories, for example one per client. |
| `resetMonitoringState` | Monitor mode: forget this watch's memory and start again. |

```json
{
    "searchQueries": ["LED light", "solar panel"],
    "maxResultsPerSearch": 60
}
```

### Monitor mode

1. First run: returns up to `maxResultsPerSearch` products (`first-check`) and remembers the list.
2. Next runs: read the same pages and return only
   - `new-in-results`: a product this watch has not seen in these results before. It may be newly listed, or it may have moved into the pages read. The search page has no listing date, so this Actor does not invent a "new since" date.
   - `price-change`: a price drop (or any change, with `priceChangeAlerts: any`), with `previousPriceMin`, `previousPriceMax`, `priceChange`, `priceChangePercent` and `priceChangeBasis`.
3. If a page cannot be read, the watch judges nothing for that search: nothing is returned, remembered or charged, and the next run checks again.
4. If a run reaches your maximum charge, the products it could not return are returned by the next run.

### Pricing

Pay per event:

- **Run start**: one small fee per run (not per page and not per GB of memory).
- **Product returned**: per product row **with a price**. A product row without a price is still returned, with `charged: false`, and is **not charged**. The run log says how many rows were charged and how many were not.

Explanation rows are free. A search that finds nothing is not charged at all. In monitor mode, the run start fee is the price of the check itself, so it is charged even when nothing changed. Set a maximum charge per run and the Actor will not start a run that cannot return at least one product.

### Reliability

- Reads the plain search page; no browser, no login, no cookies. Measured 2026-10-09 from Apify's servers, both without a proxy and through Apify's datacenter proxy: every request answered (20 of 20), no check page.
- If Made-in-China.com refuses an IP address (403, 429, 5xx), the Actor asks again from other datacenter IPs.
- If Made-in-China.com shows a check page, the Actor **does not solve or bypass it**: it stops, returns a free row and remembers nothing.
- Made-in-China.com's robots.txt is checked on every run and every URL is checked against it before it is requested. Only search pages are read; product and company pages are not opened.
- Prices are the ranges suppliers list on Made-in-China.com. The final price of an order depends on quantity and negotiation with the supplier.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

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

Products to search for on Made-in-China.com, in English, for example LED light, solar panel, stainless steel pipe. Each term is one search. Leave Search terms and Search URLs both empty to run the example search LED light.

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

Optional. Made-in-China.com search pages copied from your browser, in the form https://www.made-in-china.com/products-search/hot-china-products/LED_Light.html. Only the search words are used; every search is read from its first page.

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

Most products returned for one search (Made-in-China.com shows 30 per page). Empty = 30. In monitor mode it limits the products returned per search in one run; the rest come in the next run.

## `maxPages` (type: `integer`):

How many results pages (30 products each) to read for each search, 1 to 10. Empty = just enough pages for Max products per search. In monitor mode every run reads this many pages and compares them.

## `includeTopRankSlots` (type: `boolean`):

The first products on page 1 (placementType topRank) change on almost every visit. Empty = included in a normal search and left out in monitor mode, so the watch does not report rotation as new products. On or off sets it for both.

## `onlyMatchingTitles` (type: `boolean`):

On: leave out products whose title does not contain every search word (Made-in-China.com also lists loosely related products). Off (default): return them all, each marked titleMatchesSearch true or false.

## `onlyNew` (type: `boolean`):

On: every run reads the same pages of each search and returns only products that appear in these results for the first time (changeType new-in-results) and products whose US$ price changed as set in Price change alerts (changeType price-change, with the previous price). The first run returns up to Max products per search (changeType first-check) and remembers them as the starting point. Each run that reads the list is charged the run start fee; runs where nothing changed return a free row saying so.

## `priceChangeAlerts` (type: `string`):

Which price changes monitor mode returns. The lower end of the supplier's US$ price range is compared first, then the upper end; see priceChangeBasis in the output. Empty = price drops only.

## `watchName` (type: `string`):

Optional. Keeps separate memories for monitor mode, for example one per client (letters, digits, dot, dash, underscore; up to 40). Runs with the same watch name and search share what has already been returned.

## `resetMonitoringState` (type: `boolean`):

On: forget what this watch has seen for these searches before running, so this run is a first check again. Off or empty: keep the memory.

## Actor input object example

```json
{
  "searchQueries": [
    "LED light"
  ],
  "onlyMatchingTitles": false,
  "priceChangeAlerts": "drops"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Made-in-China.com product in the search results: product ID, title, US$ price range, minimum order quantity and unit, supplier company name, business type, member level, audited flag, province, supplier rating, product certifications, placement, link, page and position. Monitor mode marks rows first-check, new-in-results or price-change (with the previous price). A search with no products, nothing changed, a check page, a refused request or a run that hit its maximum charge comes back as a free row that says why.

# 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 = {
    "searchQueries": [
        "LED light"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/made-in-china-products-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 = { "searchQueries": ["LED light"] }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/made-in-china-products-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 '{
  "searchQueries": [
    "LED light"
  ]
}' |
apify call neverempty/made-in-china-products-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/made-in-china-products-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/afbhFKHNaiM5e7dF2/builds/90eq3Xb3B6GSczyso/openapi.json
