Skip to main content

hscode

PyPI Python versions License: MIT CI

EU customs tariff (TARIC) API client for Python: classify products into HS / CN / TARIC codes and get import duties.

A small client for the hscode.info HS code API. It covers HS code classification, HS code lookup and import duty for the EU Combined Nomenclature.

  • German, English and French descriptions. Queries in any language: Zolltarifnummer, nomenclature combinée, tarif douanier.
  • Zero dependencies. It uses the standard library only. Python 3.9 or newer.
  • Typed. Responses are TypedDicts and the package ships py.typed.
  • Built for data teams: classify a pandas column or a product export in chunks of 25.

Install

pip install hscode

Get a key on your hscode.info account. The free plan has 30 AI units and 100 lookups a day, with no credit card. Paid plans start at $19 a month. See pricing.

Quick start

from hscode import Client

client = Client(api_key="...")  # or set HSCODE_KEY
result = client.classify("cotton t-shirt", mode="accurate")
top = result["results"][0]
print(top["goods_code"], top["description"])

The CLI ships with the npm package, not with this one: npx @hscode/sdk classify "cotton t-shirt". See the TypeScript SDK and CLI.

Reference

Client(api_key=None, base_url="https://hscode.info", timeout=60, opener=None)

Argument Default
api_key the HSCODE_KEY environment variable
base_url https://hscode.info
timeout 60 seconds
opener urllib.request.urlopen. Pass your own callable (request, timeout=...) to fake the network in tests.

lang is "de", "en" or "fr" and defaults to "en". mode is "fast" (Quick, 1 AI unit) or "accurate" (Precise, 5 units, adds confidence and reasoning). When you omit year, the client looks up the latest snapshot once and reuses it.

Goods codes may contain spaces or dots. The client strips them and checks for 10 digits before it sends a request.

classify

res = client.classify("frozen shrimp, peeled", mode="accurate", lang="de")
print(res["results"][0]["goods_code"], res["question"], res["disclaimer"])

POST /api/v1/classify. Each result has goods_code, description, path, score, confidence, reasoning and duties.

classify_batch

res = client.classify_batch(["cotton t-shirt", {"id": "SKU-2", "text": "steel nails"}])
for item in res["items"]:
    print(item["id"], item["results"][0]["goods_code"] if item["results"] else item["error"])

POST /api/v1/classify/batch. One to 25 items per call. An item is a string or a dict with text and an optional id. A string gets its list position as id. An item that fails has error set.

lookup

detail = client.lookup("6109 10 00 10", year="2025", lang="fr")

GET /api/v1/{lang}/{year}/codes/{code}. Returns the description, hierarchy, duties and signals such as quotas and restrictions. Pass history=True to add the duties of every yearly snapshot.

history

detail = client.history("6109100010")
for snapshot in detail["history"]:
    print(snapshot["year"], len(snapshot["duties"]))

Same as lookup with history=True. Use it for duty history by year.

hits = client.search("t-shirt")["items"]

GET /api/v1/{lang}/{year}/search. Matches codes by words.

duties

duties = client.duties("6109100010")["items"]

GET /api/v1/{year}/duties/{code}. Import duty per origin, with legal base and measure type. Use it as the input of a customs duty calculator.

chapters and chapter

chapters = client.chapters()["items"]
rows = client.chapter("61")["items"]

The nomenclature chapters, and the rows of one 2-digit chapter.

snapshots

snapshots = client.snapshots()
print(snapshots["latest"])

The yearly TARIC snapshots from 2016 to 2026.

Classify a pandas column

classify_batch takes 25 items at most. Split the column in chunks of 25.

import pandas as pd
from hscode import Client

client = Client()
df = pd.read_csv("products.csv")
texts = df["description"].astype(str).tolist()

codes = []
for start in range(0, len(texts), 25):
    chunk = texts[start : start + 25]
    for item in client.classify_batch(chunk)["items"]:
        top = item["results"][0] if item["results"] else None
        codes.append(top["goods_code"] if top else None)

df["hs_code"] = codes
df.to_csv("classified.csv", index=False)

pandas is only used in this example. The package does not depend on it.

Errors

Every failure raises HscodeError.

from hscode import Client, HscodeError

client = Client()
try:
    client.lookup("1234")
except HscodeError as e:
    print(e.status, e.code, e.message)
Field Meaning
status HTTP status (400, 401, 404, 429, 503). 0 for errors raised before a response.
code The API error string, or invalid_request, missing_api_key and network_error for local errors.
message A readable message. str(e) returns it.

On HTTP 429 your plan quota is used up. See pricing.

Accuracy

On 1,000 real EU Binding Tariff Information (BTI, also called EBTI) rulings sampled from a pool of about 120,000, covering 94 chapters, the first suggestion is right at 2 digits (chapter) in 91 %, at 4 digits (heading) in 87.9 % and at 6 digits (subheading) in 84.7 %. As of October 2026, Precise mode. Details: accuracy.

Advisory only. Only a BTI from customs is legally binding.

For AI agents

The same tools are available as an MCP server at hscode.info/mcp: classify, lookup_code, search_codes and duty_history. Setup is on the developers page. See also llms.txt.

MIT license.

Metadata

Release files for hscode 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hscode 0.1.1
File Size Uploaded Provenance Actions
hscode-0.1.1.tar.gz 9.9 kB Without provenance Details for hscode-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for hscode 0.1.1
File Interpreter ABI Platform Actions
hscode-0.1.1-py3-none-any.whl Python 3 none any Details for hscode-0.1.1-py3-none-any.whl

Total release size: 19.2 kB

Release files / hscode-0.1.1.tar.gz

Download URL hscode-0.1.1.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2b8f0e45f3155ae2036e3a203b8c723eaeccf63315fd5242f93a0a51a44c6785
BLAKE2b-256 checksum
How to use checksums
490d3d38d67a53121ce43fc47a99565d9223cac4ebd72bfa20db1d1f18ebf61f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / hscode-0.1.1-py3-none-any.whl

Download URL hscode-0.1.1-py3-none-any.whl
Size 9.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b35079b49a4edd6d378050acfa46bab5f9977fc2ddff53bc16d2cbf9189b3aa6
BLAKE2b-256 checksum
How to use checksums
a2038841a8ce317f6d7f3688a62287a9f74d61c36c458309a7c86c3f2f52765f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for hscode 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page