# JD.com Scraper (`automation-lab/jd-scraper`) Actor

Scrape JD.com (JD Global) product listings by keyword, category, or product URL. Extract title, images, product metadata, and price/review/seller fields when JD exposes them. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/automation-lab/jd-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

## JD.com Scraper

Extract JD.com product listings and product-page metadata from [JD.com](https://www.jd.com/) (京东) — China's second-largest e-commerce platform with 600M+ registered users. Price, rating, review, and seller fields are returned when JD exposes them in the loaded page or authenticated search results; otherwise those fields are `null` instead of guessed.

Search by keyword, browse categories, or extract product details. Export to JSON, CSV, or Excel with one click.

> **Note:** JD.com requires authenticated access (cookies) for search. [See authentication setup](#authentication-jdcom-cookies-required) below.

### What does JD.com Scraper do?

JD.com Scraper navigates `search.jd.com` using your browser session cookies to extract structured product data. It supports keyword search across all JD.com product categories and exports results in multiple formats for analysis, monitoring, or AI pipelines.

**Key capabilities:**
- 🔍 Search by keyword across all JD.com categories
- 📂 Browse specific category pages
- 💰 Extract prices, discounts, and original prices when visible
- ⭐ Capture ratings and review counts when JD exposes them
- 🏪 Get seller names and self-operated (京东自营) flags when available
- 🖼️ Collect product images and thumbnails
- 📊 Export to JSON, CSV, or Excel

### Who is it for?

**E-commerce analysts & market researchers**
- Track competitor pricing across millions of JD listings
- Monitor price changes over time with scheduled runs
- Identify top-selling products in specific categories

**Dropshippers & sourcing agents**
- Find products with high review counts and ratings
- Compare self-operated (JD Logistics) vs. third-party sellers
- Automate product catalog discovery

**Data scientists & AI teams**
- Build training datasets from Chinese e-commerce
- Create price intelligence models
- Analyze consumer electronics pricing trends in China

**Business intelligence teams**
- Monitor brand presence on JD.com
- Extract pricing for market analysis reports
- Track seasonal promotions and discounts

### Why use JD.com Scraper?

- ✅ **Structured data** — clean JSON with all key fields normalized
- ✅ **No coding required** — works via Apify console, no code needed
- ✅ **Scheduled monitoring** — run on a cron to track prices over time
- ✅ **API access** — integrate via REST API or 5,000+ app connections
- ✅ **Multiple export formats** — JSON, CSV, Excel, XML
- ✅ **High reliability** — retries on failures, session management

### Authentication: JD.com Cookies (Required)

JD.com requires login for search access from outside China. You need to provide your JD.com session cookies.

**How to get your cookies:**

1. Open [https://www.jd.com](https://www.jd.com) in Chrome or Firefox
2. Log in to your JD.com account
3. Open DevTools: press `F12` or right-click → Inspect
4. Go to **Application** tab → **Cookies** → `https://www.jd.com`
5. Find cookies starting with `pt_key` and `pt_pin` (these are the auth cookies)
6. Also copy: `__jdv`, `__jda`, `__jdb`, `__jdc`, `_tp`, `_pst`
7. Format as: `pt_key=AAJt...; pt_pin=yourname...; __jdv=...; ...`
8. Paste this string into the **JD.com Cookies** field in the input

**Important:** Cookies expire. If the scraper stops working, get fresh cookies from your browser.

### What data can you extract?

| Field | Description |
|-------|-------------|
| `productId` | JD SKU ID (unique product identifier) |
| `productName` | Full product title |
| `productUrl` | Direct link to JD.com product page |
| `price` | Current selling price (CNY ¥), when visible; otherwise `null` |
| `originalPrice` | Original price before discount, when visible; otherwise `null` |
| `discountPercent` | Discount percentage (0-100) |
| `currency` | Always `CNY` (Chinese Yuan) |
| `thumbnailUrl` | Product thumbnail image URL |
| `images` | Array of product image URLs |
| `rating` | Average rating (1-5 stars), when available; otherwise `null` |
| `reviewCount` | Number of customer reviews, when available; otherwise `null` |
| `shopId` | JD shop/seller ID, when available; otherwise `null` |
| `shopName` | Seller/shop name, when available; otherwise `null` |
| `brand` | Brand name |
| `categoryName` | Product category |
| `isSelfOperated` | Whether JD self-operates (京东自营) |
| `searchKeyword` | Search keyword that found this product |
| `sourceUrl` | URL that was scraped |
| `scrapedAt` | ISO timestamp |

### How much does it cost to scrape JD.com?

JD.com Scraper uses **Pay-Per-Event (PPE)** pricing — you pay only for results scraped.

| Charge | FREE Tier | DIAMOND Tier |
|--------|-----------|--------------|
| Run start (one-time) | $0.05 | $0.05 |
| Per product scraped | $0.03 | $0.0076 |

**Full tier pricing per product:**

| Tier | Price Per Product |
|------|------------------|
| FREE | $0.03 |
| BRONZE | $0.027 |
| SILVER | $0.021 |
| GOLD | $0.016 |
| PLATINUM | $0.011 |
| DIAMOND | $0.0076 |

**Cost examples (FREE tier):**
- 10 products: ~$0.35 ($0.05 start + 10 × $0.03)
- 100 products: ~$3.05 ($0.05 start + 100 × $0.03)
- 1,000 products: ~$30.05 (FREE tier) / ~$7.65 (DIAMOND tier)
- 10,000 products: ~$300.05 (FREE tier) / ~$76.05 (DIAMOND tier)

**Free plan:** Apify gives new users $5 in free credits — enough for ~165 JD products at FREE tier.

### How to scrape JD.com products

1. **Sign up** at [apify.com](https://apify.com) (free plan available)
2. **Open** [JD.com Scraper](https://apify.com/automation-lab/jd-scraper)
3. **Add cookies:** Log into JD.com → DevTools → Application → Cookies → copy `pt_key` and `pt_pin`
4. **Enter keywords:** Add search terms (e.g., "laptop", "手机" for phone)
5. **Set limit:** Choose max results per keyword (default: 50)
6. **Click Start** and wait for results
7. **Download** as JSON, CSV, or Excel from the Results tab

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `productUrls` | Array | `[]` | Direct JD.com product page URLs — no cookies required (e.g., `["https://item.jd.com/100012043978.html"]`) |
| `keywords` | Array | `[]` | Search keywords (e.g., `["laptop", "phone"]`) — requires cookies |
| `categoryUrls` | Array | `[]` | JD.com category page URLs — requires cookies |
| `maxResultsPerSearch` | Integer | `50` | Max products per keyword or category (1–500) |
| `cookies` | String | `""` | JD.com session cookies string — required for keyword/category search |
| `proxyConfiguration` | Object | Apify RESIDENTIAL | Proxy settings |

### Output examples

```json
{
  "productId": "100067793977",
  "productName": "联想ThinkPad E14 Gen 5 AMD 轻薄笔记本电脑 14英寸 R5-7530U 16G内存 512G固态",
  "productUrl": "https://item.jd.com/100067793977.html",
  "price": 3999.00,
  "originalPrice": 5299.00,
  "discountPercent": 25,
  "currency": "CNY",
  "thumbnailUrl": "https://img10.360buyimg.com/n7/jfs/t1/123456/1/abcd.jpg",
  "images": ["https://img10.360buyimg.com/n7/jfs/t1/123456/1/abcd.jpg"],
  "rating": null,
  "reviewCount": 125000,
  "shopId": "1000003652",
  "shopName": "联想官方旗舰店",
  "brand": "ThinkPad",
  "categoryName": "笔记本",
  "isSelfOperated": false,
  "searchKeyword": "laptop",
  "sourceUrl": "https://search.jd.com/Search?keyword=laptop&enc=utf-8&page=1",
  "scrapedAt": "2026-04-01T12:00:00.000Z"
}
````

### Tips for best results

**Getting fresh cookies:**

- JD.com cookies typically expire within 7-30 days
- Get fresh cookies before each major scraping session
- Both `pt_key` and `pt_pin` cookies are required for authentication

**Keyword tips:**

- Use Chinese keywords for better results (e.g., "笔记本电脑" for laptop)
- JD.com search supports both English and Chinese keywords
- Common category searches: "手机" (phone), "电视" (TV), "冰箱" (refrigerator)

**Maximizing results:**

- Start with 50-100 results to test your keywords
- Use multiple keywords for broader coverage
- Schedule runs daily/weekly for price monitoring

**Understanding JD.com pricing:**

- Prices are in CNY (Chinese Yuan, ¥)
- JD self-operated items (自营) have better quality guarantees
- `originalPrice` shows pre-sale price when discounts apply

### Integrations

**JD.com Scraper → Google Sheets**
Use Apify's Google Sheets integration to automatically write product prices to a spreadsheet. Perfect for daily price monitoring of competitor products.

**JD.com Scraper → Slack/Discord alerts**
Set up webhooks to alert your team when products hit target price thresholds. Use Apify webhooks + Zapier to create price drop notifications.

**JD.com Scraper → Make/Zapier workflows**
Automate product catalog updates: scrape JD daily → filter by criteria → push to your CRM or database automatically.

**Scheduled price monitoring**
Use Apify's scheduling to run daily scrapes and compare prices over time. Export to CSV and analyze trends in Excel or Google Data Studio.

**JD.com data → AI models**
Feed product descriptions and pricing into LLMs for competitive analysis, price prediction, or market research reports.

### API usage

#### Node.js

```javascript
const { ApifyClient } = require('apify-client');

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('automation-lab/jd-scraper').call({
  keywords: ['laptop'],
  maxResultsPerSearch: 50,
  cookies: 'pt_key=AAJt...; pt_pin=yourpin...'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_API_TOKEN')

run = client.actor('automation-lab/jd-scraper').call(run_input={
    'keywords': ['laptop'],
    'maxResultsPerSearch': 50,
    'cookies': 'pt_key=AAJt...; pt_pin=yourpin...'
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

#### cURL

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/automation-lab~jd-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "keywords": ["laptop"],
    "maxResultsPerSearch": 50,
    "cookies": "pt_key=AAJt...; pt_pin=yourpin..."
  }'
```

### Use with AI agents via MCP

JD.com Scraper is available as a tool for AI assistants that support the [Model Context Protocol (MCP)](https://docs.apify.com/platform/integrations/mcp).

#### Setup for Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/jd-scraper"
```

#### Setup for Claude Desktop, Cursor, or VS Code

Add to your MCP config file:

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com?tools=automation-lab/jd-scraper",
            "headers": {
                "Authorization": "Bearer YOUR_APIFY_TOKEN"
            }
        }
    }
}
```

**Example prompts:**

- "Search JD.com for laptops under ¥5000 and find the top-rated options with the most reviews"
- "Get all JD.com prices for iPhone 15 Pro and compare with the official Apple store price"
- "Scrape JD.com for gaming chairs and export the results to a spreadsheet"

### Legality

JD.com Scraper accesses **publicly visible product data** using your own authenticated session — the same data any logged-in user would see while browsing. This is consistent with fair use principles for market research and price comparison.

**Best practices:**

- Use your own JD.com account credentials
- Don't exceed reasonable request rates
- Use scraped data for research and analysis only, not for unauthorized reproduction
- Comply with JD.com's Terms of Service for your specific use case

JD.com Scraper is designed for legitimate business intelligence and market research. It does not bypass paid features or access private data.

### FAQ

**Why do I need to provide cookies?**
JD.com uses geographic restrictions and bot detection that requires authentication for search access from outside mainland China. Your session cookies authenticate the requests as coming from a real logged-in user.

**How do I find my JD.com cookies?**
Log into [jd.com](https://www.jd.com), open browser DevTools (F12), go to Application → Cookies → jd.com. Look for `pt_key` and `pt_pin` cookies. Copy all cookies in the format: `name1=value1; name2=value2`.

**How much does scraping 1,000 JD products cost?**
With Apify's FREE tier: ~$40.05 ($0.05 start fee + 1,000 × $0.04). The $5 free credit on new accounts gives you about 123 products for free.

**Why are results empty or the scraper fails?**
Most common causes: (1) Cookies expired — get fresh cookies from your browser. (2) JD account was logged out — log back in and copy new cookies. (3) Network issues — retry the run.

**Can I scrape JD.com without an account?**
Yes — for individual product pages. Use the **Product URLs** input field with direct `item.jd.com` links, and no cookies are required. For keyword search or category browsing, cookies are required since JD.com blocks search access from non-China IPs without authentication.

**Why did results stop mid-run?**
JD.com may have detected the session as inactive. Try running with fresh cookies and lower `maxResultsPerSearch` values.

**Does this work for search.jd.com AND global.jd.com?**
The scraper targets `search.jd.com` (main Chinese site) using authenticated sessions. JD Global redirects all searches to the same backend.

### Related actors

- [Amazon Scraper](https://apify.com/automation-lab/amazon-scraper) — Product listings, reviews, bestsellers
- [eBay Scraper](https://apify.com/automation-lab/ebay-scraper) — Listings, bids, seller info
- [Temu Scraper](https://apify.com/automation-lab/temu-scraper) — Temu product data
- [Best Buy Scraper](https://apify.com/automation-lab/bestbuy-scraper) — Electronics pricing
- [AliExpress Scraper](https://apify.com/automation-lab/aliexpress-scraper) — Global marketplace
- [DexScreener Scraper](https://apify.com/automation-lab/dexscreener-scraper) — Crypto/token pricing

# Actor input Schema

## `keywords` (type: `array`):

Enter one or more search keywords. The scraper searches JD.com for each keyword and extracts product listings. Requires JD.com cookies (see Authentication section below).

## `categoryUrls` (type: `array`):

Enter JD.com category page URLs to scrape. Requires JD.com cookies (see Authentication section below).

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

Enter direct JD.com product page URLs (e.g. https://item.jd.com/100012043978.html). This mode does not require cookies — product pages are publicly accessible. Use this if you already have a list of product URLs.

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

Maximum number of products to extract per keyword or category. Use 0 for unlimited (within pagination limits).

## `cookies` (type: `string`):

Your JD.com session cookies string. Required for keyword search and category scraping. Not needed when using Product URLs mode. Log in to JD.com, open browser DevTools → Application → Cookies → jd.com, and copy all cookie values as a semicolon-separated string (e.g. 'pt\_key=AAJt...; pt\_pin=yourpin...').

## `proxyConfiguration` (type: `object`):

Proxy settings. Chinese residential proxy recommended for better reliability.

## Actor input object example

```json
{
  "keywords": [],
  "categoryUrls": [],
  "productUrls": [
    "https://item.jd.com/100012043978.html",
    "https://item.jd.com/100027004748.html",
    "https://item.jd.com/10086592963406.html"
  ],
  "maxResultsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "keywords": [],
    "categoryUrls": [],
    "productUrls": [
        "https://item.jd.com/100012043978.html",
        "https://item.jd.com/100027004748.html",
        "https://item.jd.com/10086592963406.html"
    ],
    "maxResultsPerSearch": 20,
    "cookies": "",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/jd-scraper").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 = {
    "keywords": [],
    "categoryUrls": [],
    "productUrls": [
        "https://item.jd.com/100012043978.html",
        "https://item.jd.com/100027004748.html",
        "https://item.jd.com/10086592963406.html",
    ],
    "maxResultsPerSearch": 20,
    "cookies": "",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/jd-scraper").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 '{
  "keywords": [],
  "categoryUrls": [],
  "productUrls": [
    "https://item.jd.com/100012043978.html",
    "https://item.jd.com/100027004748.html",
    "https://item.jd.com/10086592963406.html"
  ],
  "maxResultsPerSearch": 20,
  "cookies": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call automation-lab/jd-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/jd-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "JD.com Scraper",
        "description": "Scrape JD.com (JD Global) product listings by keyword, category, or product URL. Extract title, images, product metadata, and price/review/seller fields when JD exposes them. Export to JSON, CSV, or Excel.",
        "version": "0.1",
        "x-build-id": "1CX0yCzgerFwnTtn1"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~jd-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-jd-scraper",
                "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/automation-lab~jd-scraper/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-jd-scraper",
                "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/automation-lab~jd-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-jd-scraper",
                "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",
                "properties": {
                    "keywords": {
                        "title": "🔍 Search Keywords",
                        "type": "array",
                        "description": "Enter one or more search keywords. The scraper searches JD.com for each keyword and extracts product listings. Requires JD.com cookies (see Authentication section below).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "categoryUrls": {
                        "title": "📂 Category URLs",
                        "type": "array",
                        "description": "Enter JD.com category page URLs to scrape. Requires JD.com cookies (see Authentication section below).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "productUrls": {
                        "title": "🔗 Product URLs (No Login Required)",
                        "type": "array",
                        "description": "Enter direct JD.com product page URLs (e.g. https://item.jd.com/100012043978.html). This mode does not require cookies — product pages are publicly accessible. Use this if you already have a list of product URLs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxResultsPerSearch": {
                        "title": "📊 Max Products Per Search",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of products to extract per keyword or category. Use 0 for unlimited (within pagination limits).",
                        "default": 50
                    },
                    "cookies": {
                        "title": "🍪 JD.com Cookies (Required for keyword/category search)",
                        "type": "string",
                        "description": "Your JD.com session cookies string. Required for keyword search and category scraping. Not needed when using Product URLs mode. Log in to JD.com, open browser DevTools → Application → Cookies → jd.com, and copy all cookie values as a semicolon-separated string (e.g. 'pt_key=AAJt...; pt_pin=yourpin...')."
                    },
                    "proxyConfiguration": {
                        "title": "🌐 Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Chinese residential proxy recommended for better reliability."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
