# Ali Express Tracking (`sovanza.inc/ali-express-tracking`) Actor

AliExpress Tracking Checker tracks shipments using Cainiao, AliExpress logistics, and 17TRACK sources. It returns normalized status, carrier details, delivery flags, event history, locations, and structured tracking data for e-commerce automation.

- **URL**: https://apify.com/sovanza.inc/ali-express-tracking.md
- **Developed by:** [Sovanza](https://apify.com/sovanza.inc) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Stats:** 8 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.00 / 1,000 tracking results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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.

- **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

### AliExpress Tracking Checker – Multi-Source Shipment Tracking & Cainiao Scraper

Track AliExpress shipments using a multi-source engine: **Cainiao Global**, **AliExpress logistics**, and **17TRACK** public tracking pages. This actor walks a configurable priority list of providers and returns normalized, structured tracking data from the **first source that succeeds**.

### Overview

AliExpress Tracking Checker uses **Playwright (Chromium)** to open public tracking pages, intercept JSON responses, and parse DOM content when needed. It normalizes carrier, status, locations, and event history into one consistent schema.

**Output is compact:** empty or missing fields are omitted so each row contains only what the tracking sources exposed for that shipment.

### Key benefits

- Check **multiple tracking numbers** in one run via `trackingInputs`
- **Multi-source fallback** with configurable `sourcePriority`
- **Normalized status** (`in_transit`, `delivered`, `exception`, etc.)
- Optional **full event timeline** per shipment
- Export clean datasets in **JSON, CSV, or Excel** via Apify
- Proxy and cookie support for anti-bot tracking sites

### Core features

- Cainiao, AliExpress, and 17TRACK web adapters (priority-based)
- Bulk tracking input with optional `orderId`, `carrierHint`, `sourceHint`, `countryHint`
- Derived status flags: `delivered`, `inTransit`, `exception`
- Event history with `maxEventsPerTracking` cap
- Optional raw source payload for debugging
- Parallel lookups via `maxConcurrency`
- Output to dataset, key-value store, or both (`outputMode`)

### How to Use AliExpress Tracking Checker on Apify

#### Using the Actor

1. **Open the Actor** on the Apify platform and go to the **Input** tab.
2. **Add tracking numbers** in `trackingInputs` (with optional order IDs and hints).
3. **Enable residential proxy** via `proxyConfiguration` for best reliability.
4. **Start** the run. The actor tries each source in order and pushes **compact items** to the default dataset.
5. **Open the Dataset** tab to browse, download JSON/CSV/Excel, or pull data via the Apify API.
6. **Schedule or integrate** (optional): use schedules, webhooks, Zapier/Make, or your own code against the Apify API.

#### Input Configuration

Full schema: `INPUT_SCHEMA.json`. Example:

```json
{
  "trackingInputs": [
    { "trackingNumber": "LP00123456789012", "orderId": "8182736455463721" },
    { "trackingNumber": "CNABC0012345678", "carrierHint": "Cainiao", "countryHint": "PK" }
  ],
  "sourcePriority": ["cainiao_web", "aliexpress_web", "seventeen_track_web"],
  "includeEventHistory": true,
  "includeDerivedStatus": true,
  "maxConcurrency": 3,
  "outputMode": "dataset",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

- **`trackingInputs`** (required): Array of tracking request objects. Each may include `trackingNumber`, `orderId`, `carrierHint`, `sourceHint`, and `countryHint`. Plain strings are accepted as tracking numbers.
- **`sourcePriority`** (optional): Ordered list of source adapters. Default: `["cainiao_web", "aliexpress_web", "seventeen_track_web"]`.
- **`includeEventHistory`** (optional): Include the full tracking event timeline (default `true`).
- **`includeRawSourcePayload`** (optional): Include sanitized raw source HTML for debugging (default `false`).
- **`includeDerivedStatus`** (optional): Compute normalized status and delivery flags (default `true`).
- **`maxEventsPerTracking`** (optional): Max events per shipment (default `50`, max `500`).
- **`outputMode`** (optional): `dataset`, `kv_store`, or `both` (default `dataset`).
- **`outputKvStoreKey`** (optional): KV store key when using `kv_store` or `both` (default `TRACKING_OUTPUT`).
- **`requestTimeoutSecs`** (optional): Page navigation timeout (default `45`).
- **`maxConcurrency`** (optional): Parallel tracking lookups (default `5`, max `20`).
- **`retriesPerSource`** (optional): Retries per source before moving on (default `2`).
- **`challengeWaitSecs`** (optional): Max wait for Cloudflare/CAPTCHA resolution (default `12`).
- **`blockAssets`** (optional): Block non-essential assets for speed (default `true`).
- **`debugMode`** / **`saveHtmlSnapshot`** / **`saveScreenshot`** (optional): Debug artifacts for failed pages.
- **`proxyConfiguration`** (optional): Apify proxy; **residential** is recommended.
- **`cookiesText`** / **`cookiesJson`** (optional): Session cookies. **Secret inputs** — encrypted at rest, not copied to dataset rows.
- **`seventeenTrackApiKey`** (optional): Reserved for future 17TRACK API adapter. **Secret input**.

##### Authentication & sensitive input

Fields that can hold session credentials use Apify **secret input** (`isSecret: true`):

- **`cookiesText`** — Netscape/tab-separated cookie format
- **`cookiesJson`** — Playwright cookie array JSON
- **`seventeenTrackApiKey`** — future API key storage

Secret values are encrypted in storage and are **not** written into dataset rows or logs.

##### Run locally

`INPUT.json` is gitignored. Copy `INPUT.example.json` to `INPUT.json`, then:

```bash
cd aliexpress-tracking-checker
pip install -r requirements.txt
playwright install chromium
cp INPUT.example.json INPUT.json
python main.py
```

### Output

Results are stored in the Actor’s **default dataset** when `outputMode` is `dataset` or `both`. Each item is a **compact** JSON object: fields that are empty or unknown are **not** included.

Typical fields (when data is available):

- **Identity:** `trackingNumber`, `orderId`
- **Carrier & source:** `carrier`, `sourceUsed`, `sourceUrl`, `sourceStatusText`
- **Status:** `normalizedStatus`, `delivered`, `exception`, `inTransit`
- **Timing:** `lastUpdate`, `estimatedDelivery`, `firstSeenEvent`, `latestEvent`
- **Location:** `lastUpdateLocation`, `latestLocation`, `originCountry`, `destinationCountry`
- **Events:** `trackingEvents`, `eventCount`
- **Quality:** `statusConfidence`, `sourceAttempts`, `warnings`
- **Debug:** `rawSourcePayload` (when enabled)
- **Errors:** `error` on failure rows
- **Meta:** `timestamp`

Example item (illustrative — real items only include keys that have values):

```json
{
  "trackingNumber": "LB123456789SG",
  "orderId": "8182736455463721",
  "carrier": "Cainiao",
  "sourceUsed": "cainiao_web",
  "sourceUrl": "https://global.cainiao.com/detail.htm?mailNoList=LB123456789SG",
  "sourceStatusText": "Parcel is in transit",
  "normalizedStatus": "in_transit",
  "delivered": false,
  "inTransit": true,
  "lastUpdate": "2026-03-31T10:22:00Z",
  "lastUpdateLocation": "Lahore, Pakistan",
  "estimatedDelivery": "2026-04-07",
  "eventCount": 6,
  "statusConfidence": "high",
  "sourceAttempts": [
    { "source": "cainiao_web", "success": true, "reason": "tracking data found" }
  ],
  "trackingEvents": [
    {
      "timestamp": "2026-03-21T03:10:00Z",
      "status": "Shipment accepted by carrier",
      "location": "Shenzhen, China",
      "details": "Accepted at sorting center",
      "sourceEventIndex": 0
    }
  ],
  "timestamp": "2026-03-31T12:00:00Z"
}
```

When `outputMode` is `kv_store` or `both`, a JSON bundle with `records` and `summary` is also written to the key-value store under `outputKvStoreKey` (default `TRACKING_OUTPUT`).

#### Normalized statuses

| Status | Meaning |
|--------|---------|
| `pending` | Label created / information received |
| `accepted` | Shipment accepted by carrier |
| `in_transit` | Package is moving between facilities |
| `arrived_at_destination_country` | Customs clearance or arrival at destination |
| `out_for_delivery` | Out for final delivery |
| `delivered` | Successfully delivered |
| `failed_attempt` | Delivery attempt failed |
| `exception` | Held, lost, or other exception |
| `returned` | Returned to sender |
| `expired` | Tracking expired |
| `unknown` | Could not determine status |

#### Failure output

When no source returns valid data (compact — omitted null keys):

```json
{
  "trackingNumber": "LP00123456789012",
  "normalizedStatus": "unknown",
  "error": "No source returned valid tracking data",
  "sourceAttempts": [
    { "source": "cainiao_web", "success": false, "reason": "challenge page persisted" },
    { "source": "aliexpress_web", "success": false, "reason": "no tracking result" }
  ],
  "timestamp": "2026-03-31T12:00:00Z"
}
```

### Use Cases

- **Dropshipping order tracking** — monitor AliExpress orders and keep customers updated
- **Tracking dashboards** — feed normalized status into internal monitoring tools
- **E-commerce automation** — connect tracking data to CRMs and support systems
- **Delivery alerts** — detect status changes by diffing scheduled runs
- **Logistics analytics** — analyze shipping times, delays, and carrier performance

### Integrations & API

- Run and fetch results through the **Apify API**
- Use **Python**, **Node.js**, or HTTP clients against run and dataset endpoints
- Connect **Zapier**, **Make**, **Google Sheets**, and other Apify integrations
- **Webhooks** and **schedules** for recurring tracking checks

### FAQ

#### How does AliExpress Tracking Checker work?

It tries each source in `sourcePriority` using Playwright, extracts tracking events and status from the first successful source, normalizes the data, and pushes compact rows to the dataset.

#### Why use multiple tracking sources?

AliExpress shipments often surface updates on Cainiao or 17TRACK before or more completely than on AliExpress pages alone.

#### Can I track multiple orders in one run?

Yes. Add multiple entries to `trackingInputs`.

#### Why am I getting no tracking results?

Invalid numbers, shipments not yet registered, or blocked access are common causes. Use **residential proxy** and **cookies** when sources challenge automated traffic.

#### What formats can I export?

**JSON**, **CSV**, and **Excel** from the Apify dataset UI, plus full access via the **Apify API**.

### SEO Keywords

aliexpress tracking checker\
cainiao tracking scraper\
aliexpress shipment tracker\
17track scraper\
shipment tracking api\
package tracking automation\
apify tracking actor

### Actor permissions

This Actor is intended to work with **limited permissions**: it reads your input and writes to its **default dataset** (and uses Apify proxy/KV as configured). It does not require broad access to unrelated account data.

**To set limited permissions in Apify Console:**

1. Open your Actor on the Apify platform.
2. Go to **Source** or **Settings**.
3. Open **Review permissions** / **Permissions**.
4. Choose **Limited permissions** and save.

### Limitations

- Not all shipments expose the same fields across tracking sources.
- Tracking sites may block automated access or require CAPTCHA solving.
- Session cookies may be needed for some source flows.
- 17TRACK may show limited data for unregistered tracking numbers.
- The actor does not invent tracking data — it only returns what sources expose.
- Heavy use may require higher Apify memory, concurrency, and proxy budgets.

### License

This project is licensed under the MIT License - see the LICENSE file for details.

### Get Started

Add your tracking numbers, turn on a residential proxy, and start your first run on Apify.

# Actor input Schema

## `trackingInputs` (type: `array`):

List of tracking requests. Each item may include trackingNumber, orderId, carrierHint, sourceHint, and countryHint. Plain strings are accepted as tracking numbers.

## `sourcePriority` (type: `array`):

Ordered list of tracking sources to try. The actor walks this list top-to-bottom and stops at the first source that returns valid data.

## `includeEventHistory` (type: `boolean`):

Include the full timeline of tracking events in the output.

## `includeRawSourcePayload` (type: `boolean`):

Include a sanitized raw source payload or extracted HTML text for debugging purposes.

## `includeDerivedStatus` (type: `boolean`):

Compute a normalized high-level status from source-specific status strings.

## `maxEventsPerTracking` (type: `integer`):

Maximum number of tracking events to return per shipment.

## `outputMode` (type: `string`):

Where to write tracking results. dataset: default Apify dataset. kv\_store: key-value store JSON bundle. both: write to both.

## `outputKvStoreKey` (type: `string`):

Key name used when writing results to the key-value store.

## `requestTimeoutSecs` (type: `integer`):

Maximum time in seconds to wait for a single page navigation to complete.

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

Maximum number of tracking lookups to run in parallel.

## `retriesPerSource` (type: `integer`):

Number of retry attempts per source adapter before moving to the next source.

## `challengeWaitSecs` (type: `integer`):

Maximum time in seconds to wait for a Cloudflare or CAPTCHA challenge page to resolve.

## `blockAssets` (type: `boolean`):

Block images, fonts, and other non-essential assets to speed up page loads.

## `debugMode` (type: `boolean`):

Enable debug mode to save HTML snapshots and screenshots for failed or blocked pages.

## `saveHtmlSnapshot` (type: `boolean`):

Save an HTML snapshot to the key-value store when extraction fails.

## `saveScreenshot` (type: `boolean`):

Save a page screenshot to the key-value store when extraction fails.

## `useCarrierAutoDetect` (type: `boolean`):

Reserved for future use. Carrier auto-detection from tracking number format is not yet implemented.

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

Apify proxy settings. Residential proxy is recommended for Cainiao, AliExpress, and 17TRACK pages.

## `cookiesText` (type: `string`):

Optional browser cookies in Netscape/tab-separated format. Each line: name<TAB>value<TAB>domain<TAB>path. Stored as a secret input and never written to the dataset.

## `cookiesJson` (type: `string`):

Optional Playwright cookie array JSON. Alternative to cookiesText. Stored as a secret input and never written to the dataset.

## `seventeenTrackApiKey` (type: `string`):

Optional 17TRACK API key for future API-based tracking. Currently unused; reserved for API adapter expansion.

## Actor input object example

```json
{
  "trackingInputs": [
    {
      "trackingNumber": "LP00123456789012",
      "orderId": "8182736455463721"
    },
    {
      "trackingNumber": "CNABC0012345678",
      "carrierHint": "Cainiao",
      "countryHint": "PK"
    }
  ],
  "sourcePriority": [
    "cainiao_web",
    "aliexpress_web",
    "seventeen_track_web"
  ],
  "includeEventHistory": true,
  "includeRawSourcePayload": false,
  "includeDerivedStatus": true,
  "maxEventsPerTracking": 50,
  "outputMode": "dataset",
  "outputKvStoreKey": "TRACKING_OUTPUT",
  "requestTimeoutSecs": 45,
  "maxConcurrency": 3,
  "retriesPerSource": 2,
  "challengeWaitSecs": 12,
  "blockAssets": true,
  "debugMode": false,
  "saveHtmlSnapshot": false,
  "saveScreenshot": false,
  "useCarrierAutoDetect": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `trackings` (type: `string`):

Normalized shipment tracking records in the default dataset.

## `kvOutput` (type: `string`):

JSON bundle with records and run summary when outputMode is kv\_store or both.

# 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 = {
    "trackingInputs": [
        {
            "trackingNumber": "LP00123456789012",
            "orderId": "8182736455463721"
        },
        {
            "trackingNumber": "CNABC0012345678",
            "carrierHint": "Cainiao",
            "countryHint": "PK"
        }
    ],
    "sourcePriority": [
        "cainiao_web",
        "aliexpress_web",
        "seventeen_track_web"
    ],
    "includeEventHistory": true,
    "includeRawSourcePayload": false,
    "includeDerivedStatus": true,
    "maxEventsPerTracking": 50,
    "outputMode": "dataset",
    "outputKvStoreKey": "TRACKING_OUTPUT",
    "requestTimeoutSecs": 45,
    "maxConcurrency": 3,
    "retriesPerSource": 2,
    "challengeWaitSecs": 12,
    "blockAssets": true,
    "debugMode": false,
    "saveHtmlSnapshot": false,
    "saveScreenshot": false,
    "useCarrierAutoDetect": true,
    "cookiesText": "",
    "cookiesJson": "",
    "seventeenTrackApiKey": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("sovanza.inc/ali-express-tracking").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 = {
    "trackingInputs": [
        {
            "trackingNumber": "LP00123456789012",
            "orderId": "8182736455463721",
        },
        {
            "trackingNumber": "CNABC0012345678",
            "carrierHint": "Cainiao",
            "countryHint": "PK",
        },
    ],
    "sourcePriority": [
        "cainiao_web",
        "aliexpress_web",
        "seventeen_track_web",
    ],
    "includeEventHistory": True,
    "includeRawSourcePayload": False,
    "includeDerivedStatus": True,
    "maxEventsPerTracking": 50,
    "outputMode": "dataset",
    "outputKvStoreKey": "TRACKING_OUTPUT",
    "requestTimeoutSecs": 45,
    "maxConcurrency": 3,
    "retriesPerSource": 2,
    "challengeWaitSecs": 12,
    "blockAssets": True,
    "debugMode": False,
    "saveHtmlSnapshot": False,
    "saveScreenshot": False,
    "useCarrierAutoDetect": True,
    "cookiesText": "",
    "cookiesJson": "",
    "seventeenTrackApiKey": "",
}

# Run the Actor and wait for it to finish
run = client.actor("sovanza.inc/ali-express-tracking").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 '{
  "trackingInputs": [
    {
      "trackingNumber": "LP00123456789012",
      "orderId": "8182736455463721"
    },
    {
      "trackingNumber": "CNABC0012345678",
      "carrierHint": "Cainiao",
      "countryHint": "PK"
    }
  ],
  "sourcePriority": [
    "cainiao_web",
    "aliexpress_web",
    "seventeen_track_web"
  ],
  "includeEventHistory": true,
  "includeRawSourcePayload": false,
  "includeDerivedStatus": true,
  "maxEventsPerTracking": 50,
  "outputMode": "dataset",
  "outputKvStoreKey": "TRACKING_OUTPUT",
  "requestTimeoutSecs": 45,
  "maxConcurrency": 3,
  "retriesPerSource": 2,
  "challengeWaitSecs": 12,
  "blockAssets": true,
  "debugMode": false,
  "saveHtmlSnapshot": false,
  "saveScreenshot": false,
  "useCarrierAutoDetect": true,
  "cookiesText": "",
  "cookiesJson": "",
  "seventeenTrackApiKey": ""
}' |
apify call sovanza.inc/ali-express-tracking --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sovanza.inc/ali-express-tracking",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0BXmOaIWdo6pUKUdY/builds/UhurKKBHMwrVyfyv2/openapi.json
