Guide · Node.js · SDK · REST API

HS Code Validation in Node.js — International Trade Classification

Every product crossing an international border needs a Harmonized System (HS) code. Get the code wrong and you face the wrong tariff, overpaid duties, or customs penalties. Here's how to validate HS codes properly in Node.js — including chapter, heading, and subheading lookups.

1. What is an HS code?

The Harmonized System (HS) is a standardised numerical classification for traded products, maintained by the World Customs Organization (WCO). Introduced in 1988, it is used by more than 200 countries and economies as the foundation for their customs tariffs and trade statistics.

The system organises roughly 5,000 commodity groups into a logical hierarchy. Every item that crosses a border — from coffee beans to semiconductors — is assigned an HS code that determines the applicable tariff rate, trade regulations, and statistical reporting category.

HS codes are mandatory for international trade. They appear on commercial invoices, customs declarations, bills of lading, and certificates of origin. Without a valid HS code, goods cannot clear customs in any country that is party to the HS Convention.

The WCO revises the HS nomenclature every five years (most recently in 2022) to reflect changes in technology, trade patterns, and environmental concerns. This means HS codes can become obsolete or be reclassified, making ongoing validation essential.


2. HS code structure

HS codes are organised into three hierarchical levels. The international standard covers the first six digits. Individual countries then add their own national digits (typically bringing the total to 8–10 digits) for finer classification and tariff determination.

847150
84 = chapter71 = heading50 = subheading
LevelDigitsCountExampleDescription
Chapter297 chapters84Nuclear reactors, boilers, machinery...
Heading4~1,200 headings8471Automatic data-processing machines
Subheading6~5,000 subheadings847150Processing units (other than combined)
ℹ️The internationally standardised HS code is always 6 digits or fewer. When you see 8-digit or 10-digit codes, those include national extensions. For example, the US uses 10-digit HTS (Harmonized Tariff Schedule) codes, and the EU uses 8-digit CN (Combined Nomenclature) codes. The IsValid API validates the international 2, 4, or 6-digit HS codes.

3. Why HS code validation matters

Correct tariff classification

The HS code directly determines the tariff rate applied to imported goods. A wrong code means paying the wrong duty — either overpaying (reducing margins) or underpaying (risking back-duties, interest, and penalties when audited by customs authorities).

Customs clearance speed

Invalid or unrecognised HS codes trigger manual review at the border. This can delay clearance by days, incurring demurrage charges, warehouse fees, and disrupting just-in-time supply chains. Validating codes before shipment prevents these delays.

Trade compliance

Certain HS codes are subject to export controls, sanctions, anti-dumping duties, or preferential trade agreements. Misclassification can lead to inadvertent violations of trade regulations — a serious legal and reputational risk for any business involved in international trade.

Data quality in trade platforms

ERP systems, customs brokers, and logistics platforms process thousands of product classifications daily. Validating HS codes at the point of entry — in product catalogs, purchase orders, or customs forms — catches errors before they propagate through the supply chain.


4. The right solution

The IsValid HS Code API provides two endpoints: a validate endpoint that checks whether a 2, 4, or 6-digit HS code is valid and returns its description, and a list endpoint that returns all codes at a given level or within a specific chapter.

3
Levels
chapter / heading / subheading
~5,000
Commodities
WCO nomenclature
100/day
Free tier
no credit card

Get your free API key at isvalid.dev. The free tier includes 100 calls per day — enough for most development and low-volume production use.

Full parameter reference and response schema: HS Code Validation API docs →


5. Node.js code example

Using the isvalid-sdk Node.js SDK or the built-in fetch API. Install with npm install isvalid-sdk.

// hs-validator.mjs
import { IsValid } from "isvalid-sdk";

const iv = new IsValid({ apiKey: process.env.ISVALID_API_KEY });

// ── Validate a heading (4-digit HS code) ────────────────────────────────

const result = await iv.hsCode("8471");

if (!result.valid) {
  console.log("Invalid HS code");
} else {
  console.log(`Valid HS code — ${result.level}`);
  console.log(`Code: ${result.code}`);
  console.log(`Description: ${result.description}`);
  console.log(`Formatted: ${result.formatted}`);
  console.log(`Chapter: ${result.chapter.code} — ${result.chapter.description}`);
  // → Valid HS code — heading
  // → Code: 8471
  // → Description: Automatic data-processing machines and units thereof
  // → Formatted: 84.71
  // → Chapter: 84 — Nuclear reactors, boilers, machinery and mechanical appliances; parts thereof
}

// ── Validate a subheading (6-digit HS code) ─────────────────────────────

const sub = await iv.hsCode("847150");
console.log(sub.description);
// → Processing units other than those of subheading 8471.41 or 8471.49

// ── Validate a chapter (2-digit HS code) ────────────────────────────────

const chapter = await iv.hsCode("84");
console.log(chapter.description);
// → Nuclear reactors, boilers, machinery and mechanical appliances; parts thereof

You can also list all HS codes at a given level or within a chapter:

// List all headings in chapter 84
const headings = await iv.hsCode.list({ chapter: "84", level: "heading" });

for (const h of headings) {
  console.log(`${h.code} — ${h.description}`);
}
// → 8401 — Nuclear reactors; fuel elements...
// → 8402 — Steam or other vapour generating boilers...
// → ...
// → 8471 — Automatic data-processing machines and units thereof
// → ...

In an Express application, you might use it to validate product classifications:

// app.mjs (Express)
import express from "express";
import { IsValid } from "isvalid-sdk";

const app = express();
app.use(express.json());

const iv = new IsValid({ apiKey: process.env.ISVALID_API_KEY });

app.post("/products", async (req, res) => {
  const { name, hsCode, origin, destination } = req.body;

  // Validate the HS code before saving the product
  const check = await iv.hsCode(hsCode);

  if (!check.valid) {
    return res.status(400).json({
      error: "Invalid HS code",
      hint: "Provide a 2, 4, or 6-digit HS code (e.g. 8471 or 847150)",
    });
  }

  // Use the validated data
  const product = await saveProduct({
    name,
    hsCode: check.code,
    hsDescription: check.description,
    hsLevel: check.level,
    hsFormatted: check.formatted,
    chapterCode: check.chapter.code,
    chapterDescription: check.chapter.description,
    origin,
    destination,
  });

  res.json({ success: true, product });
});

app.listen(3000);
Use the list endpoint to build HS code picker dropdowns in your UI. Fetch chapters first, then load headings for the selected chapter, then subheadings — giving users a guided classification experience.

6. cURL example

Validate a 4-digit heading:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/hs-code?value=8471"

Validate a 6-digit subheading:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/hs-code?value=847150"

Validate a 2-digit chapter:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/hs-code?value=84"

List all headings in chapter 84:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/hs-code/list?chapter=84&level=heading"

7. Understanding the response

Response for a chapter (2-digit code):

{
  "valid": true,
  "code": "84",
  "level": "chapter",
  "description": "Nuclear reactors, boilers, machinery and mechanical appliances; parts thereof",
  "formatted": "84"
}

Response for a heading (4-digit code):

{
  "valid": true,
  "code": "8471",
  "level": "heading",
  "description": "Automatic data-processing machines and units thereof",
  "formatted": "84.71",
  "chapter": {
    "code": "84",
    "description": "Nuclear reactors, boilers, machinery and mechanical appliances; parts thereof"
  }
}

Response for a subheading (6-digit code):

{
  "valid": true,
  "code": "847150",
  "level": "subheading",
  "description": "Processing units other than those of subheading 8471.41 or 8471.49",
  "formatted": "8471.50",
  "chapter": {
    "code": "84",
    "description": "Nuclear reactors, boilers, machinery and mechanical appliances; parts thereof"
  }
}

Invalid HS code:

{
  "valid": false
}
FieldTypeDescription
validbooleanWhether the HS code exists in the WCO nomenclature
codestringThe normalised HS code (2, 4, or 6 digits)
levelstringClassification level: "chapter", "heading", or "subheading"
descriptionstringOfficial WCO description of the commodity group
formattedstringDot-separated display format (e.g. "84.71" or "8471.50")
chapter.codestring2-digit chapter code (present for headings and subheadings)
chapter.descriptionstringDescription of the parent chapter
⚠️The chapter object is only present for heading and subheading codes. When validating a 2-digit chapter code, the response does not include a nested chapter object since the code itself is already at the chapter level.

8. Edge cases to handle

National extensions (HTS, CN, TARIC)

Countries extend the 6-digit HS code with national digits. The United States uses 10-digit HTS codes, the EU uses 8-digit CN codes (and 10-digit TARIC codes for trade measures). If your system stores these longer codes, extract the first 6 digits for HS validation and store the national extension separately.

// US HTS code: 8471.50.0150 (10 digits)
const htsCode = "8471500150";

// Extract the 6-digit international HS code
const hsCode = htsCode.slice(0, 6); // "847150"

const result = await iv.hsCode(hsCode);
// Validates against the international HS nomenclature

// Store both for customs purposes
const product = {
  hsCode: result.code,       // "847150" — international
  htsCode: htsCode,          // "8471500150" — US national
  description: result.description,
};

Chapter vs. heading validation

A valid 2-digit chapter code does not guarantee that a 4-digit heading within it exists. For example, chapter 84 is valid, but 8499 may not be a valid heading. Always validate at the specific level you need.

// Chapter 84 is valid
const chapter = await iv.hsCode("84");
console.log(chapter.valid); // true

// But not every 4-digit combination in chapter 84 is a valid heading
const invalid = await iv.hsCode("8499");
console.log(invalid.valid); // false

// Always validate the exact code, not just the chapter
const valid = await iv.hsCode("8471");
console.log(valid.valid); // true

Obsolete and reclassified codes

The WCO revises the HS nomenclature every five years. Codes that were valid in the 2017 edition may have been split, merged, or deleted in the 2022 edition. If your system stores historical HS codes, be aware that older codes may no longer validate against the current nomenclature. The API validates against the most recent HS edition. Consider storing the HS revision year alongside the code for audit purposes.

Input formatting

Users may enter HS codes with dots, spaces, or dashes (e.g. 84.71 or 8471.50). The API normalises input automatically — strip separators and pass the raw digits. The formatted field in the response gives you the canonical dot-separated display form.


9. Summary

Do not hardcode HS code tables — the WCO revises them every five years
Do not assume a valid chapter means all headings within it exist
Do not validate national extensions (8-10 digit codes) as international HS codes
Use the validate endpoint for instant HS code lookup with descriptions
Use the list endpoint to build cascading HS code pickers in your UI
Store the formatted code and chapter info alongside the raw code for reporting

See also

Validate HS codes instantly

Free tier includes 100 API calls per day. No credit card required. Validate any HS code and get descriptions, chapter info, and formatted display codes.