Developers ยท REST API ยท JSON
Free HS Code API โ Look up, search and classify HS codes in JSON. No API key, no sign-up.
The HS Code Atlas API is a free REST API for Harmonized System codes. Send an HS code, a product name or a description and get JSON back: the official description from HS 2022, the latest edition, where the code sits in the hierarchy, matching products and Brazil NCM codes. There is no API key, no account and no cost.
curl https://hscodeatlas.com/api/hs-code/0902/ Quick start
All endpoints live under https://hscodeatlas.com/api/ and work from any language. No headers or keys are needed. Keep the slash at the end of each path: without it you get a redirect, which curl only follows with -L.
curl "https://hscodeatlas.com/api/search/?q=laptop"// Node 18+, Deno, Bun or a serverless function
const res = await fetch('https://hscodeatlas.com/api/search/?q=laptop');
const { results } = await res.json();
console.log(results[0].code); // "847130"import requests
res = requests.get("https://hscodeatlas.com/api/search/", params={"q": "laptop"})
print(res.json()["results"][0]["code"]) # 847130 Try the API live
Pick an endpoint, enter a code or a product and send a real request. The response is exactly what your code receives.
{
"code": "0902",
"level": 4,
"description": "Tea",
"section": "II",
"parent": "09",
"slug": "tea",
"is_commodity": false,
"flags": {
"eudr": false,
"eutr": false,
"cbam": false
},
"children": [
{
"code": "090210",
"description": "Tea, green; (not fermented), in immediate packings of a content not exceeding 3kg",
"level": 6
},
{
"code": "090220",
"description": "Tea, green; (not fermented), in immediate packings of a content exceeding 3kg",
"level": 6
},
{
"code": "090230",
"description": "Tea, black; (fermented) and partly fermented tea, in immediate packings of a content not exceeding 3kg",
"level": 6
},
{
"code": "090240",
"description": "Tea, black; (fermented) and partly fermented tea, in immediate packings of a content exceeding 3kg",
"level": 6
}
]
} Endpoints 3
Look up a code you have, search by words or part of a code, or classify a product description. Search and classify return results in the same shape.
Look up an HS code
GET/api/hs-code/{code}/
Returns one HS code: its official description, HS section, parent code, EU regulatory flags and the codes one level below it. Works for 2-digit chapters, 4-digit headings and 6-digit subheadings. The example is the same data you see on the HS 0902 page.
Parameters
| Name | In | Description |
|---|---|---|
codeRequired | path | 2, 4 or 6 digits, with or without dots: 09, 0902, 090210 or 0902.10. |
Example
curl https://hscodeatlas.com/api/hs-code/0902/ {
"code": "0902",
"level": 4,
"description": "Tea",
"section": "II",
"parent": "09",
"slug": "tea",
"is_commodity": false,
"flags": {
"eudr": false,
"eutr": false,
"cbam": false
},
"children": [
{
"code": "090210",
"description": "Tea, green; (not fermented), in immediate packings of a content not exceeding 3kg",
"level": 6
},
{
"code": "090220",
"description": "Tea, green; (not fermented), in immediate packings of a content exceeding 3kg",
"level": 6
},
{
"code": "090230",
"description": "Tea, black; (fermented) and partly fermented tea, in immediate packings of a content not exceeding 3kg",
"level": 6
},
{
"code": "090240",
"description": "Tea, black; (fermented) and partly fermented tea, in immediate packings of a content exceeding 3kg",
"level": 6
}
]
} Response fields
| Field | Type | Description |
|---|---|---|
code | string | The HS code, digits only. |
level | number | 2 for a chapter, 4 for a heading, 6 for a subheading. |
description | string | Official HS 2022 description from the World Customs Organization. |
section | string | HS section in Roman numerals, such as "II". |
parent | string | null | The code one level up; null for chapters. |
slug | string | A readable slug made from the description. |
is_commodity | boolean | Reserved; always false. |
flags | object | eudr, eutr and cbam: true when the EU Deforestation Regulation, the EU Timber Regulation or the Carbon Border Adjustment Mechanism covers the code. |
children | array | Codes one level down, each with code, description and level. Empty for 6-digit codes. |
Anything other than a 2, 4 or 6-digit code returns 400; a code that doesn't exist returns 404 with {"error": "HS code not found"}.
Search HS codes and products
GET/api/search/?q={query}
Searches 10,000+ product names, every HS description and all Brazil NCM codes, and returns up to 8 results, best first. Products whose name has all your words come first, then HS descriptions, then results that match only some of the words. Send digits, with or without dots, to list the codes that start with them, such as 0902. A 7- or 8-digit Brazil NCM code returns the NCM codes and the HS subheading they belong to. The search boxes on this site use this endpoint.
Parameters
| Name | In | Description |
|---|---|---|
qRequired | query | A product name, a few words, or the first digits of a code. At least 2 characters; shorter queries return an empty list. |
Example
curl "https://hscodeatlas.com/api/search/?q=laptop" {
"results": [
{
"kind": "hs",
"code": "847130",
"description": "Automatic data processing machines; portable, weighing not more than 10kg, consisting of at least a central processing unit, a keyboard and a display",
"product_name": "Laptop",
"confidence": "high",
"url": "/hs-code/847130/"
},
{
"kind": "hs",
"code": "850760",
"description": "Electric accumulators; lithium-ion, including separators, whether or not rectangular (including square)",
"confidence": "medium",
"url": "/hs-code/850760/"
}
]
} Shortened to the first 2 results.
Response fields
| Field | Type | Description |
|---|---|---|
results | array | Up to 8 results, best first. Each one has the fields below. |
results[].kind | string | "hs" for an HS code, "ncm" for a Brazil NCM code. |
results[].code | string | The code, digits only. |
results[].description | string | Official description of the code (HS 2022, or the English translation of the NCM text). |
results[].product_name | string | The product that matched, when the match came from a product name. Not sent otherwise. |
results[].confidence | string | "high", "medium" or "low": how closely the code matched your words. |
results[].url | string | Path of the code's page on HS Code Atlas. |
No match is not an error: you get 200 with an empty results list. Search never calls the AI model, so it is fast enough for autocomplete.
Classify a product description
POST/api/classify/
Runs the same search as /api/search/ and answers with the single best code, its confidence and why it matched, plus the other candidates. When nothing in the catalogue matches, an AI model suggests a 6-digit code, and it is returned only if that code exists in HS 2022. Use search for autocomplete and classify when the user submits a description.
JSON body
| Name | In | Description |
|---|---|---|
queryRequired | body | Product description, at least 2 characters. Short and specific works best: "cotton t-shirt", "roasted coffee beans". |
modeOptional | body | "full" (default) may ask the AI model; "suggest" never does. |
Example
curl -X POST https://hscodeatlas.com/api/classify/ \
-H "Content-Type: application/json" \
-d '{"query": "green tea"}' {
"code": "090210",
"description": "Tea, green; (not fermented), in immediate packings of a content not exceeding 3kg",
"confidence": "high",
"reasoning": "Matched the product \"Green tea bags\".",
"results": [
{
"kind": "hs",
"code": "090210",
"description": "Tea, green; (not fermented), in immediate packings of a content not exceeding 3kg",
"product_name": "Green tea bags",
"confidence": "high",
"url": "/hs-code/090210/"
},
{
"kind": "hs",
"code": "090220",
"description": "Tea, green; (not fermented), in immediate packings of a content exceeding 3kg",
"product_name": "Bulk green tea",
"confidence": "high",
"url": "/hs-code/090220/"
}
]
} Shortened to the first 2 candidates.
Response fields
| Field | Type | Description |
|---|---|---|
code | string | The best-matching code. |
description | string | Its official description. |
confidence | string | "high", "medium" or "low". |
reasoning | string | Where the match came from: a product, an HS description, a code, or the AI model. |
results | array | Up to 8 candidates, best first, in the same shape as search results. |
Send the body as JSON with Content-Type: application/json. Bad input (not JSON, a query under 2 characters, an unknown mode) returns 400; a description with no match returns 404.
Errors and limits
Every response is JSON, errors included: they carry an error message and one of these status codes.
| Status | Meaning |
|---|---|
200 | Success. A search with no matches is also 200, with an empty results list. |
400 | Bad input: a lookup that isn't a 2, 4 or 6-digit code, or a classify body that isn't valid. |
404 | The code doesn't exist, or classify found no match. |
429 | Too many requests. Wait for the Retry-After header (60 seconds) and try again. |
500 / 503 | A problem on our side. Retry after a short wait. |
- Rate limit. Search and classify allow 300 requests a minute per IP address.
- Server-side calls. The API doesn't send CORS headers, so call it from your backend, a script or a tool such as Postman, not from JavaScript on another website.
- Need more? For higher volumes or a bulk data file, contact us.
Questions about the HS Code API
Is the HS Code API free?
Yes. All three endpoints are free, with no API key, no sign-up and no paid tier. Search and classify allow 300 requests a minute per IP address.
Do I need an API key to use the HS Code API?
No. Send a plain HTTPS request to https://hscodeatlas.com/api/ with no token or account. The only header you ever need is Content-Type: application/json on classify requests.
What is the difference between search and classify?
Both run the same search. GET /api/search/ returns a ranked list and never calls AI, which suits autocomplete. POST /api/classify/ returns one best code with a reason, and asks an AI model when the catalogue has no match, which suits a submitted product description.
How do I get the HS code for a product name with an API?
Send the product name to POST /api/classify/ as {"query": "green tea"}. The code field is the best match (090210 for green tea) and results lists other candidates with a confidence level. For a quick keyword search, use GET /api/search/?q=green%20tea.
Which HS version does the API use?
HS 2022, the latest edition of the Harmonized System, in force since 1 January 2022. The API covers its chapters, headings and 6-digit subheadings, plus all 10,516 Brazil NCM codes, which add 2 digits to the HS code.
Can I get Brazil NCM codes from the API?
Yes. Send a 7- or 8-digit NCM code, with or without dots, to /api/search/?q=8471.30.12 or to classify. You get the matching NCM codes with English descriptions and the 6-digit HS code they belong to.
Does the API return import duty rates?
No. The API covers classification: codes, descriptions, the HS hierarchy, products and Brazil NCM codes. Check duty rates in the importing country's customs tariff.
Can I call the HS Code API from JavaScript in the browser?
Call it from your own server or script. The API doesn't send CORS headers, so browsers block calls from pages on other websites. Make the request from your backend (Node, Python, PHP or a serverless function) and pass the result to your page.
How accurate is the classify endpoint?
Classify matches your words against 10,000+ products we have already classified and against the official HS descriptions, so short, specific descriptions work best. Every result has a confidence level. Treat it as guidance, not a binding ruling: confirm the code with the customs authority or a licensed broker before you declare goods.
HS Code Atlas gives classification guidance, not binding rulings. Confirm the code with the customs authority of the importing country before you declare goods.