Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
US Tariff Schedule Scraper icon

US Tariff Schedule Scraper

Scrape the US Harmonized Tariff Schedule: HTS codes, descriptions, units of quantity, general, special and column 2 duty rates, and the edition on every row.

46 runs on Apify $0.002 per tariff line ($2 / 1,000)
Run this in the cloudRun on Apify →

Developer & Research Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust chapters, hsCodes, searchTerms (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.002 per tariff line = $2 per 1,000

You are charged forWhenPrice
Tariff line scrapedOne HTS tariff line with its duty rates and the edition it came from. Edition mismatches stop the run before it spends.$0.002

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-20, and they are what you are actually charged.

Inputs

FieldWhat it doesType
chaptersChapters of the tariff schedule to read, as numbers: 61 is knitted apparel, 84 is machinery, 87 is vehicles, 99 holds the temporary modifications. Ranges work too - write 61-63. Chapter 77 is reserved in the Harmonized System and has no lines.array
hsCodesSpecific codes, at any depth. 8471 gives you the whole heading, 8471.30 the subheading, 6101.20.00.10 that one statistical line. Dots are optional. The run reads the chapter each code sits in and keeps the lines that start with it.array
searchTermsWords to look up in the schedule's own index, like "laptop" or "olive oil". The matching codes come back as full rows with their duty rates and the description path above them. The index is broad - searching "cotton shirt" also returns cotton seed - so check the descriptions.array
allChaptersReads every chapter from 01 to 99 in order. That is about 29,900 numbered lines, so raise the row limit to match or you will get the first slice of it. This costs you one charge per row.boolean
includeLinesThe schedule is a tree. "all" returns every numbered line, including the 4-digit headings and 6-digit subheadings that hold the structure but print no rate. "withDutyRate" drops those and keeps the 8- and 10-digit lines. "statisticalOnly" keeps just the 10-digit lines, the ones that go on an entry.string
maxItemsHow many tariff lines to return. Keep it low while you are testing - you pay per row. The whole schedule is about 29,900 numbered lines, and the hard ceiling is 40,000.integer
requireEditionOptional. Put an edition name here, like 2026HTSRev19, and the run will refuse to return anything if the live schedule is a different edition. Useful on a schedule, where a revision landing overnight would otherwise change your rates without anyone noticing. Leave it empty to take whatever is current.string
proxyUrlsLeave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.array

What you get

A structured dataset — each result includes fields like:

htsnolineLevelchapterheadingdescriptionunitOfQuantitygeneralRateEffectivespecialRateEffectivecolumn2RateEffectiveratesAreInheritedrateSourcedutyRateResolvedhtsEditionhtsUrl

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

Related tools in Developer & Research Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

GitHub Scraper iconDeveloper & Research Tools

GitHub Scraper

Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.

18 use cases

Stack Overflow / Stack Exchange Scraper iconDeveloper & Research Tools

Stack Overflow / Stack Exchange Scraper

Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.

2 use cases

Package Registry Scraper (npm + PyPI) iconDeveloper & Research Tools

Package Registry Scraper (npm + PyPI)

Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.

2 use cases

arXiv Scraper iconDeveloper & Research Tools

arXiv Scraper

Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.

2 use cases

OpenAlex Scholarly Works Scraper iconDeveloper & Research Tools

OpenAlex Scholarly Works Scraper

Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.

2 use cases

Crossref Scholarly Works Scraper iconDeveloper & Research Tools

Crossref Scholarly Works Scraper

Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.

2 use cases

See all Developer & Research Tools →

US Tariff Schedule Scraper: HTS codes, duty rates and units, with the edition on every row

Give it chapters, HTS codes or search terms, and it reads those lines of the US Harmonized Tariff Schedule from the USITC's own published data. Each row is one line: the HTS code, its description and full description path, the unit of quantity, the general, special and column 2 rates exactly as printed, the rate that applies when a line inherits it, and the edition it came from. The awkward part: an empty rate on a line does not mean duty-free, and only the live edition is published, so a rate you pulled in March may not be the one in force in September.

InputChapters or chapter ranges, HTS codes at any depth, search terms, or the whole schedule
OutputOne row per tariff line
Ceiling40,000 rows, 200 codes and 10 search terms per run
Account neededNone
Price$2.00 per 1,000 tariff lines, flat on every plan

🔍 What US Tariff Schedule Scraper does

The edition is read before a single line, and every row carries it, so a dataset dates itself. It is read again at the end, and if a revision landed mid-run you get a free row saying so. On a schedule, requireEdition makes the run return nothing rather than a different edition.

Then the rates. The schedule states a rate once and lets the lines beneath it inherit, so a 10-digit line often prints nothing in its rate columns. In edition 2026HTSRev19, 11,836 of the 29,860 numbered lines carried no rate of their own. Read those blanks as zero and you price about two lines in five at no duty when they are dutiable. So each row keeps both readings apart:

FieldWhat it is
generalRate, specialRate, column2RateExactly what this line printed. null when it printed nothing
generalRateEffective, specialRateEffective, column2RateEffectiveThe rate that applies, copied verbatim from wherever it was stated
ratesAreInherited, rateSourceWhether it came from a line above, and the HTS code it was read off
dutyRateResolved, rateNotefalse when no line above prints a general rate, with the reason in plain words

A rate is only inherited from a line whose code starts the row's own code. Rates are never parsed into numbers. You get 15.9%, Free, 1¢/kg, 3.7¢/kg on drained weight, and in chapter 99 whole sentences such as The duty provided in the applicable subheading + 25%. Turning those into a number is a judgement about your goods.

Each chapter is checked before it is used. One that comes back empty, or carrying lines from another chapter, becomes a free row instead of a charge.

📥 What you give it

FieldIf you leave it outWhat it does
chaptersnoneChapter numbers 1 to 99, or ranges such as 61-63. 61 is knitted apparel, 84 machinery, 87 vehicles, 99 the temporary modifications. Chapter 77 is reserved and gets a free row saying so.
hsCodesnoneCodes at any depth, 2 to 10 digits, dots optional, up to 200. 8471 is a whole heading, 6101.20.00.10 one line.
searchTermsnoneWords looked up in the schedule's own index, up to 10. The index is broad: cotton shirt also finds cotton seed, so read the descriptions.
allChaptersfalseReads every chapter, 01 to 99. Raise maxItems to match or you get the first slice.
includeLinesallall, withDutyRate (8- and 10-digit lines only) or statisticalOnly (the 10-digit lines that go on an entry).
maxItems1001 to 40,000 rows.
requireEditionany editionAn edition name such as 2026HTSRev20. If a different one is live, the run reads nothing and charges nothing.
proxyUrlsnot usedYour own servers to send the traffic through, as http://user:pass@host:port. Leave it empty unless you need that.

One thing about combining them. Give chapters together with hsCodes or searchTerms and you get the whole chapters, with the codes only filling in matchedQuery. To get just the lines you named, leave chapters empty.

{
  "hsCodes": ["8471.30", "6101.20"],
  "searchTerms": ["olive oil"],
  "includeLines": "statisticalOnly",
  "maxItems": 200
}

An input with nothing in it, such as {} sent through the API, returns one free sample row so you can see the shape first.

📤 What you get back

A real row from a real run. Look at the rates: this line printed none, and the 15.9% it carries was read off 6101.20.00 above it.

{
  "ok": true,
  "charged": true,
  "recordType": "tariffLine",
  "htsEdition": "2026HTSRev20",
  "htsEditionTitle": "Revision 20 (2026)",
  "htsno": "6101.20.00.10",
  "lineLevel": "statistical",
  "chapter": "61",
  "heading": "6101",
  "subheading": "6101.20",
  "headingDescription": "Men's or boys' overcoats, carcoats, capes, cloaks, anoraks (including ski-jackets), windbreakers and similar articles, knitted or crocheted, other than those of heading 6103:",
  "indent": 2,
  "description": "Men's (334)",
  "descriptionPath": "Men's or boys' overcoats, carcoats, capes, cloaks, anoraks (including ski-jackets), windbreakers and similar articles, knitted or crocheted, other than those of heading 6103: > Of cotton > Men's (334)",
  "unitOfQuantity": "doz., kg",
  "units": ["doz.", "kg"],
  "generalRate": null,
  "specialRate": null,
  "column2Rate": null,
  "generalRateEffective": "15.9%",
  "specialRateEffective": "Free (AU,BH, CL,CO,IL,JO,KR, MA,OM, P,PA,PE,S,SG)",
  "column2RateEffective": "50%",
  "ratesAreInherited": true,
  "rateSource": "6101.20.00",
  "dutyRateResolved": true,
  "rateNote": null,
  "additionalDuties": null,
  "footnotes": [],
  "matchedQuery": null,
  "htsUrl": "https://hts.usitc.gov/search?query=6101.20.00.10",
  "scrapedAt": "2026-09-30T02:28:10.927Z"
}
FieldWhat it is
htsEdition, htsEditionTitleThe edition the row came from, so two pulls a month apart can be told apart without notes.
htsno, lineLevelThe code as published, and its level: heading (4 digits), subheading (6), tariffLine (8) or statistical (10).
chapter, heading, subheadingThe code's own leading digits, split out for grouping.
description, descriptionPathThe line's own text, often a fragment like Men's (334), and the whole branch joined with > so a deep line reads on its own.
unitOfQuantity, unitsThe published unit as text, and the same thing split into an array. Many lines carry two.
additionalDuties, footnotesExtra duty provisions, mostly chapter 99 safeguards, and the publisher's own footnotes, untouched.
matchedQueryWhich of your codes or search terms picked the row.
htsUrlThe line on hts.usitc.gov, for when someone wants to check.

🧾 Reading the output

Three kinds of row can share a dataset, and charged is the field that separates them.

RowHow to spot itCharged
A tariff linecharged: trueyes
The sample_sample: true, charged: falseno
A diagnostic_diagnostic: true, charged: false, an errorCodeno

The sample row also says recordType: "tariffLine", so filter on charged == true, not on recordType.

CodeWhat it means
NO_RESULTSSeveral cases, and details says which: nothing matched, a search term found nothing, chapter 77, a chapter that came back empty, a requireEdition that is not the live one, or a revision that landed while the run was reading.
BAD_INPUTSomething in chapters or hsCodes is not a chapter number or an HTS code.
NETWORKThe schedule could not be read. If that happens at the edition check, nothing is read at all.
TIME_BUDGETThe run ran out of time before a chapter was read.

▶️ How to run it

1. Open US Tariff Schedule Scraper and click Try for free. 2. Type chapter numbers into Chapters, or clear it and use HTS codes or Search terms. The form arrives with chapter 61. 3. Choose Which lines to return. "Statistical lines only" gives you the codes that go on an entry. 4. Set Maximum rows, or tick Read the whole schedule and raise it to match. 5. Click Start, then download the dataset as CSV, JSON or Excel.

💰 How much does it cost?

$2.00 per 1,000 tariff lines, which is $0.002 a line, flat on every Apify plan. An average chapter holds around 300 lines, which comes to roughly 60 cents, and the whole schedule of about 29,900 lines to roughly $60.

You pay for tariff-line rows and nothing else per row. The sample row and every diagnostic row are free, including chapter 77, an empty chapter, a search term that finds nothing and a requireEdition refusal. Lines in chapters 98 and 99 that resolve to no rate are still charged, because they are still the lines you asked for. If you set a maximum charge on the run, it stops at that figure instead of going past it.

💡 What people use it for

  • Checking the duty on a product before pricing an import, with the rate and the line it came from on one row.
  • Keeping your own history. Only the live edition is published, so a pull after each revision is the only archive you will have.
  • Seeing what a revision moved, by comparing two pulls on htsno plus generalRateEffective.
  • Loading the schedule into a spreadsheet, where descriptionPath makes a deep line readable on its own.

🚧 What it does not do

  • No classification. Which line your goods fall under is your call, or your broker's.
  • No advice, customs, legal or otherwise.
  • Only the live edition. There is no way to ask for last year's rates.
  • No notes. General, section and chapter notes are prose documents, not data. Chapter titles are not returned either.
  • Only the US schedule. No other country's tariff.
  • No duty calculation. No landed cost, freight, trade-remedy stacking or rules of origin.
  • Chapters 98 and 99 carry lines with no rate. In edition 2026HTSRev19, 1,169 of their lines resolved to no general rate, because the treatment comes from a note rather than a rate column. They arrive with dutyRateResolved: false and a rateNote.

🧭 Which trade data scraper do you need?

If you wantUse
US tariff lines and duty ratesThis one
Who imports what, from US customs shipment recordsImportYeti Scraper
Wholesale products, price ranges and MOQs from suppliersAlibaba.com Scraper
US industrial suppliers by product and locationThomasnet Suppliers Scraper

❓ Questions people ask

What is the HTS? The Harmonized Tariff Schedule of the United States: the codes every imported good is classified under and the duty attached to each. The US International Trade Commission publishes it.

How many lines are there? In edition 2026HTSRev19 there were 29,860 numbered lines: 961 headings, 2,093 subheadings, 6,857 eight-digit lines and 19,949 statistical lines. Revision 20 is live now and has not been recounted.

Can I get the Section 232 and 301 duties? Chapter 99 holds the temporary modifications and it is included: {"chapters": ["99"]}. Those lines often state the treatment as a sentence rather than a percentage, and you get that sentence.

Can I run it on a schedule? Yes. Compare runs on htsno plus generalRateEffective to see what moved, and watch htsEdition for when a revision landed.

🆘 If something breaks

Open the Issues tab on the actor page and send the run ID with the input you used. The errorCode and details on a diagnostic row usually name the reason already.