How to Automate Tariff Code Assignment Using an API (2026)
You can automate HTS tariff code assignment by sending product descriptions to a classification API that returns 10-digit HTS codes, duty rates, confidence scores, and CBP ruling citations as evidence. This replaces manual lookup in the USITC tariff schedule with a single POST request that completes in seconds.
Why Automate Tariff Code Assignment?
Manual HTS classification is the bottleneck in most import workflows. A trained customs broker spends 10-30 minutes per product looking up codes in the Harmonized Tariff Schedule, cross-referencing CBP rulings, and applying the WCO's General Rules of Interpretation. This process has three structural problems:
- Slow. Classifying a 500-SKU catalog takes weeks. New products wait for broker availability.
- Error-prone. Different brokers classify the same product differently. CBP penalty assessments for misclassification averaged $7,500 per entry in 2025.
- Expensive. Customs brokers charge $100-200 per classification. At scale, that's $50K-100K for a mid-size catalog.
An API call costs $0.05-0.10, returns in 5-15 seconds, produces the same result every time for the same input, and cites CBP ruling precedents as evidence. It doesn't replace a broker for final filing decisions, but it eliminates 90% of the research work.
| Manual (broker) | API (htsapi.dev) | |
|---|---|---|
| Cost per classification | $100-200 | $0.05-0.10 |
| Time per classification | 10-30 minutes | 5-15 seconds |
| Evidence provided | Varies by broker | CBP ruling citation + rationale |
| Consistency | Varies by broker | Cited rulings + GRI rationale on every call — repeatable evidence path |
| Batch capability | Days/weeks | 500 products in minutes |
How the htsapi.dev Classification API Works
The API uses an agent-based approach. When you submit a product description, it:
- Searches 134K+ CBP rulings in the CROSS database for precedents matching your product
- Reads the HTS schedule from the USITC to identify candidate codes and legal notes
- Applies GRI rules (General Rules of Interpretation) to determine the correct classification
- Enriches with duty data from Census Bureau import statistics for real-world effective rates
The response includes:
| Field | What it contains |
|---|---|
hts_code | Full 10-digit HTS classification |
confidence | high, medium, or low |
rationale | Plain-English explanation of why this code applies |
rulings | CBP ruling numbers with links to the official CROSS database |
census_duties | Effective duty rates from Census import data (what CBP actually collected) |
general_duty | Statutory MFN duty rate from the tariff schedule |
legal_notes | Section/Chapter/Heading notes from the official schedule |
clarification | Follow-up question if the description is ambiguous (null otherwise) |
When the description is ambiguous, the API asks a clarification question instead of guessing. This is a deliberate design choice: a wrong classification with high confidence is worse than asking for more detail.
Step 1 — Get Your API Key
Sign up at htsapi.dev and purchase a credit pack. Each /v1/classify call costs 1 credit. All other endpoints (HTS search, rulings search) are free.
Set your key as an environment variable:
# Linux / macOS export HTS_API_KEY="your_api_key_here" # Windows PowerShell $env:HTS_API_KEY = "your_api_key_here"
Step 2 — Send a Classification Request
Python
import os import requests resp = requests.post( "https://htsapi.dev/v1/classify", headers={"X-API-Key": os.environ["HTS_API_KEY"]}, json={ "description": "stainless steel insulated water bottle 500ml double wall vacuum", "material": "stainless steel", "country_of_origin": "China" } ) data = resp.json() print(data)
Node.js
const resp = await fetch("https://htsapi.dev/v1/classify", { method: "POST", headers: { "Content-Type": "application/json", "X-API-Key": process.env.HTS_API_KEY }, body: JSON.stringify({ description: "stainless steel insulated water bottle 500ml double wall vacuum", material: "stainless steel", country_of_origin: "China" }) }); const data = await resp.json(); console.log(data);
The request body accepts three fields:
| Field | Required | Notes |
|---|---|---|
description | Yes | 3-2000 characters. More detail produces better results. |
material | No | Primary material. HTS classification often hinges on this. |
country_of_origin | No | Needed for Section 301/232 duties and country-specific Census rates. |
Step 3 — Parse the Response
A successful classification returns a JSON object with candidates ranked by confidence:
{
"confident_to": "7323.93.00",
"candidates": [
{
"hts_code": "7323.93.00.50",
"description": "Table, kitchen or other household articles... of stainless steel",
"general_duty": "2%",
"census_duties": {
"country": "CHINA",
"period": "2026-01",
"total_effective_rate_pct": 27.3,
"total_import_value_usd": 45200000,
"total_duty_collected_usd": 12339600,
"breakdown": [
{ "rp_code": "00", "rp_label": "MFN base rate", "effective_rate_pct": 2.0 },
{ "rp_code": "69", "rp_label": "Additional tariffs (Section 301/232/reciprocal)", "effective_rate_pct": 25.3 }
]
},
"confidence": "high",
"rationale": "Stainless steel insulated water bottles are classified under heading 7323 as household articles of stainless steel. The double-wall vacuum construction does not change the classification. CBP has consistently ruled similar products under 7323.93.00.",
"rulings": [
{
"ruling_number": "N284519",
"subject": "The tariff classification of a stainless steel water bottle from China",
"source_url": "https://rulings.cbp.gov/ruling/N284519"
}
],
"legal_notes": "--- SECTION XV ---\nNotes\n1. This section does not cover..."
}
],
"clarification": null
}
Key fields to use in your integration:
confident_to— The deepest HTS prefix where all high/medium-confidence candidates agree. If it's a full 10-digit code, you can file with high confidence. If it's only 4 digits, the description needs more detail.census_duties.total_effective_rate_pct— The actual duty rate CBP collected on this code from this country, including all additional tariffs. This is ground truth from Census Bureau import data, not a theoretical calculation.rulings— Direct links to CBP CROSS rulings you can cite as precedent.rationale— Plain-English explanation of the classification logic, useful for audit documentation.
Step 4 — Handle Clarifications
When a product description is too vague, the API returns a clarification question instead of guessing. This prevents misclassification on ambiguous items.
Example: classifying "wall clock" without additional detail:
{
"confident_to": "9105",
"candidates": [
{
"hts_code": "9105.21.40.00",
"description": "Wall clocks, electrically operated",
"confidence": "medium"
},
{
"hts_code": "9105.11.40.00",
"description": "Wall clocks, mechanically operated",
"confidence": "medium"
}
],
"clarification": "Is the clock movement electric (battery/AC powered) or mechanical (spring/weight driven)?"
}
To resolve, resubmit with the additional detail:
# Resubmit with clarification detail resp = requests.post( "https://htsapi.dev/v1/classify", headers={"X-API-Key": os.environ["HTS_API_KEY"]}, json={ "description": "wall clock, battery-operated quartz movement, plastic case", "country_of_origin": "China" } )
The second call will return a high-confidence result with a full 10-digit code. In a user-facing application, display the clarification question to your user and append their answer to the description before resubmitting.
Integrating into Your Workflow
E-commerce: classify on product import
When a new product is added to your catalog or imported from a supplier feed, classify it automatically. Store the HTS code and duty rate alongside the product record for landed-cost calculations.
ERP: batch classify a catalog
Loop over unclassified SKUs and classify each one. Store results in your ERP. Flag items where confident_to is shorter than 8 digits for manual review.
import os, time import requests API_KEY = os.environ["HTS_API_KEY"] products = [ {"sku": "WB-001", "desc": "stainless steel water bottle 500ml insulated", "origin": "China"}, {"sku": "TS-042", "desc": "men's 100% cotton knit t-shirt short sleeve", "origin": "Vietnam"}, {"sku": "CB-119", "desc": "lithium-ion battery pack 48V for electric bicycle", "origin": "China"}, ] for p in products: resp = requests.post( "https://htsapi.dev/v1/classify", headers={"X-API-Key": API_KEY}, json={"description": p["desc"], "country_of_origin": p["origin"]} ) result = resp.json() top = result["candidates"][0] needs_review = len(result["confident_to"] or "") < 10 print(f"{p['sku']}: {top['hts_code']} ({top['confidence']})" f{" ⚠ REVIEW" if needs_review else ""}) time.sleep(1) # respect rate limits
Customs broker: pre-screen before filing
Use the API as a first pass to classify shipments. Route high-confidence results directly to entry preparation. Send low-confidence or clarification-needed items to a human broker. This cuts broker workload by 60-80% on typical shipments.
Accuracy and Evidence
Accuracy claims require context. Here is what we measure and what the numbers mean:
| Metric | Value | What it means |
|---|---|---|
| 10-digit exact match | ~70% | On novel CBP rulings (products the model hasn't seen), the API returns the exact 10-digit code that CBP assigned |
| 6-digit match | ~70% | Correct at the international HS level (determines duty heading) |
| Clarification rate | ~15% | Percentage of requests where the API asks for more detail instead of guessing |
Every result includes:
- CBP ruling citations when a relevant precedent exists in the 134K+ ruling database
- Census Bureau effective duty rates from actual import data — what CBP collected, not just what the schedule says
- Legal notes from the official USITC tariff schedule
- Confidence level so you know when to trust the result and when to escalate
Pricing
| Pack | Credits | Price | Per classification |
|---|---|---|---|
| Starter | 100 | $10 | $0.10 |
| Standard | 1,000 | $50 | $0.05 |
What's free:
- Web UI classification at htsapi.dev — try the classifier before buying API credits
- HTS code search —
GET /v1/hts/search?q= - CBP rulings search —
GET /v1/rulings/search?q= - Balance check —
GET /v1/billing/balance
Only /v1/classify costs credits. Everything else is free and unlimited within rate limits.
Frequently Asked Questions
How accurate is automated HTS classification?
The htsapi.dev classification API achieves approximately 70% exact 10-digit match accuracy on novel CBP rulings benchmarks. Every result includes a confidence level and CBP ruling citation when available, so you can verify the classification against official precedent before filing. At the 6-digit HS level, accuracy is approximately 70%, and 80% at 4-digit heading.
Can the API handle ambiguous product descriptions?
Yes. When a product description is too vague to classify confidently, the API returns a clarification question instead of guessing. For example, "wall clock" would prompt "Is the movement electric or mechanical?" You resubmit with the additional detail and receive a precise classification. This happens on roughly 15% of requests.
What data sources does the API use?
The API searches 134,000+ CBP ruling precedents from the CROSS database, the official USITC Harmonized Tariff Schedule, Census Bureau import statistics for effective duty rates, and applies WCO General Rules of Interpretation (GRI) for classification logic. Data is updated daily for rulings, monthly for HTS revisions, and quarterly for Census duty data.
How fast is the API response?
Most classification requests complete in 5-15 seconds. The API performs real-time searches across CBP rulings and the HTS schedule, then applies GRI reasoning. This is slower than a simple database lookup but produces evidence-backed results with citations. Rate limit is 60 requests per minute per API key.
Is there a free trial?
The web UI at htsapi.dev lets you classify products for free with no API key required. All non-classify endpoints (HTS search, rulings search) are also free and unlimited. Paid API access for programmatic use starts at $10 for 100 credits.