USITC publishes updates to the Harmonized Tariff Schedule multiple times per year. If you are building software that depends on HTS data, you need a precise mental model of what these updates contain — because not all changes have the same implications for your application, and treating them all the same will either cause you to over-engineer your response or miss something that actually matters.
This article breaks down exactly what changes in a USITC schedule update, what the downstream impact is for each type, and what your pipeline needs to handle correctly.
The Types of Changes USITC Publishes
Schedule updates are not monolithic. A given release may contain any combination of the following, and understanding which type you are dealing with determines how urgently you need to respond and what you need to recalculate.
Rate changes
The duty rate in the General (MFN), Special, or Other column changes for one or more HTS codes. This is the change that directly affects what importers pay. Applications that surface duty rates to users, calculate landed costs, or flag rate changes to compliance teams must detect and propagate these immediately. A stale rate in a production application is a compliance error.
Chapter 99 additions or modifications
A new Section 232, Section 301, or other trade action provision is added, modified, or removed. Chapter 99 entries impose additional duties on top of the base MFN rate and are updated whenever trade policy changes — which in the current environment means frequently. These changes are high impact because they affect the effective duty rate without touching the rate columns in the product chapters directly.
Code additions and deletions
HTS codes are added, split into more specific subheadings, or consolidated and retired. If your application stores HTS codes in a database — for product catalogs, classification history, or customer records — a deleted code that your system still references is now invalid. A new code that splits an existing classification may mean products previously classified under one code now require a more specific determination.
Description changes
The text description of an HTS code is revised. This does not change the rate, but it may change how the code is interpreted for classification purposes. If your application uses descriptions for search, display, or classification assistance, stale descriptions can mislead users even when the underlying rate is correct.
Unit of quantity changes
The statistical reporting unit for a code changes — for example, from kilograms to number of items. This affects how quantities are reported on import documentation. Applications that generate or validate entry data need to track these changes to avoid reporting errors.
Indent and hierarchy changes
The hierarchical position of a code within its chapter changes. This affects how the schedule is displayed and navigated but rarely has direct rate implications. Applications that render the HTS as a tree structure need to handle this, but it is not typically urgent.
How USITC Publishes Updates
USITC does not publish a diff or changelog. They publish a new version of the full schedule. The update is reflected in the API and in the downloadable files simultaneously, but there is no versioning in the API response that would let your application detect that a new release has been published. You find out by fetching and comparing.
There is also no fixed release calendar. Major annual revisions typically happen in January, reflecting changes that take effect at the start of the year. But trade policy actions — Section 232, Section 301, Presidential proclamations — can trigger mid-year updates at any time and with little advance notice. In active trade policy periods, this can mean meaningful updates appearing multiple times per month.
What USITC Updates Do Not Include
Understanding the boundaries of what a USITC schedule update covers is as important as understanding what it does cover. Several things that affect effective duty rates are not reflected in the schedule itself:
- Exclusions from Section 232 and Section 301 duties. Individual importers or products can receive exclusions from additional duties through a separate USTR or Commerce process. These exclusions are not reflected in the HTS schedule. An application that relies solely on the schedule for rate calculation will overstate the duty for excluded goods.
- Antidumping and countervailing duty orders. ADD/CVD orders are administered by Commerce and CBP separately from the HTS. They impose additional duties on specific goods from specific countries and are not visible in the tariff schedule at all.
- First sale and other valuation adjustments. Duty is assessed on the value of the goods, and how that value is determined involves rules that sit outside the schedule entirely.
For most trade compliance applications, HTS rate data is the core of the calculation, but a complete landed cost or duty estimate requires these additional data sources. The schedule tells you the applicable rates; it does not tell you everything that affects what a specific importer pays on a specific shipment.
The Schema Problem
Beyond the content of updates, there is a structural problem that engineering teams encounter when building long-running HTS pipelines: USITC occasionally changes the schema of their published data between releases. Field names shift. Nesting changes. Values that were previously strings become arrays or vice versa.
This is not announced. You discover it when your pipeline fails or, worse, when it silently produces malformed output because a field your code expects is now named differently or structured differently than your parser expects.
The practical defense is to build schema validation into your ingestion pipeline — check that expected fields are present across a representative sample of records before accepting a new dataset as valid. A fetch that passes the record count check but fails the schema validation check should be treated the same as a failed fetch: abort without overwriting the live dataset.
REQUIRED_FIELDS = {"htsno", "description", "general", "indent"}
def validate_schema(records: list, sample_size: int = 500) -> bool:
sample = [r for r in records if r.get("htsno")][:sample_size]
for record in sample:
missing = REQUIRED_FIELDS - set(record.keys())
if missing:
print(f"Schema error on {record.get('htsno')}: missing {missing}")
return False
return True
How to Prioritize Your Response to Different Update Types
Not all changes require the same response from your application. A reasonable prioritization:
- Rate changes and Chapter 99 modifications — propagate immediately, notify affected users if your product supports that, recalculate any stored duty estimates that reference affected codes.
- Code additions and deletions — audit your stored data for references to deleted codes, flag them for review, map split codes to their successors where possible.
- Description and unit changes — update your local copy, refresh any search indexes, review affected classifications if your application assists with classification decisions.
- Hierarchy changes — update display logic, lower urgency unless your application renders the schedule as a navigable tree.
The practical implication: Your change detection pipeline needs to produce a typed diff — not just "these codes changed" but "these codes had rate changes, these were added, these were removed." Treating all changes as equivalent means either over-notifying users about low-impact changes or under-prioritizing high-impact ones. The fields_changed field in a well-structured diff gives you this granularity without extra work.
What a Well-Instrumented Pipeline Tells You
After each nightly run, you should be able to answer these questions from your logs without manual investigation:
- Did the run complete successfully?
- How many records were fetched, and does that match the expected range?
- Did the schema validate cleanly?
- Were any changes detected, and if so, what types?
- Did any Chapter 99 codes change?
- Were any codes added or removed?
If you cannot answer all of these from a log entry without SSHing into the server and manually inspecting files, your pipeline is not sufficiently instrumented for production use.
TradeFacts.io handles all of this upstream of your application. Our /changes endpoint returns a typed diff after every nightly run — rate changes, code additions and removals, Chapter 99 modifications, all separated and timestamped. Your application queries one endpoint and gets structured, actionable change data without maintaining any of the pipeline described above. 30-day free trial, no credit card required.
Get typed HTS change detection via API.
30-day free trial, no credit card required. Rate changes, code additions, Chapter 99 modifications — all separated and timestamped.
Request API Access