CBP CROSS Customs Ruling Scraper
Pricing
from $0.80 / 1,000 record scrapeds
CBP CROSS Customs Ruling Scraper
Pulls binding classification rulings from CBP's CROSS database — HQ, NY and legacy letters going back decades. Each row carries the ruling number, date, subject, HTS codes, the full letter text, and the modify/revoke graph so you can tell whether a ruling is still good law.
Pricing
from $0.80 / 1,000 record scrapeds
Rating
0.0
(0)
Developer
BowTiedRaccoon
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Share
CBP CROSS Customs Ruling Scraper - Binding Classification Rulings
Extract binding customs classification rulings from CBP's CROSS database (Customs Rulings Online Search System) — the official record of every HQ, NY and legacy ruling letter CBP has issued on how a product is classified under the Harmonized Tariff Schedule. Each record carries the ruling number, date, subject, every HTS code it classifies to, the full letter text, and the modify/revoke graph so you can tell whether a ruling is still good law.
CBP CROSS Customs Ruling Scraper Features
- Pulls HQ, NY and legacy (L/D/C/numeric) ruling letters from CBP's complete public ruling corpus
- Every HTS code a ruling classifies to, plus a derived
primary_htsand two-digithts_chapterfor joining to a tariff schedule - Full ruling letter text, not just the subject line
- The revocation graph resolved into
is_currently_good_law— know whether a ruling you're about to cite has been superseded - USMCA/NAFTA flags and CBP's own commodity grouping for filtering
- Filter by collection (HQ/NY/all) and ruling date range
- Toggle full-text fetch off for a fast index-only pull of ruling numbers, dates, subjects and HTS codes
Who Uses CBP Ruling Data and Why?
- Customs brokers and classification desks — find every prior ruling for a product description before submitting a new one, and confirm a cited ruling hasn't been revoked
- Landed-cost and duty-engine vendors — back a classification decision with binding CBP precedent, not just a schedule lookup
- Corporate trade-compliance teams — build HTS decision trees from CBP's own classification language, especially with Section 301 duties now turning on exact HTS codes
- Customs law firms — research precedent for protests and prospective ruling requests
- AI/ML teams — train classification models on a clean (product description → HTS code) labelled corpus written by CBP's own classification officers
How CBP CROSS Customs Ruling Scraper Works
- You set an optional collection filter (HQ, NY, or all), an optional ruling date range, and whether to fetch full letter text.
- The crawler pulls matching ruling letters from CBP's CROSS search, covering the HQ, NY and legacy collections.
- Each ruling is normalized into a clean record: the HTS codes it classifies to, the subject, CBP's own categories, the USMCA/NAFTA flags, and the modify/revoke graph.
- When full-text fetch is on (the default), the actor also pulls the ruling letter body and parses out the requester and stated country of origin where present.
Input
Basic: recent rulings, full text included
{"maxItems": 100}
HQ rulings only, fast index-only pull
{"maxItems": 500,"collection": "HQ","fetchFullText": false}
Rulings issued in a date window
{"maxItems": 200,"fromDate": "2026-01-01","toDate": "2026-06-30"}
Pull everything (full corpus)
{"maxItems": 0}
Input Parameters
| Field | Type | Default | Description |
|---|---|---|---|
| maxItems | integer | 10 | Maximum number of rulings to return. Set to 0 for no cap. |
| collection | string | "ALL" | "ALL", "HQ" (Headquarters rulings) or "NY" (New York rulings). |
| fromDate | string | "" | Only return rulings dated on or after this date (YYYY-MM-DD). Leave empty for no lower bound. |
| toDate | string | "" | Only return rulings dated on or before this date (YYYY-MM-DD). Leave empty for no upper bound. |
| fetchFullText | boolean | true | Fetch the full ruling letter (text, requester, country of origin) per record. Turn off for a faster, index-only pull of ruling numbers, dates, subjects and HTS codes. |
CBP CROSS Customs Ruling Scraper Output Fields
Example Output
{"ruling_number": "H335012","collection": "hq","ruling_date": "2026-10-02","ruling_year": 2026,"subject": "Re: Request for Binding Ruling; Classification of Casio Colpocamera Stand model number CST-100M","tariffs": ["9620.00.70"],"primary_hts": "9620.00.70","hts_chapter": "96","categories": ["Classification"],"commodity_grouping": null,"is_usmca": false,"is_nafta": false,"operationally_revoked": false,"modifies": [],"modified_by": [],"revokes": [],"revoked_by": [],"related_rulings": [],"is_currently_good_law": true,"ruling_text": "HQ H335012 October 2, 2026 ... [full letter text]","requester": "Ms. Ewa Szczepanski Casio America, Inc.","country_of_origin": "Japan","doc_url": "https://rulings.cbp.gov/api/getdoc/hq/2026/H335012.pdf","url": "https://rulings.cbp.gov/docs/hq/2026/H335012","internal_id": 222635,"source": "rulings.cbp.gov","scraped_at": "2026-10-15T07:30:47.720Z"}
Output Field Reference
| Field | Type | Description |
|---|---|---|
| ruling_number | string | CBP's public ruling identifier, e.g. H357206, N363447, 955022 |
| collection | string | hq, ny, or legacy |
| ruling_date | string | Date the ruling was issued (YYYY-MM-DD) |
| ruling_year | number | Year the ruling was issued |
| subject | string | Ruling subject line |
| tariffs | string[] | Every HTS code this ruling classifies to — empty for non-classification rulings (Valuation, country-of-origin marking, etc.) |
| primary_hts | string | First/controlling HTS code, or null |
| hts_chapter | string | Two-digit HTS chapter derived from primary_hts |
| categories | string[] | CBP's own subject categories for this ruling |
| commodity_grouping | string | CBP's commodity grouping label, where assigned |
| is_usmca | boolean | Whether this ruling addresses USMCA |
| is_nafta | boolean | Whether this ruling addresses NAFTA |
| operationally_revoked | boolean | Whether CBP has flagged this ruling as operationally revoked |
| modifies | string[] | Ruling numbers this ruling modifies |
| modified_by | string[] | Ruling numbers that modify this ruling |
| revokes | string[] | Ruling numbers this ruling revokes |
| revoked_by | string[] | Ruling numbers that revoke this ruling |
| related_rulings | string[] | Other ruling numbers CBP links to this one |
| is_currently_good_law | boolean | Derived: true when the ruling is neither operationally revoked nor revoked by a later ruling |
| ruling_text | string | Full ruling letter text (present when fetchFullText is on) |
| requester | string | Importer, broker or counsel who requested the ruling, parsed from the letter header (best effort — not every letter yields a clean match) |
| country_of_origin | string | Country of origin stated in the ruling body, where present (best effort — most rulings don't state one) |
| doc_url | string | Direct PDF link for the original ruling letter |
| url | string | Public CROSS web page for this ruling |
| internal_id | number | CROSS internal numeric id |
| source | string | Source site name |
| scraped_at | string | UTC timestamp this record was collected |
FAQ
How many rulings does this cover? CROSS holds 221,000+ searchable ruling letters across the HQ, NY and legacy collections, going back to the 1980s. The scraper pulls from the full corpus, not a subset.
Does every ruling have an HTS code?
No. Most rulings are classification decisions and carry one or more HTS codes in tariffs. CROSS also publishes non-classification letters — Valuation, country-of-origin marking, IPR — and those legitimately have an empty tariffs array.
Why is requester or country_of_origin sometimes empty?
Both are parsed from the free-text ruling letter, not a structured CBP field. Most letters name the requester in a standard header, so that field fills reliably; a stated country of origin is less common — many rulings classify a product without ever naming where it's made.
How do I know if a ruling is still valid?
Check is_currently_good_law. It's derived from CBP's own operationally_revoked flag and the revoked_by list — false means a later ruling superseded this one, or CBP flagged it directly.
What does it cost to run? Priced per record. A quick sample of 100 rulings costs pennies; a full-corpus pull is priced the same per row regardless of how large the run.
Can I pull just HQ or just NY rulings?
Yes — set collection to "HQ" or "NY". Leave it at "ALL" (the default) to search both plus the legacy collections.
Need More Features?
Need custom fields, filters, or a different data source? File an issue or get in touch.
Why Use CBP CROSS Customs Ruling Scraper?
- The full letter, not just the headline — most tariff tools stop at the subject line; this one carries the complete ruling text.
- HTS codes as a real join key —
tariffsis a structured array, so you can go from an HTS code to every ruling that ever classified to it. - Know what's still valid — the modify/revoke graph is resolved into one boolean, so you're not citing a dead ruling in a protest.
- The whole corpus, priced per record — one run covers HQ, NY and legacy letters back to the 1980s.