The official HTS API gives you the schedule. Not the rate.
USITC publishes the Harmonized Tariff Schedule as JSON, for free, and it's the source we ingest. It just doesn't answer the question you're actually asking: what does this code cost from this country, today.
If you're evaluating hts.usitc.gov/reststop or DataWeb for a duty feature, start here. The official data is authoritative and free, and we depend on it. But it publishes the schedule as a document, not as a resolved answer. The gap between those two things is most of what we do, and it's larger than it looks on day one. This page shows the raw responses so you can judge the build yourself.
Tariffs API vs the USITC HTS API
| Feature | Tariffs API | the USITC HTS API |
|---|---|---|
| What one lookup returns | The effective rate for an HTS code from a given origin on a given date | The schedule entry for that code, with no origin and no date applied |
| GET hts.usitc.gov/reststop/search?keyword=8541.10.00 returns "general": "Free" with no field indicating whether a Chapter 99 measure applies to that code (accessed 2026-08-04). | ||
| Origin awareness | Origin is a required parameter | None. The schedule is origin-agnostic by design |
| Chapter 99 linkage | Resolved and returned as additional_measures | Not linked. You infer it from note bodies |
| The 9903.88.03 record defines its own scope as "as provided for in U.S. note 20(e)" and "the subheadings enumerated in U.S. note 20(f)". Those note bodies are not in the JSON response (accessed 2026-08-04). | ||
| Rate format | Numeric components you can compute with | Prose strings |
| 9903.88.03 returns "general": "The duty provided in the applicable subheading + 25%" as a single string (accessed 2026-08-04). | ||
| 10-digit statistical codes | Resolved via the parent chain | Often empty; the rate lives on the 8-digit parent |
| 8541.10.00.40 returns "general": "" while its parent 8541.10.00 carries the rate. You walk the hierarchy yourself using the "indent" field (accessed 2026-08-04). | ||
| Revision churn | Re-ingested every 6 hours, with a public changelog | Revisions replace the file; codes are added, split, and removed |
| reststop/currentRelease returned "2026HTSRev15" on 2026-08-04. That is 15 revisions in one year. | ||
| Historical dates | as_of parameter resolves the rate in force on that date | Current release only |
| Cost | From $49/month, public pricing | Free |
| Scope beyond the schedule | Section 301, 232, 122, 338, IEEPA stacking and exclusions | The schedule as published |
When the official USITC data is the right pick
- →You need the schedule itself: descriptions, hierarchy, statistical suffixes, units of quantity.
- →You're doing trade statistics or research, where DataWeb's import and export volumes are the actual product.
- →You need a free, authoritative, citable source and you have engineering time to model the rest.
- →Your use case is one-off analysis rather than a rate served to a customer on every request.
When Tariffs API is the right pick
- ✓You need a number, by origin, by date, that you can put in a checkout or an invoice.
- ✓You don't want to own a parser for note bodies, exclusion lists, and stacking rules that change by proclamation.
- ✓You've already discovered that Chapter 99 is where the real money is and that nothing links it to your code.
- ✓You'd rather a wrong rate be our production incident than yours.
One endpoint. Deterministic JSON.
We ingest the same USITC release you would, every 6 hours, then do the part the raw feed leaves to you: link Chapter 99 measures to the base code, apply origin and date, parse prose rates into numeric components, and resolve stacking and exclusions. GET /api/v1/tariffs/resolve?hts=8541.10.00.80&origin=CN returns the base duty, every applicable measure with its Chapter 99 heading, a confidence score, and the candidates we attempted.
GET /api/v1/tariffs/resolve?hts=8541.10.00.80&origin=CN
{
"summary": {
"applicable_ad_valorem_rate": 0.0,
"resolved_additional_ad_valorem_rate": 25.0,
"total_resolved_ad_valorem_rate": 25.0
},
"base_tariff": { "percentage_component": 0.0 },
"additional_measures": [
{
"program": "section_301",
"chapter_99_code": "9903.91.05",
"resolved_rate": { "percentage_component": 0.25 }
}
]
}
Switching from the USITC HTS API
Isn't the USITC HTS API free? Why pay for this?
It is free, and you should use it if the schedule is what you need. You're not paying us for the data. You're paying for the resolution layer: Chapter 99 linkage, origin and date handling, numeric rate parsing, stacking order, and exclusions. That layer is where the schedule stops and the engineering starts.
What's the difference between the HTS API and DataWeb?
They're two different systems. hts.usitc.gov publishes the tariff schedule itself, which is what you'd build a duty lookup on. DataWeb is USITC's trade statistics system, covering import and export values and volumes. If you're calculating what a shipment owes, the schedule is the relevant one; DataWeb answers a different question.
Could I just build this on the official API myself?
Yes, and some teams should. Be clear-eyed about the scope: the Chapter 99 headings that carry Section 301 and 232 define their coverage in note bodies that aren't in the JSON, rates come back as prose strings, 10-digit codes inherit from their parents, and the schedule was revised 15 times in 2026 alone. It's a maintained system, not a one-week integration.
Where does your data come from?
The same place. We ingest USITC's published release every 6 hours, plus Federal Register proclamations, USTR Section 301 notices, and CBP CSMS messages for the measures that don't live in the schedule. See /how-we-source-data for the full list.
Does this replace a customs broker?
No. We report rates on codes you already have. We don't classify products into HTS codes and we don't file entries. Both of those are licensed-broker work.
- USITC HTS REST endpoint (search) · accessed 2026-08-04
- USITC HTS REST endpoint (current release) · accessed 2026-08-04
- USITC DataWeb · accessed 2026-08-04