# Import Duty Lookup – EU TARIC & UK Tariff by Commodity Code (`rowfeed/import-duty-lookup`) Actor

Official import duty per commodity code and origin from EU TARIC and the UK Trade Tariff: third-country duty, preferences, quotas, VAT and the EU's €3 low-value consignment duty. Validates codes.

- **URL**: https://apify.com/rowfeed/import-duty-lookup.md
- **Developed by:** [Rowfeed](https://apify.com/rowfeed) (community)
- **Categories:** E-commerce, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 lookups

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

## Import Duty Lookup – EU TARIC & UK Tariff by Code

Get every official customs measure for a commodity code and origin country, straight from EU TARIC and the UK Trade Tariff: third-country duty, tariff preferences, quotas, VAT, additional duties, restrictions and the EU's new €3-per-item low-value consignment duty.
Built for e-commerce sellers and 3PLs shipping into the EU or UK, customs brokers' automations, and AI agents that need a real duty answer instead of a guess.
Reliable because it reads two official government sources live on every run - the European Commission's own TARIC consultation service and the UK's Trade Tariff API - and returns their raw measures, never a made-up "landed cost" number.

### What you get

- **Every applicable measure, not one number** - third-country duty, tariff preference, preferential quota, VAT (UK), suspensions, restrictions and more, each with its rate, validity dates and legal basis (regulation reference), exactly as the source published it.
- **Code validation built in** - an unknown commodity code comes back as `code_valid: false` instead of a crash; for the UK source you also get up to 20 valid codes under the same 4-digit heading as a suggestion.
- **The EU €3 low-value duty read live, not hardcoded** - since 1 July 2026 consignments up to €150 carry a flat €3 customs duty per tariff classification. This Actor reads it straight from TARIC's own "Low-value consignment customs duty" measure, with its real validity window, so it tracks the source instead of going stale.

### Sample row

One EU lookup for a T-shirt (6109100010) from China, from a local run:

```json
{
  "destination": "EU",
  "code": "6109100010",
  "code_normalised": "6109100010",
  "code_valid": true,
  "origin": "CN",
  "third_country_duty": "12.00%",
  "preferential_duty": null,
  "preferential_quota": [],
  "vat": null,
  "vat_note": "VAT is set per member state",
  "low_value_consignment_duty_eur": 3.0,
  "low_value_duty_valid_until": "2026-10-31",
  "measures": [
    { "type": "Third country duty", "geographical_area": "ERGA OMNES (ERGA OMNES 1011)", "duty": "12.00%", "start_date": "1997-01-01", "end_date": null, "legal_basis": ["R1734/96"], "footnotes": [], "has_conditions": false },
    { "type": "Low-value consignment customs duty", "geographical_area": "ERGA OMNES (ERGA OMNES 1011)", "duty": "3.00 EUR", "start_date": "2026-07-01", "end_date": "2026-10-31", "legal_basis": ["R0382/26"], "footnotes": ["TM01066"], "has_conditions": false },
    { "type": "Suspension - goods for certain categories of ships, boats and other vessels and for drilling or production platforms", "geographical_area": "ERGA OMNES (ERGA OMNES 1011)", "duty": "0%", "start_date": "2016-07-01", "end_date": null, "legal_basis": ["R2658/87"], "footnotes": ["EU003", "TM510"], "has_conditions": true },
    { "type": "Supplementary unit", "geographical_area": "ERGA OMNES (ERGA OMNES 1011)", "duty": "p/st", "start_date": "2008-01-01", "end_date": null, "legal_basis": ["R2658/87"], "footnotes": [], "has_conditions": false }
  ],
  "source_url": "https://ec.europa.eu/taxation_customs/dds2/taric/measures.jsp?Lang=en&Taric=6109100010&Area=CN&Expand=true&SimDate=20260923",
  "fetched_at": "2026-09-23T18:11:38+00:00"
}
```

A GB lookup for the same code adds `vat` (e.g. `"20.00%"`) and drops `low_value_consignment_duty_eur` (UK-only rows never carry it); an unknown code returns `code_valid: false` with empty `measures` and, on the UK side, a `suggestions` list of valid neighbouring codes.

### Input

| Input | Default | What it does |
|---|---|---|
| `items` | 3 sample items (T-shirt/CN, laptop/US, watch/CH) | Objects with `code` (6-10 digits, spaces/dots stripped), `origin` (ISO2), and optional `description`, `value`, `quantity` echoed back on the row. |
| `codes` + `origin` | `[]` / `""` | Shortcut: a flat list of codes plus one origin, expanded into `items`. Used instead of `items`, not in addition to it. |
| `destination` | `EU` | `EU` (TARIC), `GB` (UK Trade Tariff) or `BOTH` (one row per item per destination). |
| `date` | today (UTC) | `YYYY-MM-DD`. Only affects the EU TARIC lookup (`SimDate`); the UK source always answers as of today. |
| `maxItems` | `100` | Cap on how many items (1-500) are looked up, before the destination fan-out. |

### Pricing

Pay per event, no subscription: **$3 per 1,000 lookups** and **$0.001 per run start**. One lookup = one (item, destination) pair the source actually answered - a `code_valid: false` row is charged too, because "is this code valid" is data you paid to find out. A genuine source outage never gets charged; it comes back as an uncharged error row instead.

### The EU €3 low-value duty

From 1 July 2026, the European Commission's low-value consignment duty applies a flat customs duty per tariff classification on consignments up to €150: the Commission has said the duty "will apply per item, based on tariff classification and not quantity." This Actor never hardcodes that rate or its dates - it reads them live from TARIC's own "Low-value consignment customs duty" measure (`low_value_consignment_duty_eur`, `low_value_duty_valid_until`), so a rate change or an extended validity window shows up on the very next run. After a batch of EU lookups, the run's `STATS` record also carries `eu_low_value_summary`: the number of distinct classifications in the batch that carry the duty, and what that would cost per consignment under €150 - an aid for planning a shipment, not a customs ruling.

### What this is not

This Actor is not a customs ruling and not a landed-cost calculator. It returns the measures a code and origin actually carry, exactly as EU TARIC and the UK Trade Tariff publish them - it never sums them into one "final price," because a wrong single number is a liability and the measures are the truth. Always confirm classification and duty with a licensed customs broker before you rely on it for a real shipment. Not affiliated with the European Commission, DG TAXUD or HMRC.

### Details

- **Sources**: EU TARIC (`ec.europa.eu/taxation_customs/dds2/taric`, DG TAXUD, reused under Commission Decision 2011/833/EU) and the UK's official Trade Tariff API (`trade-tariff.service.gov.uk`, Open Government Licence). No authentication, no proxies, no browser.
- **Reliability**: 429 and 5xx responses retry with exponential backoff (5 tries), a 200 without the expected data counts as a failure, and one bad code never stops the run - it becomes an error row and the rest continues. A run fails only when it produced no lookups *and* hit errors or invalid input; items with nothing wrong simply succeed.
- **Run stats**: the `STATS` record in the run's key-value store holds lookups, invalid input rows, error rows, request and per-category error counts, plus `eu_low_value_summary` for EU runs.
- **Output**: one dataset row per (item, destination), with every measure the source returned nested under `measures`. Export as JSON, CSV or Excel, fetch through the Apify API, or schedule runs and pipe them into your own pricing or compliance pipeline. Eligible for agentic use via Apify's MCP server.

# Actor input Schema

## `items` (type: `array`):

Commodity codes to look up. Each item needs a `code` (6-10 digits, spaces/dots are stripped, e.g. "6109 10 00 10") and an `origin` (ISO2 country of origin, e.g. "CN"). Optional `description`, `value` and `quantity` are echoed back on the row unchanged.

## `codes` (type: `array`):

Shortcut for a single origin: a plain list of commodity codes, combined with the `origin` field below into items. Ignored if empty. Adds to, rather than replaces, `items`.

## `origin` (type: `string`):

ISO2 country of origin used only with the `codes` shortcut above, e.g. "CN".

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

Which customs territory to look up measures for: EU (TARIC), GB (UK Trade Tariff) or BOTH (one row per item per destination).

## `date` (type: `string`):

Measures in force on this date, YYYY-MM-DD. Only affects the EU TARIC lookup (SimDate). Defaults to today (UTC).

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

Look up at most this many items from the (expanded) list, before the destination fan-out.

## Actor input object example

```json
{
  "items": [
    {
      "code": "6109100010",
      "origin": "CN"
    },
    {
      "code": "8471300000",
      "origin": "US"
    },
    {
      "code": "9102110000",
      "origin": "CH"
    }
  ],
  "codes": [
    "6109100010",
    "8471300000"
  ],
  "origin": "",
  "destination": "EU",
  "date": "",
  "maxItems": 100
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("rowfeed/import-duty-lookup").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("rowfeed/import-duty-lookup").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 '{}' |
apify call rowfeed/import-duty-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rowfeed/import-duty-lookup"
        }
    }
}
```

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/TG6NwcE5EvjA0Zsby/builds/UxCdU2FnsTXbO3rfZ/openapi.json
