# 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin (`sourcing-data-studio/1688-landed-cost-api`) Actor

1688 landed cost API: give your 1688 product rows (any 1688 scraper's dataset, or CSV) and a destination; get the delivered cost per unit (price tier, ECB rate, freight, insurance, duty, VAT) plus the AliExpress median and margin. Never loads 1688. Pay per computed product.

- **URL**: https://apify.com/sourcing-data-studio/1688-landed-cost-api.md
- **Developed by:** [Sourcing Data Studio](https://apify.com/sourcing-data-studio) (community)
- **Categories:** E-commerce, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 landed cost 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?

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

Know what a 1688 product costs delivered before you order it. This Actor is a 1688 landed cost API for the product rows you already have (the dataset of any 1688 scraper run, or CSV text). It works out the delivered cost per unit to Bahrain, Saudi Arabia, the United Arab Emirates, Oman, Qatar, Kuwait, the United Kingdom or the United States: price tier, ECB exchange rate, freight, insurance, duty, VAT and fees, plus the AliExpress median price and your margin. It never loads 1688. You pay only for computed rows saved to your dataset: $0.003 per computed product on the Free tier, so a typical query (the 50 products of one 1688 scraper run, to one destination) costs $0.15.

**At a glance:** three rows from a real run.

| Product | To | Qty | Unit price (CNY) | Delivered per unit | Duty (whole order) | Currency |
|---|---|---|---|---|---|---|
| Silicone phone case | BH | 500 | 2.8 | 0.39134 | 8.471 | BHD |
| Cotton tote bag | BH | 500 | 4.2 | 0.82269 | 17.807 | BHD |
| Ceramic coffee mug 350 ml | BH | 500 | 6.8 | 1.56211 | 33.812 | BHD |

Unofficial: not affiliated with or endorsed by 1688.com, Alibaba Group, AliExpress, the European Central Bank, HM Revenue & Customs or the U.S. International Trade Commission.

Exchange rates derived from ECB reference rates (source: European Central Bank). Contains public sector information licensed under the Open Government Licence v3.0. Source: Harmonized Tariff Schedule of the United States, U.S. International Trade Commission.

Importers, sourcing agents and online sellers use it as a landed cost calculator and an import duty calculator for a whole list of products. Give your forwarder's rate and it adds the 1688 shipping cost of every product; give your sell price and it works as a 1688 profit calculator. Every row says where each figure comes from and what it leaves out.

Every row carries this notice, word for word:

> Estimate only, not a customs ruling or tax advice. Built from public tariff data, reference exchange rates and the assumptions listed for this row. Customs decides classification, value, origin and rates at entry, and rules change often. Verify with a licensed customs broker before you buy, price or declare.

### What does 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin do?

- Reads your 1688 product rows: the dataset of a 1688 scraper run (its ID pasted in the form, or passed as `datasetId`), CSV text (`productsCsv`), or both. It recognises the usual fields of 1688 scrapers (price tiers, price range, MOQ, unit weight, offer ID, English title), and **Column mapping** covers any other shape.
- Never loads 1688. It reads four public sources only: the ECB euro reference rates, the UK Trade Tariff, the US Harmonized Tariff Schedule and AliExpress search pages.
- Picks the price tier for your quantity (or for the MOQ), converts CNY at the ECB rate of the day, and adds the shipping inside China, the freight from your own rate and the insurance.
- Works out duty and VAT for the destination: 5 % of CIF and the state's VAT for the GCC; the third-country duty of the UK commodity code and UK VAT; for the US the general duty, the 12.5 % forced-labour Section 301 duty on goods from China, the merchandise processing fee and, by sea, the harbor maintenance fee on formal entries (above USD 2,500). The Section 301 list duties are not included in this version unless you give their rate (see "United States" below).
- Returns the landed total and the cost per unit, with and without VAT, and the profit and margin per unit when you give a sell price.
- Checks the market: the median, lowest and top-selling price of the product's keyword on AliExpress, and your margin at the median (net of the destination VAT).
- Says where every figure comes from (`basis`) and what it leaves out or assumes (`flags`), with the ECB date, the tariff dates and the version of every data table.
- Charges one event per computed row. A row it cannot compute is skipped, listed in the run summary with the reason, and never charged.
- Works from Apify Console, the Apify API, n8n, Make and AI agents through the Apify MCP server, and runs by itself after every run of your 1688 scraper through an integration.

### Output example

These rows come from a real run.

```json
[
  {
    "offerId": null,
    "offerUrl": null,
    "title": null,
    "titleEn": "Silicone phone case",
    "supplierName": null,
    "sourceIndex": 0,
    "sourceType": "csv",
    "destination": "BH",
    "currency": "BHD",
    "shippingMode": "airExpress",
    "shipmentType": "commercial",
    "quantity": 500,
    "moq": 100,
    "priceTier": {
      "minQuantity": 1,
      "maxQuantity": null,
      "priceCny": 2.8
    },
    "unitPriceCny": 2.8,
    "goodsCny": 1400,
    "hsCode": null,
    "hsCodeBasis": "not-computed",
    "goods": 78.893,
    "domesticShipping": 1.691,
    "freight": 87.984,
    "insurance": 0.843,
    "sourcingFee": 0,
    "dutiableValue": 169.41,
    "duty": 8.471,
    "dutyLines": [
      {
        "code": "GCC-CET",
        "label": "Customs duty, 5% of CIF (GCC common external tariff)",
        "ratePercent": 5,
        "rateText": null,
        "amount": 8.471,
        "basis": "default-assumption"
      }
    ],
    "fees": 0,
    "feeLines": [],
    "vat": 17.788,
    "vatRatePercent": 10,
    "vatKind": "import",
    "landedTotal": 195.669,
    "landedTotalExVat": 177.881,
    "landedPerUnit": 0.39134,
    "landedPerUnitExVat": 0.35576,
    "basis": {
      "quantity": "user",
      "unitPrice": "computed",
      "goods": "computed",
      "domesticShipping": "computed",
      "freight": "user",
      "insurance": "default-assumption",
      "sourcingFee": "default-assumption",
      "exchangeRate": "computed",
      "dutiableValue": "computed",
      "duty": "default-assumption",
      "fees": "not-computed",
      "vat": "computed",
      "landedTotal": "computed",
      "profit": "not-computed"
    },
    "sellPricePerUnit": null,
    "profitPerUnit": null,
    "marginPercent": null,
    "market": {
      "keyword": "silicone phone case",
      "status": "ok",
      "cardsRead": 46,
      "pricedCards": 15,
      "currency": "USD",
      "medianPrice": 4.19,
      "lowestPrice": 2.23,
      "topSoldPrice": 4.45,
      "topSoldCount": 441,
      "medianPriceLocal": 1.57544,
      "marginPerUnitLocal": 1.07646,
      "marginPercent": 75.16,
      "shipTo": "US",
      "note": "AliExpress showed its prices for delivery to US, not BH: prices and taxes for BH may differ.",
      "retrievedAt": "2026-11-04T09:16:53.666Z"
    },
    "exchangeRates": {
      "source": "ECB",
      "date": "2026-11-03",
      "usdPerCny": 0.1498726371,
      "gbpPerUsd": 0.7456659809,
      "localPerUsd": 0.376,
      "localRateSource": "peg-table",
      "label": "derived from ECB reference rates; BHD per USD 0.376 (peg, table gcc-pegs 2026-11)"
    },
    "sources": {
      "ecbDate": "2026-11-03",
      "ukAsOf": null,
      "htsRelease": null,
      "tables": {
        "gcc-pegs": "2026-11",
        "destination-vat": "2026-11",
        "gcc-duty": "2026-11",
        "uk-rules": "2026-11",
        "us-cbp-fees": "FY2027",
        "freight-model": "2026-11",
        "us-ch99-status": "2026-rev22"
      }
    },
    "flags": [
      "INSURANCE_ASSUMED",
      "FX_NOT_CUSTOMS_RATE",
      "HS_MISSING_GCC_GENERAL_RATE"
    ],
    "notes": [
      "one price for every quantity (priceCny)",
      "5% GCC general rate applied. Exempt lines and higher national rates (Saudi Arabia) not checked.",
      "GCC customs service fees and excise are not included; direct shipment to the destination state is assumed (duty is collected at the first GCC point of entry)."
    ],
    "disclaimer": "Estimate only, not a customs ruling or tax advice. Built from public tariff data, reference exchange rates and the assumptions listed for this row. Customs decides classification, value, origin and rates at entry, and rules change often. Verify with a licensed customs broker before you buy, price or declare.",
    "computedAt": "2026-11-04T09:17:18.221Z"
  },
  {
    "offerId": null,
    "offerUrl": null,
    "title": null,
    "titleEn": "Cotton tote bag",
    "supplierName": null,
    "sourceIndex": 1,
    "sourceType": "csv",
    "destination": "BH",
    "currency": "BHD",
    "shippingMode": "airExpress",
    "shipmentType": "commercial",
    "quantity": 500,
    "moq": 200,
    "priceTier": {
      "minQuantity": 1,
      "maxQuantity": null,
      "priceCny": 4.2
    },
    "unitPriceCny": 4.2,
    "goodsCny": 2100,
    "hsCode": null,
    "hsCodeBasis": "not-computed",
    "goods": 118.339,
    "domesticShipping": 1.409,
    "freight": 234.624,
    "insurance": 1.772,
    "sourcingFee": 0,
    "dutiableValue": 356.144,
    "duty": 17.807,
    "dutyLines": [
      {
        "code": "GCC-CET",
        "label": "Customs duty, 5% of CIF (GCC common external tariff)",
        "ratePercent": 5,
        "rateText": null,
        "amount": 17.807,
        "basis": "default-assumption"
      }
    ],
    "fees": 0,
    "feeLines": [],
    "vat": 37.395,
    "vatRatePercent": 10,
    "vatKind": "import",
    "landedTotal": 411.346,
    "landedTotalExVat": 373.951,
    "landedPerUnit": 0.82269,
    "landedPerUnitExVat": 0.7479,
    "basis": {
      "quantity": "user",
      "unitPrice": "computed",
      "goods": "computed",
      "domesticShipping": "computed",
      "freight": "user",
      "insurance": "default-assumption",
      "sourcingFee": "default-assumption",
      "exchangeRate": "computed",
      "dutiableValue": "computed",
      "duty": "default-assumption",
      "fees": "not-computed",
      "vat": "computed",
      "landedTotal": "computed",
      "profit": "not-computed"
    },
    "sellPricePerUnit": null,
    "profitPerUnit": null,
    "marginPercent": null,
    "market": {
      "keyword": "cotton tote bag",
      "status": "ok",
      "cardsRead": 59,
      "pricedCards": 17,
      "currency": "USD",
      "medianPrice": 249.7,
      "lowestPrice": 2.79,
      "topSoldPrice": 2.79,
      "topSoldCount": 6033,
      "medianPriceLocal": 93.8872,
      "marginPerUnitLocal": 84.6041,
      "marginPercent": 99.12,
      "shipTo": "US",
      "note": "AliExpress showed its prices for delivery to US, not BH: prices and taxes for BH may differ.",
      "retrievedAt": "2026-11-04T09:17:06.967Z"
    },
    "exchangeRates": {
      "source": "ECB",
      "date": "2026-11-03",
      "usdPerCny": 0.1498726371,
      "gbpPerUsd": 0.7456659809,
      "localPerUsd": 0.376,
      "localRateSource": "peg-table",
      "label": "derived from ECB reference rates; BHD per USD 0.376 (peg, table gcc-pegs 2026-11)"
    },
    "sources": {
      "ecbDate": "2026-11-03",
      "ukAsOf": null,
      "htsRelease": null,
      "tables": {
        "gcc-pegs": "2026-11",
        "destination-vat": "2026-11",
        "gcc-duty": "2026-11",
        "uk-rules": "2026-11",
        "us-cbp-fees": "FY2027",
        "freight-model": "2026-11",
        "us-ch99-status": "2026-rev22"
      }
    },
    "flags": [
      "INSURANCE_ASSUMED",
      "FX_NOT_CUSTOMS_RATE",
      "HS_MISSING_GCC_GENERAL_RATE"
    ],
    "notes": [
      "one price for every quantity (priceCny)",
      "5% GCC general rate applied. Exempt lines and higher national rates (Saudi Arabia) not checked.",
      "GCC customs service fees and excise are not included; direct shipment to the destination state is assumed (duty is collected at the first GCC point of entry)."
    ],
    "disclaimer": "Estimate only, not a customs ruling or tax advice. Built from public tariff data, reference exchange rates and the assumptions listed for this row. Customs decides classification, value, origin and rates at entry, and rules change often. Verify with a licensed customs broker before you buy, price or declare.",
    "computedAt": "2026-11-04T09:17:18.221Z"
  },
  {
    "offerId": null,
    "offerUrl": null,
    "title": null,
    "titleEn": "Ceramic coffee mug 350 ml",
    "supplierName": null,
    "sourceIndex": 2,
    "sourceType": "csv",
    "destination": "BH",
    "currency": "BHD",
    "shippingMode": "airExpress",
    "shipmentType": "commercial",
    "quantity": 500,
    "moq": 72,
    "priceTier": {
      "minQuantity": 1,
      "maxQuantity": null,
      "priceCny": 6.8
    },
    "unitPriceCny": 6.8,
    "goodsCny": 3400,
    "hsCode": null,
    "hsCodeBasis": "not-computed",
    "goods": 191.597,
    "domesticShipping": 2.254,
    "freight": 479.024,
    "insurance": 3.364,
    "sourcingFee": 0,
    "dutiableValue": 676.24,
    "duty": 33.812,
    "dutyLines": [
      {
        "code": "GCC-CET",
        "label": "Customs duty, 5% of CIF (GCC common external tariff)",
        "ratePercent": 5,
        "rateText": null,
        "amount": 33.812,
        "basis": "default-assumption"
      }
    ],
    "fees": 0,
    "feeLines": [],
    "vat": 71.005,
    "vatRatePercent": 10,
    "vatKind": "import",
    "landedTotal": 781.057,
    "landedTotalExVat": 710.052,
    "landedPerUnit": 1.56211,
    "landedPerUnitExVat": 1.4201,
    "basis": {
      "quantity": "user",
      "unitPrice": "computed",
      "goods": "computed",
      "domesticShipping": "computed",
      "freight": "user",
      "insurance": "default-assumption",
      "sourcingFee": "default-assumption",
      "exchangeRate": "computed",
      "dutiableValue": "computed",
      "duty": "default-assumption",
      "fees": "not-computed",
      "vat": "computed",
      "landedTotal": "computed",
      "profit": "not-computed"
    },
    "sellPricePerUnit": null,
    "profitPerUnit": null,
    "marginPercent": null,
    "market": {
      "keyword": "ceramic coffee mug",
      "status": "ok",
      "cardsRead": 60,
      "pricedCards": 37,
      "currency": "USD",
      "medianPrice": 12.55,
      "lowestPrice": 4.39,
      "topSoldPrice": 5.36,
      "topSoldCount": 5424,
      "medianPriceLocal": 4.7188,
      "marginPerUnitLocal": 2.86971,
      "marginPercent": 66.9,
      "shipTo": "US",
      "note": "AliExpress showed its prices for delivery to US, not BH: prices and taxes for BH may differ.",
      "retrievedAt": "2026-11-04T09:17:16.566Z"
    },
    "exchangeRates": {
      "source": "ECB",
      "date": "2026-11-03",
      "usdPerCny": 0.1498726371,
      "gbpPerUsd": 0.7456659809,
      "localPerUsd": 0.376,
      "localRateSource": "peg-table",
      "label": "derived from ECB reference rates; BHD per USD 0.376 (peg, table gcc-pegs 2026-11)"
    },
    "sources": {
      "ecbDate": "2026-11-03",
      "ukAsOf": null,
      "htsRelease": null,
      "tables": {
        "gcc-pegs": "2026-11",
        "destination-vat": "2026-11",
        "gcc-duty": "2026-11",
        "uk-rules": "2026-11",
        "us-cbp-fees": "FY2027",
        "freight-model": "2026-11",
        "us-ch99-status": "2026-rev22"
      }
    },
    "flags": [
      "INSURANCE_ASSUMED",
      "FX_NOT_CUSTOMS_RATE",
      "HS_MISSING_GCC_GENERAL_RATE"
    ],
    "notes": [
      "one price for every quantity (priceCny)",
      "5% GCC general rate applied. Exempt lines and higher national rates (Saudi Arabia) not checked.",
      "GCC customs service fees and excise are not included; direct shipment to the destination state is assumed (duty is collected at the first GCC point of entry)."
    ],
    "disclaimer": "Estimate only, not a customs ruling or tax advice. Built from public tariff data, reference exchange rates and the assumptions listed for this row. Customs decides classification, value, origin and rates at entry, and rules change often. Verify with a licensed customs broker before you buy, price or declare.",
    "computedAt": "2026-11-04T09:17:18.221Z"
  }
]
```

#### A worked example: phone cases to Bahrain

These figures are the first worked example of the method (ECB reference rates of 3 November 2026), not a run. 500 silicone phone cases with price tiers of CNY 3.50 (2 or more), 2.80 (100 or more) and 2.20 (1,000 or more), 0.05 kg each, 200 to a 50 x 40 x 30 cm carton, CNY 30 of shipping inside China, air express at USD 6.50 per kg, no HS code:

| Step | Figure |
|---|---|
| Price tier and goods | 500 x CNY 2.80 = CNY 1,400 = USD 209.82 |
| Shipping inside China | CNY 30 = USD 4.50 |
| Freight | 3 cartons: 25 kg actual, 36.0 kg volumetric, so 36.0 kg x USD 6.50 = USD 234.00 |
| Insurance (0.5 %, assumed) | USD 2.24 |
| CIF | USD 450.56 = BHD 169.410 |
| Duty (5 % GCC general rate, no HS code) | BHD 8.471 |
| VAT (10 % of CIF and duty) | BHD 17.788 |
| Landed total, and without VAT | BHD 195.669, and BHD 177.881 |
| Per unit, and without VAT | BHD 0.39134, and BHD 0.35576 |

The row carries the flags `INSURANCE_ASSUMED`, `FX_NOT_CUSTOMS_RATE` and `HS_MISSING_GCC_GENERAL_RATE`. In the row, the goods, the shipping inside China, the freight and the insurance are each rounded to BHD 78.893, 1.691, 87.984 and 0.843, which add up to 169.411, one fils more than the CIF: totals come from the unrounded parts.

### What data can you get with 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin?

| Field | Type | Description |
|---|---|---|
| `offerId` | string | Digits of the 1688 offer as your row gives them (an ID field, or the digits of an offer/<digits>.html address). Null when the row has none. |
| `offerUrl` | string | Public address of the 1688 offer page, built from offerId (`detail.1688.com/offer/<offerId>.html`), never copied from your row. Null when the row has no offer ID. The Actor never loads it. |
| `title` | string | Product title as your row gives it, often in Chinese. Null when the row has none. |
| `titleEn` | string | English title from your row, when it has one. The Actor does not translate titles. |
| `supplierName` | string | Supplier company name from your row, when it has one. No other supplier data is copied. |
| `sourceIndex` | integer | Where the row sits in your input: its position in the dataset (0 is the first item), or its CSV data line (0 is the first line after the column names). |
| `sourceType` | string | dataset when the row came from datasetId, csv when it came from productsCsv. |
| `destination` | string | Destination country the cost is worked out for: BH, SA, AE, OM, QA, KW, GB or US. |
| `currency` | string | Currency of the destination, and of every amount in the row except the CNY fields and the prices AliExpress showed. |
| `shippingMode` | string | Shipping mode of the calculation: airExpress, airCargo or sea (LCL). |
| `shipmentType` | string | commercial (the default) or personal. GCC low-value thresholds apply to personal shipments only. |
| `quantity` | number | Units costed: your quantity, or the row's minimum order quantity (MOQ) when you gave none. A quantity below the MOQ is raised to it (flag QTY_RAISED_TO_MOQ). |
| `moq` | number | Minimum order quantity from your row. Null when the row has none. |
| `priceTier` | object | The price tier used: the tier with the largest minimum quantity at or below quantity. minQuantity and maxQuantity are units (maxQuantity null means no upper bound), priceCny is CNY per unit. |
| `unitPriceCny` | number | Unit price in CNY at that tier. |
| `goodsCny` | number | Goods value in CNY: quantity times unitPriceCny. |
| `hsCode` | string | HS or national tariff code the duty was worked out with (6, 8 or 10 digits): from your row, from the hsCode input, or a suggested code (hsCodeBasis suggested-code). Null for a GCC row without a code, which gets the 5 % GCC general rate. |
| `hsCodeBasis` | string | Where the code comes from: user (your row or the hsCode input), suggested-code (a tariff text search of the title, used only with computeWithSuggestedCode) or not-computed (a GCC row without a code). |
| `goods` | number | Goods value in the destination currency: goodsCny at the ECB cross rate (plus your paymentFxMarkupPercent), then into the destination currency. |
| `domesticShipping` | number | Shipping inside China, supplier to forwarder, in the destination currency: from chinaShippingCny, from your row, or 0 (flag DOMESTIC_SHIPPING_MISSING). |
| `freight` | number | International freight in the destination currency, from your rate and the chargeable weight (air) or W/M (sea). 0 when you gave no rate (flag FREIGHT_NOT_INCLUDED): the Actor never invents a freight rate. |
| `insurance` | number | Cargo insurance in the destination currency: insurancePercent (default 0.5, flag INSURANCE_ASSUMED) of goods, domestic shipping and freight, at the ECB cross rate (without paymentFxMarkupPercent). |
| `sourcingFee` | number | Sourcing agent fee in the destination currency: sourcingFeePercent of the goods value. It is part of the landed total and of no dutiable value. |
| `dutiableValue` | number | The value duty is charged on, in the destination currency: CIF for the GCC, the customs value for the UK, and for the US the goods and domestic shipping (no international freight or insurance). It takes the goods at the ECB cross rate: paymentFxMarkupPercent is in the landed total, in no dutiable value. |
| `duty` | number | All duties of the row in the destination currency: the sum of dutyLines. |
| `dutyLines` | array | Each duty: code (GCC-CET, UK-103, US-GENERAL or a Chapter 99 heading such as 9903.88.15), label, ratePercent, rateText as published, amount in the destination currency and basis. |
| `fees` | number | Entry fees in the destination currency: the US merchandise processing fee (MPF) and, by sea, the harbor maintenance fee (HMF, 0.125 %, formal entries only: the entry's dutiable value above USD 2,500; not included for informal entries). 0 for the GCC and the UK, where customs service fees are not computed (basis.fees not-computed). |
| `feeLines` | array | Each US entry fee: code (MPF or HMF), label and amount in the destination currency. Empty for the GCC and the UK. |
| `vat` | number | Import VAT in the destination currency. For UK goods of GBP 135 or less it is the VAT at the point of sale instead (vatKind point-of-sale). 0 for the US, which has no federal VAT. |
| `vatRatePercent` | number | VAT rate used, in percent (0 for the US, Qatar and Kuwait). |
| `vatKind` | string | import, point-of-sale (UK goods of GBP 135 or less) or none (US). |
| `landedTotal` | number | Landed cost of the whole quantity in the destination currency: goods, domestic shipping, freight, insurance, sourcing fee, duties, fees and VAT, added up before rounding. |
| `landedTotalExVat` | number | landedTotal without the import VAT, for VAT-registered importers who usually recover it. |
| `landedPerUnit` | number | landedTotal divided by quantity, with two more decimals than the currency has. |
| `landedPerUnitExVat` | number | landedTotalExVat divided by quantity, with two more decimals than the currency has. |
| `basis` | object | Where each figure comes from: computed, user (your input), default-assumption (a default of the method, such as insurance 0.5 % or quantity = MOQ), suggested-code, or not-computed (left out, amount 0). Keys: quantity, unitPrice, goods, domesticShipping, freight, insurance, sourcingFee, exchangeRate, dutiableValue, duty, fees, vat, landedTotal, profit. |
| `sellPricePerUnit` | number | Your sellPricePerUnit in the destination currency, VAT included where the destination has VAT. Null when you gave none. |
| `profitPerUnit` | number | Profit per unit: the sell price without VAT, less the marketplace fee and the fixed fee per unit, less landedPerUnitExVat. Null without sellPricePerUnit. |
| `marginPercent` | number | profitPerUnit divided by the sell price without VAT, in percent. Null without sellPricePerUnit. |
| `market` | object | AliExpress market check of the row's keyword: status (ok, few-results, no-results, blocked, failed, not-read or not-run), cards read and priced, the median, lowest and top-sold price in the currency AliExpress showed, the median in the destination currency (medianPriceLocal) and the margin per unit (marginPerUnitLocal): the median taken as a VAT-included price, net of the destination VAT (medianPriceLocal / (1 + vatRatePercent / 100)), less landedPerUnitExVat, before marketplace fees; market.marginPercent is that margin in percent of the net median. Null when the market check is off or the row has no keyword. A failed check does not stop the row. |
| `exchangeRates` | object | Exchange rates used, to 10 significant digits: source ECB, date of the ECB reference rates, usdPerCny and gbpPerUsd (ECB cross rates), localPerUsd with localRateSource (ECB for GBP and USD, the peg table for BHD, SAR, AED, OMR and QAR, the dated basket rate of the table for KWD), and the label. |
| `sources` | object | Dates and versions behind the figures: ecbDate, ukAsOf (UK Trade Tariff date, UK rows only), htsRelease (US tariff release, US rows only) and tables (the version of every data table of the run). |
| `flags` | array | What the figures leave out or assume, as codes (the README lists them all). A flag never changes a figure by itself. |
| `notes` | array | Short sentences on what was assumed or decided for this row. |
| `disclaimer` | string | Estimate only, not a customs ruling or tax advice. Built from public tariff data, reference exchange rates and the assumptions listed for this row. Customs decides classification, value, origin and rates at entry, and rules change often. Verify with a licensed customs broker before you buy, price or declare. |
| `computedAt` | string | ISO 8601 time (UTC) when the row was computed. |

Some notes on the fields:

- Every amount is in the currency of the destination (`currency`), except the fields that end in `Cny` and the prices AliExpress showed (`market.medianPrice`, `market.lowestPrice`, `market.topSoldPrice`, in `market.currency`).
- Amounts are rounded half away from zero to the minor unit of the currency (3 decimals for BHD, OMR and KWD, 2 for the others), and per-unit figures get two more. Totals are added up before rounding, so the parts may differ from a total by one minor unit.
- `basis` says where each figure comes from: `computed`, `user` (your input), `default-assumption` (a default of the method, such as insurance 0.5 % or the MOQ as quantity), `suggested-code`, or `not-computed` (left out, counted as 0).
- `flags` say what the figures leave out or assume. A flag never changes a figure by itself.
- The row copies only these fields of your row: offer ID (with an offer address built from it), title, English title and supplier company name. Nothing else of it is kept: no member or user IDs, addresses or reviews.

#### Flags

| Flag | Meaning |
|---|---|
| `QTY_RAISED_TO_MOQ` | Your quantity was below the row's MOQ (or its first price tier) and was raised to it. |
| `DOMESTIC_SHIPPING_MISSING` | No shipping inside China was given or found: it counts as 0. |
| `INSURANCE_ASSUMED` | No insurance percent was given: 0.5 % was used. |
| `FREIGHT_NOT_INCLUDED` | No freight rate was given: freight is 0. The Actor never invents a rate. |
| `NO_DIMENSIONS` | The row has no carton size: freight uses the actual weight only. |
| `FX_NOT_CUSTOMS_RATE` | The ECB reference rate is not the rate customs uses (the UK uses HMRC's monthly rates; US and GCC customs have their own). The ECB itself discourages using its rates for transactions. |
| `HS_MISSING_GCC_GENERAL_RATE` | No HS code: the 5 % GCC general rate was applied. Exempt lines and higher national rates (Saudi Arabia) were not checked. |
| `GCC_RATE_NOT_LINE_CHECKED` | The 5 % rate was not checked against the national line of the code. |
| `KSA_RATE_MAY_EXCEED_5` | Saudi Arabia charges more than 5 % on many lines. Give **Saudi Arabia duty (%)** when you know the rate. |
| `GCC_LOW_VALUE_RELIEF` | A personal shipment under the state's low-value threshold: no duty, VAT still due. Each row is taken as its own shipment: rows shipped together with a CIF value over the threshold in all pay customs duty. |
| `UK_TRADE_REMEDY_MEASURE` | The UK line carries an anti-dumping or other trade remedy measure, which is not in the duty. |
| `UK_LOW_VALUE_RELIEF` | Goods of GBP 135 or less: no import duty, and VAT is charged at the point of sale instead of at import. Each row is taken as its own consignment: rows shipped together with goods over GBP 135 in all pay duty and import VAT at the border. |
| `US_DUTY_UNITS_MISSING` | A US rate per unit or per kg needs a figure the row does not give. |
| `US_VALUE_BRACKET_MISMATCH` | The value per unit does not fit the "valued over" or "not over" bracket of the US line. |
| `NO_DE_MINIMIS_US` | The US de minimis exemption is suspended: small shipments pay duty and fees too. |
| `US_232_POSSIBLE` | Section 232 duties on steel, aluminium or copper may apply. They are not in the duty. |
| `US_FORCED_LABOUR_EXEMPTION_NOT_CHECKED` | The 12.5 % Section 301 duty of 9903.05.31 was applied; its exemptions were not checked. |
| `US_301_EXCLUSION_POSSIBLE` | A Section 301 exclusion may apply. It is not applied. |
| `US_ADCVD_POSSIBLE` | Anti-dumping or countervailing duties may apply. They are not in the duty. |
| `US_301_NOT_INCLUDED` | The Section 301 list duties are not in the duty: this version has no verified table of the codes each list covers, and you gave no **US Section 301 duty (%)**. |
| `US_CH99_RATE_UNREAD` | The rate text of a Chapter 99 line could not be read: that duty is left out. |
| `MPF_PER_ENTRY` | The merchandise processing fee was worked out as if the row were its own customs entry. |
| `HS_TOO_SHORT` | A 6-digit code covers national lines with different rates: give the full code. |
| `SUGGESTED_HS_CODE` | The figures use a code suggested by a tariff search of the title. Verify it. |
| `TARIFF_DATA_STALE` | The Actor's table of US Chapter 99 headings was made from another release of the tariff than the one read in the run. |

### How each figure is computed

The live figures are read in the run: the ECB rates of the day, the UK commodity line and the US tariff lines. Rates that do not change from run to run (the GCC pegs, VAT rates, US entry fees, carrier conventions) come from versioned data tables, and every row names their versions.

UK tariff data comes from the [UK Trade Tariff](https://www.trade-tariff.service.gov.uk/) under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). US tariff data comes from the [Harmonized Tariff Schedule](https://hts.usitc.gov/) of the U.S. International Trade Commission.

#### Common steps

- **Quantity and price:** your quantity, or the row's MOQ when you give none; a quantity below the MOQ is raised to it, and so is one below the first price tier of the row. The unit price is the tier with the largest minimum quantity at or below the quantity. A row with only a price range is priced at the top of the range.
- **Exchange rates:** CNY, USD and GBP from the ECB reference rates of the day, cross rates kept to 10 significant digits. BHD, SAR, AED, OMR and QAR follow their published pegs to the US dollar; KWD uses the dated basket rate of the table, and a row says how old it is once it is more than 30 days older than the ECB rates. **Payment exchange markup** raises the cost of what you pay in CNY in the landed total; customs values, duty, VAT and fees use the ECB cross rate without it.
- **Freight:** only from your rate. Air: the larger of the actual weight and the volumetric weight (volume / 5000 for express, / 6000 for cargo), rounded up to 0.5 kg, times your rate. Sea (LCL): the larger of cubic metres and tonnes, at least 1 W/M, times your rate. Never below your minimum charge.
- **Insurance:** your percent (0.5 % when you give none) of the goods, the shipping inside China and the freight.

#### GCC: Bahrain, Saudi Arabia, United Arab Emirates, Oman, Qatar and Kuwait

- **CIF** = goods + shipping inside China + freight + insurance, in the local currency.
- **Duty** = 5 % of CIF, the GCC common external tariff, or your **Saudi Arabia duty (%)**. Exempt lines and national rates are flagged, not applied: there is no public GCC tariff service to read them from.
- **VAT** = the state's rate of CIF plus duty: 10 % in Bahrain, 15 % in Saudi Arabia, 5 % in the United Arab Emirates and Oman; Qatar and Kuwait levy none (November 2026; for Kuwait from secondary sources only).
- Low-value thresholds apply to personal shipments only, and each row is taken as its own shipment. Customs service fees and excise are not computed, and the goods are taken to be shipped straight to the destination state.

#### United Kingdom

- **Customs value** = goods + shipping inside China + air freight (your share, 100 % by default) + insurance, in GBP.
- **Duty** = the third-country duty of the 10-digit commodity code, read from the UK Trade Tariff for goods from China, when it is a percentage. A rate per unit or per kg is not computed: the row is skipped and not charged.
- **VAT** = the standard VAT rate of the line (20 %; a row notes the zero or reduced rates the line also shows for goods declared with an additional code) of the customs value, the duty, the freight left out of the customs value and your **UK costs to the first destination**.
- Goods of GBP 135 or less: no import duty, and the VAT is charged at the point of sale instead (flag `UK_LOW_VALUE_RELIEF`). Each row is taken as its own consignment.

#### United States

- **Dutiable value** = goods + shipping inside China. International freight and insurance are not part of it (19 CFR 152.102(f)); **US: leave China shipping out of the dutiable value** follows 152.103(a)(5)(i).
- **Duty** = the general rate of the HTS line, plus the 12.5 % forced-labour Section 301 duty on goods from China (9903.05.31). Both rates are read from the tariff in the run, and a table of the Chapter 99 headings says which are in force.
- **Section 301 lists:** the list duties (Lists 1 to 4B and the 2024 increases, 7.5 % to 100 %) are **not included** in this version: every US row says so with the flag `US_301_NOT_INCLUDED` and a duty line "Section 301: not included". Which codes a list covers is not in the tariff service; our table of them did not pass its independent check (27 of 30 sampled codes matched, the others were renumbered since the lists were published), so the Actor does not guess. If you know the rate, give **US Section 301 duty (%)**: it is applied to every US row of the run (basis `user`).
- **Fees:** the merchandise processing fee, 0.3464 % of the dutiable value (at least USD 34.58, at most USD 670.86) above USD 2,500 and USD 2.77 at or below; the harbor maintenance fee, 0.125 % by sea, on formal entries only (the entry's dutiable value above USD 2,500; not included for informal entries). Each row is its own entry unless you switch on **US: one entry for all rows**.
- No VAT: the US has no federal VAT, and state sales tax is not computed. The de minimis exemption is suspended.

#### Totals and profit

- **Landed total** = goods + shipping inside China + freight + insurance + sourcing fee + duties + fees + VAT (and, for the UK, the costs to the first destination). **Without VAT** takes the import VAT out: VAT-registered importers usually recover it.
- **Per unit** = the total divided by the quantity.
- **Profit per unit** = the sell price without VAT, less the marketplace fee and the fixed fee, less the landed cost per unit without VAT. **Margin** = profit / sell price without VAT.
- **AliExpress margin** = the AliExpress median in the destination currency, taken as a price with VAT and net of the destination VAT, less the landed cost per unit without VAT; in percent of that net median. No marketplace fees.

### How to use 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin

#### After every run of your 1688 scraper

1. In Apify Console, open the 1688 scraper you use (or your saved task of it) and go to its **Integrations** tab.
2. Add 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin as the Actor to run when a run of the scraper succeeds.
3. Give it the input `{"datasetId": "{{resource.defaultDatasetId}}", "destination": "BH"}`, with your own destination, freight rate and quantity added. Apify puts the ID of the scraper's dataset in place of `{{resource.defaultDatasetId}}`.

Each scraper run is then followed by a run of 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin on its rows.

#### With a dataset you already have, or with CSV

1. Click **Try for free** on this page.
2. In **Dataset of a 1688 scraper run**, pick a named dataset from the list, or paste the dataset ID of your 1688 scraper run (on the run's **Storage** tab): the list shows named datasets only, and a scraper run's dataset has no name. Or paste your rows into **Products as CSV**, or do both.
3. Choose the **Destination**, and set the **Quantity per product** (empty means each row's MOQ).
4. Under **Shipping and costs**, give your forwarder's **Air freight rate** or **Sea freight rate**. Without one, freight is 0 and every row says so.
5. For the UK and the US, put the HS code in your rows (`hsCode`) or in **HS code**.
6. Click **Start**. The rows appear in the **Output** tab; skipped rows are listed in the run summary (record `RUN_SUMMARY` in the **Storage** tab).

#### CSV columns

The first line holds the column names, in any letter case. The usual names of 1688 scraper exports are recognised too; for anything else use **Column mapping**.

| Column | What it holds |
|---|---|
| `titleEn`, `title` | English title (used for the AliExpress keyword) and the original title. |
| `priceCny` | Unit price in CNY. |
| `priceMinCny`, `priceMaxCny` | A price range in CNY, priced at the top of the range. |
| `moq` | Minimum order quantity. |
| `unitWeightKg` | Weight of one unit in kg (needed when you give a freight rate). |
| `unitsPerCarton`, `cartonLengthCm`, `cartonWidthCm`, `cartonHeightCm` | Packing, for the volumetric weight. |
| `hsCode` | HS or national tariff code, 6, 8 or 10 digits. |
| `domesticShippingCny` | Shipping inside China for the order line, in CNY. |
| `offerId`, `supplierName` | The 1688 offer ID and the supplier company name, copied to the row. |

### Input examples

#### CSV to Bahrain by air

```json
{
  "productsCsv": "titleEn,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nSilicone phone case,2.80,100,0.05,200,50,40,30,30\nCotton tote bag,4.20,200,0.12,100,60,40,40,25\nCeramic coffee mug 350 ml,6.80,72,0.38,36,50,35,40,40\n",
  "destination": "BH",
  "quantity": 500,
  "shippingMode": "airExpress",
  "freightRatePerKg": 6.5,
  "maxMarketChecks": 3,
  "maxItems": 10
}
```

#### CSV with HS codes to the UK

```json
{
  "productsCsv": "titleEn,hsCode,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nWomen's PU sneakers,6402999800,95.00,50,0.90,12,60,40,35,120\nCotton tote bag,4202229090,4.20,200,0.12,100,60,40,40,25\nUSB-C charging cable 1 m,8544429090,3.10,100,0.04,200,40,30,30,20\n",
  "destination": "GB",
  "quantity": 120,
  "shippingMode": "airCargo",
  "freightRatePerKg": 4.2,
  "ukFirstDestinationCostGbp": 25,
  "marketCheck": false,
  "maxItems": 10
}
```

#### Sea freight to Saudi Arabia

```json
{
  "productsCsv": "titleEn,hsCode,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nPlastic building block toys,950300,13.80,300,0.45,24,60,40,40,260\n",
  "destination": "SA",
  "quantity": 1000,
  "shippingMode": "sea",
  "seaFreightRatePerCbm": 95,
  "sellPricePerUnit": 39,
  "marketplaceFeePercent": 15,
  "maxMarketChecks": 1,
  "maxItems": 10
}
```

### Run summary

Every run writes a `RUN_SUMMARY` record to its key-value store (the **Storage** tab):

- `skippedRows` lists the first 50 rows that were not computed, each with its place in your input (`origin` and `index`), its offer ID and the reason: `no-price`, `no-weight`, `hs-code-missing`, `hs-code-invalid`, `hs-too-short`, `duty-not-computable`, `excise-goods`, `lookup-failed`, `lookup-not-read`, `fx-unavailable`, `duplicate`, `unmappable`, `sentinel-row`, `over-budget` or `invalid-row` (a computed row that failed the Actor's own output check: a fault of the Actor, so please tell us). A UK or US row without an HS code also gets up to 3 suggested codes, each marked "suggested, verify". `skippedByReason` counts all of them. None of them is charged.
- `sources` gives the ECB date, the UK and US lookups and the AliExpress keywords, with the country, currency and language AliExpress applied. `tables` gives the version of every data table, and `mapping` says how your rows were read.
- `listings` gives the status of every lookup: `ok`, `no-match`, `failed`, `blocked`, `stopped` or `not-read`.
- `otherHosts` counts the requests the loaded pages made by themselves (their scripts and data calls) to hosts other than the four sources, by host.

The status message of the run says how many rows were skipped and why.

### How much does 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin cost?

| Event | You pay for | Free | Bronze | Silver | Gold |
|---|---|---|---|---|---|
| Landed cost result | One computed landed-cost row saved to the dataset: the delivered cost of one product to one destination. Skipped rows (no price, no HS code for the UK or the US, failed lookups, duplicates, excise goods) are never charged. | $0.003 | $0.003 | $0.0027 | $0.0024 |

Prices are per event. Your tier follows your Apify subscription plan.

On the Free tier, $0.003 per computed product means:

- 100 computed products cost $0.30.
- 1,000 computed products cost $3.00.
- A typical query (the 50 products of one 1688 scraper run, to one destination) is 50 computed products and costs $0.15.

Apify also charges a tiny start fee per run (apify-actor-start, $0.00005 per GB of memory). Skipped rows (no price, no HS code for the UK or the US, failed lookups, duplicates, excise goods) are never charged. To cap your spending, set **Maximum cost per run** in the run options; the run stops cleanly when that budget is used.

### Use 1688 Landed Cost API: Delivered Price, Duty & AliExpress Margin from the API, n8n, Make or an AI agent

#### Apify API

Run the Actor on CSV rows and get the landed costs in one call:

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/sourcing-data-studio~1688-landed-cost-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"productsCsv":"titleEn,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nSilicone phone case,2.80,100,0.05,200,50,40,30,30\nCotton tote bag,4.20,200,0.12,100,60,40,40,25\nCeramic coffee mug 350 ml,6.80,72,0.38,36,50,35,40,40\n","destination":"BH","quantity":500,"shippingMode":"airExpress","freightRatePerKg":6.5,"maxMarketChecks":3,"maxItems":10}'
```

**JavaScript** (Node.js, `npm install apify-client`)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const input = {
    "productsCsv": "titleEn,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nSilicone phone case,2.80,100,0.05,200,50,40,30,30\nCotton tote bag,4.20,200,0.12,100,60,40,40,25\nCeramic coffee mug 350 ml,6.80,72,0.38,36,50,35,40,40\n",
    "destination": "BH",
    "quantity": 500,
    "shippingMode": "airExpress",
    "freightRatePerKg": 6.5,
    "maxMarketChecks": 3,
    "maxItems": 10
};

const run = await client.actor('sourcing-data-studio/1688-landed-cost-api').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**Python** (`pip install "apify-client>=3"`, Python 3.11 or later)

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run_input = {
    "productsCsv": "titleEn,priceCny,moq,unitWeightKg,unitsPerCarton,cartonLengthCm,cartonWidthCm,cartonHeightCm,domesticShippingCny\nSilicone phone case,2.80,100,0.05,200,50,40,30,30\nCotton tote bag,4.20,200,0.12,100,60,40,40,25\nCeramic coffee mug 350 ml,6.80,72,0.38,36,50,35,40,40\n",
    "destination": "BH",
    "quantity": 500,
    "shippingMode": "airExpress",
    "freightRatePerKg": 6.5,
    "maxMarketChecks": 3,
    "maxItems": 10
}

run = client.actor("sourcing-data-studio/1688-landed-cost-api").call(run_input=run_input)

for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

The synchronous call waits up to 300 seconds. Each AliExpress keyword takes about 10 seconds and each tariff lookup about 3, so for long product lists start the run with the normal run endpoint and read the dataset when it has finished.

#### n8n and Make

Use an HTTP request module with the same URL, method POST and a JSON body like the input examples above. Store your Apify API token as a credential, never in the workflow itself.

#### AI agents through the Apify MCP server

Connect your agent to the Apify MCP server and call `sourcing-data-studio/1688-landed-cost-api` with the same input: CSV text in `productsCsv` (or a dataset ID in `datasetId`) and a `destination`. Agents can use the **Feedback for the developer** field to report missing fields or problems.

### For AI agents

- Minimal input: `{"productsCsv": "titleEn,priceCny,moq\nSilicone phone case,2.80,100\n", "destination": "BH"}`. It returns one row; add `freightRatePerKg` and `unitWeightKg` to include freight.
- Read these fields first: `landedPerUnit` and `landedPerUnitExVat` with `currency`, then `basis` and `flags` to see what each figure includes. Every row carries the `disclaimer`: the figures are estimates, not a customs ruling.
- Outcomes are in the run status message and in the `RUN_SUMMARY` record of the run's key-value store: `skippedRows` gives the reason for every row that was not computed (never charged), with suggested HS codes for UK and US rows without one.
- UK and US rows need an HS code (`hsCode` in the row or in the input). With `computeWithSuggestedCode: true` they are computed with the top suggestion instead, flagged `SUGGESTED_HS_CODE`.
- Do not use it for a customs declaration, a binding classification, excise goods, or destinations other than BH, SA, AE, OM, QA, KW, GB and US.
- It is callable through the Apify MCP server as the tool `sourcing-data-studio/1688-landed-cost-api` and through the Apify API.

### Limits

- At most 2,000 products per run. The Actor reads at most 20,000 rows of a dataset and at most 5,000,000 characters of CSV.
- It never loads 1688, so prices, MOQs, weights and carton sizes are what your scraper captured. Prices are read in CNY only; the USD figures some scrapers add are ignored.
- It sends one request at a time: tariff lookups about 3 seconds apart (at most 300 per run, and at most 50 title searches for suggested codes), AliExpress keywords about 10 seconds apart (at most 50 per run, the first result page only). Rows whose lookup was not read are skipped as `lookup-not-read` and not charged.
- Freight comes only from your rate. The carrier conventions it uses (volume divided by 5,000 or 6,000, rounding up to 0.5 kg, at least 1 W/M by sea) are common, but your carrier's can differ.
- GCC: the 5 % general rate; exempt lines, national rates, customs service fees and excise are not applied. Saudi Arabia charges more than 5 % on many lines.
- UK: only percentage duties are computed. Trade remedy measures are flagged, not added. The exchange rate is the ECB rate, not HMRC's monthly rate.
- US: the Section 301 list duties are not included unless you give **US Section 301 duty (%)**. The harbor maintenance fee is not included for informal sea entries (USD 2,500 or less). Section 232 duties, anti-dumping and countervailing duties and Section 301 exclusions are flagged, not computed. State sales tax is not computed.
- Alcohol, tobacco, nicotine, vapes and the GCC's excise drinks are not computed: such rows are skipped (`excise-goods`) and not charged.
- A product is computed once per run for each quantity and destination; repeats are skipped as `duplicate` and not charged. **Maximum products** counts distinct offers, so repeated rows of one offer (one row per SKU) do not use it up.
- If the ECB rates cannot be read, no row can be computed: the run ends as failed and nothing is charged for rows.
- The AliExpress market check reads what AliExpress shows to a visitor without an account, in the currency it picks for the request; new-user deal prices are left out of the median. A row says so when AliExpress priced for another country than the destination, or named none and showed another currency. A blocked or failed check is shown in the row and does not stop it.

### FAQ

#### Does it load 1688?

No. The Actor never asks 1688 for a page. It works only on the rows you give it, from your own scraper run or your CSV, and asks four public sources only: the ECB reference rates, the UK Trade Tariff, the US Harmonized Tariff Schedule and AliExpress search pages. The pages it loads fetch their own scripts and data from their own hosts; the run summary lists every host outside the four that they reached (`otherHosts`).

#### Is this a customs ruling?

No. Every figure is an estimate built from public tariff data, reference exchange rates and the assumptions listed in the row. Customs decides the classification, the value, the origin and the rates at entry. Ask a licensed customs broker before you buy, price or declare.

#### Which exchange rate is used?

The ECB euro reference rates of the day, from the [ECB's reference rates page](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html), as cross rates for CNY, USD and GBP, and the published pegs for the Gulf currencies. Customs use their own rates (the UK uses HMRC's monthly rates), so every row carries the flag `FX_NOT_CUSTOMS_RATE`. The row gives the date and the rates in `exchangeRates`.

#### Why is freight 0 on my rows?

You gave no freight rate. The Actor does not guess one: the row says `FREIGHT_NOT_INCLUDED`. Give your forwarder's **Air freight rate** (USD per kg) or **Sea freight rate** (USD per W/M); air freight then also needs the unit weight in your rows.

#### Why was a row skipped, and do I pay for it?

You do not pay for it. The run summary lists the reason in `skippedRows`: for example no CNY price, no weight while a freight rate is set, no HS code for the UK or the US, a tariff lookup that failed, excise goods or a duplicate. Fix the row and run it again.

#### My UK or US rows were skipped as hs-code-missing. What now?

The UK and US duties depend on the national tariff code, so a row needs one. The run summary gives up to 3 suggested codes for each such row, marked "suggested, verify". Put the right code in your rows or in **HS code**, or switch on **Compute UK and US rows with a suggested code** to use the top suggestion; those figures are then flagged `SUGGESTED_HS_CODE`. You can look codes up in the [UK Trade Tariff](https://www.trade-tariff.service.gov.uk/) and the [US Harmonized Tariff Schedule](https://hts.usitc.gov/).

#### Can I get the import VAT back?

VAT-registered importers usually can, which is why every row also gives the landed cost without VAT. In the United Arab Emirates import VAT is accounted for by reverse charge, and in Saudi Arabia only the importer of record can deduct it. Ask your tax adviser.

#### Which 1688 scrapers does it work with?

Any whose dataset has a CNY price per row. The fields of the common 1688 scrapers on the Apify Store are recognised by their names (price tiers, price range, MOQ, weight, offer ID, English title). For other names, add **Column mapping** entries such as `unitWeightKg=shipping.weightKg`. The run summary (`mapping`) shows which fields of your rows were used.

#### Can I run it after every scraper run?

Yes: add it as an integration of your 1688 scraper with the input `{"datasetId": "{{resource.defaultDatasetId}}"}` and your destination (see "How to use"). Or save your input as a task and run it on a schedule.

#### Why does the market check say blocked or few-results?

`blocked`: AliExpress showed a block or a verification page, which the Actor does not try to pass. `few-results`: fewer than 10 regular-price results matched the keyword, so the median says little. The landed cost of the row is computed either way. A short English title or a **Search term column** gives better keywords.

### Feedback

Tell us which destination, cost line or column to add next in the **Feedback for the developer** input field, or open an issue in the **Issues** tab. Feedback is saved with the run summary.

# Changelog

This Actor's version history is a separate document: https://apify.com/sourcing-data-studio/1688-landed-cost-api/changelog.md

# Actor input Schema

## `datasetId` (type: `string`):

The dataset of a 1688 scraper run. Pick a named dataset from the list, or paste the dataset ID of your 1688 scraper run (17 letters and digits, on the run's Storage tab): the list shows named datasets only, and a scraper run's dataset has no name. username~dataset-name works too. The Actor only reads it: it never writes to it and never loads a 1688 page. The usual column names of 1688 scrapers are recognised; Column mapping covers the rest. To compute landed costs after every run of your scraper, add an integration to the scraper (its Integrations tab, then this Actor) with the input {"datasetId": "{{resource.defaultDatasetId}}"}. For AI agents: pass the dataset ID as a string, or use productsCsv when you have the rows as text.

## `productsCsv` (type: `string`):

Your product rows as CSV text, one product per line, with the column names on the first line. Columns the Actor reads include titleEn (English title), title, priceCny (unit price in CNY), priceMinCny and priceMaxCny (a price range, priced at the maximum), moq, unitWeightKg, unitsPerCarton, cartonLengthCm, cartonWidthCm, cartonHeightCm, hsCode, domesticShippingCny, offerId and supplierName. Comma, semicolon or tab separated; put a cell that holds the separator in double quotes. Prices are read in CNY only. You can give a dataset and CSV rows together: the dataset is read first. At most 5,000,000 characters.

## `destination` (type: `string`):

Country the goods are imported into: Bahrain (BH, the default), Saudi Arabia (SA), United Arab Emirates (AE), Oman (OM), Qatar (QA), Kuwait (KW), United Kingdom (GB) or United States (US). Every amount of a row is in that country's currency. UK and US rows need an HS code (in the row or in HS code below); GCC rows without one get the 5 % GCC general rate.

## `quantity` (type: `integer`):

Units to cost for every product, for example 500. Leave empty to use each row's minimum order quantity (MOQ), or the minimum of its first price tier when that is higher. A quantity below it is raised to it (flag QTY_RAISED_TO_MOQ). The unit price is the price tier with the largest minimum quantity at or below this quantity.

## `maxItems` (type: `integer`):

Maximum number of distinct products (offers) to read and compute in this run, at most 2,000. Repeated rows of one offer (one row per SKU) count once and are saved once. You pay only for the rows saved to the dataset: rows that are skipped (no price, no HS code for the UK or the US, a failed tariff lookup, a duplicate, excise goods) are free and are listed in the run summary. For AI agents: 10 is enough for a test.

## `shippingMode` (type: `string`):

airExpress (courier: the chargeable weight is the larger of the actual weight and the volume / 5000, rounded up to 0.5 kg), airCargo (volume / 6000) or sea (LCL: priced per W/M, the larger of cubic metres and tonnes, at least 1).

## `freightRatePerKg` (type: `number`):

Your air freight rate in USD per chargeable kg, for example 6.5. Used with air express and air cargo. Without it freight is 0 and the row is flagged FREIGHT_NOT_INCLUDED: the Actor never invents a freight rate. With it, a row needs a unit weight (unitWeightKg); a row without one is skipped and not charged. Carton sizes, when the row has them, add the volumetric weight.

## `seaFreightRatePerCbm` (type: `number`):

Your sea freight (LCL) rate in USD per W/M (a cubic metre or a tonne, whichever is larger, at least 1), for example 95. Used with sea freight. Without it freight is 0 and the row is flagged FREIGHT_NOT_INCLUDED.

## `freightMinimumUsd` (type: `number`):

Minimum freight charge of your forwarder for each product row, in USD, for example 50. The freight of a row is never below it. 0 means no minimum.

## `chinaShippingCny` (type: `number`):

Shipping inside China, from the supplier to your forwarder, in CNY for each product row (the whole order line), for example 30. Used for every row that has no value of its own: a domesticShippingCny value in the row wins. A row with neither counts 0 and is flagged DOMESTIC_SHIPPING_MISSING.

## `insurancePercent` (type: `number`):

Cargo insurance in percent of the goods, the China shipping and the freight, for example 0.5. Leave empty for 0.5 % (flag INSURANCE_ASSUMED).

## `sourcingFeePercent` (type: `number`):

Fee of a sourcing agent in percent of the goods value, for example 5. It is added to the landed total and is part of no value that duty is charged on. Default 0.

## `paymentFxMarkupPercent` (type: `number`):

What your bank or payment service adds to the exchange rate when you pay in CNY, in percent, for example 2. It raises the cost of the goods and of the China shipping in the landed total; customs values, duty, VAT and fees use the ECB cross rate without it. Default 0: the ECB cross rate as it is.

## `sellPricePerUnit` (type: `number`):

The price a buyer pays you per unit, in the destination currency, VAT included where the destination has VAT, for example 2.5 (BHD). With it every row gets profitPerUnit and marginPercent.

## `marketplaceFeePercent` (type: `number`):

Marketplace or payment fee in percent of the sell price without VAT, for example 15. Used with Sell price per unit. Default 0.

## `fixedFeePerUnit` (type: `number`):

Fixed fee per unit sold, in the destination currency, for example a fulfilment fee of 0.4. Used with Sell price per unit. Default 0.

## `hsCode` (type: `string`):

HS or national tariff code for every row that has none of its own: 6, 8 or 10 digits, dots allowed (6402.99.98.00). A code in the row wins. UK: the 10-digit commodity code. US: the HTS code. GCC: optional; without a code the 5 % GCC general rate applies (flag HS_MISSING_GCC_GENERAL_RATE).

## `computeWithSuggestedCode` (type: `boolean`):

UK and US only. A row without an HS code is skipped and not charged, and the run summary gives up to 3 codes suggested by a search of its English title, each marked 'suggested, verify'. Switch this on to compute such rows with the top suggestion instead: the figures that depend on it get the basis suggested-code and the flag SUGGESTED_HS_CODE.

## `shipmentType` (type: `string`):

commercial (the default: an import by a business) or personal. GCC low-value thresholds, which waive the duty on small consignments, apply to personal shipments only; VAT is still due.

## `saudiDutyPercent` (type: `number`):

Saudi Arabia only: the duty rate in percent to use instead of the 5 % GCC general rate, for example 12. Saudi Arabia charges more than 5 % on many tariff lines, and the Actor does not check the line (flag KSA_RATE_MAY_EXCEED_5).

## `us301Percent` (type: `number`):

US only: the Section 301 list duty on goods from China in percent, for example 25 (Lists 1 to 3) or 7.5 (List 4A), applied to every US row of the run. This version has no verified table of the codes each Section 301 list covers, so without this field the list duties are left out and every US row is flagged US_301_NOT_INCLUDED. The 12.5 % forced-labour Section 301 duty (9903.05.31) is computed either way.

## `ukFirstDestinationCostGbp` (type: `number`):

UK only: costs in GBP from the UK border to the first destination in the UK, for example delivery to your warehouse, for each product row. They go into the import VAT base and the landed total. Default 0.

## `ukAirFreightSharePercent` (type: `number`):

UK only: the share of the air freight that goes into the customs value, 0 to 100. Default 100, all of it, which is the conservative choice. The part left out still goes into the VAT base.

## `usExcludeDomesticShipping` (type: `boolean`):

US only: leave the shipping inside China out of the dutiable value, as 19 CFR 152.103(a)(5)(i) allows when its conditions are met. Off by default: the dutiable value includes it, which is the conservative choice.

## `usConsolidatedEntry` (type: `boolean`):

US only: treat all US rows of the run as one customs entry, so the merchandise processing fee (MPF) is worked out once on their summed value and shared by value. Off by default: each row is its own entry (flag MPF_PER_ENTRY).

## `marketCheck` (type: `boolean`):

Look up each product's keyword on AliExpress and add the median, lowest and top-selling price and the margin against your landed cost per unit. The keyword comes from the English title or from the Search term column. A failed or blocked check is shown in the row and does not stop it. Default on.

## `maxMarketChecks` (type: `integer`):

At most this many distinct keywords are looked up on AliExpress in one run, 1 to 50 (default 10). Each takes about 10 seconds. Rows whose keyword is not looked up get the market status not-run. Keywords of UK and US rows without an HS code (skipped, free) are not looked up, nor more than your maximum cost per run pays rows for (plus 5).

## `searchTermColumn` (type: `string`):

Name of the column (or dotted path, such as product.keyword) of your rows that holds the AliExpress search term. Leave empty to use the English title.

## `columnMapping` (type: `array`):

Only for rows the Actor does not recognise: one target=path entry per line, where path is a column name or a dotted path of your rows, for example unitWeightKg=shipping.weightKg. Targets: offerId, offerUrl, title, titleEn, supplierName, tiers, priceMinCny, priceMaxCny, moq, unitWeightKg, unitsPerCarton, cartonLengthCm, cartonWidthCm, cartonHeightCm, hsCode, domesticShippingCny, searchTerm. An entry wins over the column the Actor would find itself.

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

Proxy for the requests to the four sources: the ECB, the UK Trade Tariff, the US Harmonized Tariff Schedule and AliExpress. No proxy is needed, and the default is none. A proxy is never used to get around a refusal. The Actor sends no request to 1688.

## `maxRequestRetries` (type: `integer`):

How many times a failed request is asked for again, with a growing wait between attempts. A request that a source refuses is not asked for again. A row whose tariff lookup failed is skipped and never charged. The default of 3 fits almost every run.

## `debugLog` (type: `boolean`):

Print detailed debug messages to the run log. Leave off unless you are investigating a problem; it does not change the results.

## `feedback` (type: `string`):

Optional. Tell us which destination, cost line or column you need next, or what went wrong. It is saved with the run summary and does not change the results. Do not include personal data. AI agents may also use this field to report problems.

## Actor input object example

```json
{
  "productsCsv": "titleEn,priceCny,moq,unitWeightKg\nSilicone phone case,2.80,100,0.05\nStainless steel water bottle 500 ml,18.50,50,0.32\nLED desk lamp with USB charging,35.00,20,0.90\nCotton tote bag,4.20,200,0.12\nYoga mat 6 mm,22.00,30,1.10\nCeramic coffee mug 350 ml,6.80,72,0.38\n",
  "destination": "BH",
  "maxItems": 10,
  "shippingMode": "airExpress",
  "freightMinimumUsd": 0,
  "sourcingFeePercent": 0,
  "paymentFxMarkupPercent": 0,
  "marketplaceFeePercent": 0,
  "fixedFeePerUnit": 0,
  "computeWithSuggestedCode": false,
  "shipmentType": "commercial",
  "ukFirstDestinationCostGbp": 0,
  "ukAirFreightSharePercent": 100,
  "usExcludeDomesticShipping": false,
  "usConsolidatedEntry": false,
  "marketCheck": true,
  "maxMarketChecks": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxRequestRetries": 3,
  "debugLog": false
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "productsCsv": `titleEn,priceCny,moq,unitWeightKg
Silicone phone case,2.80,100,0.05
Stainless steel water bottle 500 ml,18.50,50,0.32
LED desk lamp with USB charging,35.00,20,0.90
Cotton tote bag,4.20,200,0.12
Yoga mat 6 mm,22.00,30,1.10
Ceramic coffee mug 350 ml,6.80,72,0.38`,
    "destination": "BH",
    "maxItems": 10,
    "marketCheck": true,
    "maxMarketChecks": 1,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sourcing-data-studio/1688-landed-cost-api").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 = {
    "productsCsv": """titleEn,priceCny,moq,unitWeightKg
Silicone phone case,2.80,100,0.05
Stainless steel water bottle 500 ml,18.50,50,0.32
LED desk lamp with USB charging,35.00,20,0.90
Cotton tote bag,4.20,200,0.12
Yoga mat 6 mm,22.00,30,1.10
Ceramic coffee mug 350 ml,6.80,72,0.38
""",
    "destination": "BH",
    "maxItems": 10,
    "marketCheck": True,
    "maxMarketChecks": 1,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("sourcing-data-studio/1688-landed-cost-api").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 '{
  "productsCsv": "titleEn,priceCny,moq,unitWeightKg\\nSilicone phone case,2.80,100,0.05\\nStainless steel water bottle 500 ml,18.50,50,0.32\\nLED desk lamp with USB charging,35.00,20,0.90\\nCotton tote bag,4.20,200,0.12\\nYoga mat 6 mm,22.00,30,1.10\\nCeramic coffee mug 350 ml,6.80,72,0.38\\n",
  "destination": "BH",
  "maxItems": 10,
  "marketCheck": true,
  "maxMarketChecks": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call sourcing-data-studio/1688-landed-cost-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sourcing-data-studio/1688-landed-cost-api"
        }
    }
}
```

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/SjXocX8R2HsyfuNml/builds/kawAjGFTLnKxTmR97/openapi.json
