AD/CVD Antidumping Duty Tracker — Federal Register API
Pricing
from $4.40 / 1,000 results
AD/CVD Antidumping Duty Tracker — Federal Register API
Antidumping and countervailing (AD/CVD) duty tracker: turns US Federal Register trade-remedy notices into a structured feed. Extracts the Commerce case number, product and country and classifies each notice by lifecycle stage (initiation, determination, order, review). Keyless.
Pricing
from $4.40 / 1,000 results
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Track US antidumping and countervailing duty (AD/CVD) trade-remedy actions as a clean, structured feed. Every Commerce and ITC trade-remedy notice in the Federal Register, with the Commerce case number, the product, the country, the lifecycle stage and the precise event pulled out — keyless, official source, no scraping.
What v1.1 changed (2026-08-01 validation pass)
The headline: the case number now actually works.
case_numberwas null on 99.79% of notices. It was regex-scraped out of the title and abstract, which finds it on 3 of 1,412 live ITA notices. The Federal Register publishes the Commerce case number as a structured field,docket_ids(["A-428-850"]), present on 91.6% of ITA notices — and the actor never requested it. It is now the primary source; a live run measures 88–94% coverage.- A case-number lookup returned zero rows.
caseNumberwas a client-side filter over only the newest page of results, so asking forA-570-049returned nothing — read as "no activity on this case". It is now a server-side docket lookup across the whole archive:A-570-049returns its complete 7-document history, 2016 Initiation → 2017 Order → 2022 Sunset Review → 2023 Continuation. case_typewas wrong on 21.9% of notices. It was inferred from keywords, so a pure-countervailing notice whose boilerplate names both statutes came back"both"(Large Diameter Graphite Electrodes, docketC-570-221), and a plain antidumping notice came backnull(Steel Concrete Reinforcing Bar From Bulgaria, docketA-487-002). It is now derived from the docket prefixes, with keyword inference only as a labelled fallback.- The truncation guard was never read. The API publishes an exact
count; the actor ignored it and pinnedper_pageat 100, which caps a result set at 50 pages × 100 = 5,000 records.per_pageis now 1,000 (reaching 10,000, the API's own hard ceiling) and every row carriesupstream_result_count,upstream_count_saturatedandresults_truncated. - The lifecycle vocabulary was not closed. "Continuation of Antidumping Duty Order"
(62 live notices) landed in
action_type: "Order"— which the code defines as the imposition of an order. Revocation, Termination and Postponement had no home at all, and "Opportunity To Request Administrative Review" — the monthly anniversary-month announcement — was classified as an actual review.action_typeis unchanged (buyers filter on it); the precise event is now carried on the newaction_subtype, and an undeclared value fails the run. - Monitor mode never remembered anything. Its seen-set lived in the platform's default key-value store, which is per-run — so a scheduled monitor found an empty baseline every run and re-emitted the entire feed as unseen. It now uses a named store, keyed to the run's case number, query and agency scope.
- Nine published fields were fetched and thrown away — FR citation, volume, page range, the DATES paragraph, the raw-text URL, the ACTION paragraph, every credited agency, the document type and the abstract itself.
- Nothing was removed or renamed.
Who it's for
- Customs brokers & trade-compliance teams — know the moment a duty order is continued, revoked or amended for a product you import.
- Importers & procurement — watch a specific Commerce case number for the next determination that changes your landed cost.
- Trade lawyers & consultants — a structured docket of every notice on a case, with citations and full-text links.
- Analysts & supply-chain risk — cross-country, cross-product AD/CVD activity in one dataset.
Example input — everything AD/CVD since a date
{ "sinceDate": "2026-01-01", "maxResults": 1000 }
Example input — one Commerce case, whole history
{ "caseNumber": "A-570-049", "maxResults": 200 }
Returns every Federal Register notice on that docket, newest first. This is a server-side docket query, so it reaches the whole archive rather than the last few months.
Example input — watch for duties ending or being extended
{ "actionSubtypes": ["Revocation", "Continuation"], "sinceDate": "2025-01-01" }
Example input — scheduled new-notice alert
{ "query": "steel", "monitor": true, "monitorStoreName": "adcvd-monitor" }
Output fields — all 42 declared fields
The case
| Field | Meaning |
|---|---|
case_number | Primary Commerce case number: A-###-### antidumping, C-###-### countervailing. Read from the Federal Register's structured docket_ids. |
case_numbers | Every case number on the notice. 224 of 1,412 live notices cite more than one; the largest observed is 16 (Non-Oriented Electrical Steel from eight countries). |
case_number_count | How many. |
case_number_source | "docket_ids" (authoritative) or "title_or_abstract" (regex fallback, used on the 8.9% with no published docket). null when none was found. |
docket_ids_raw | The docket array exactly as published, joined with "; ". |
case_type | antidumping, countervailing or both. |
case_type_source | "docket_ids" or "keyword_inference" — keyword inference disagreed with the docket truth on 21.9% of live rows, so this tells you which you are reading. |
The event
| Field | Meaning |
|---|---|
action_type | Coarse lifecycle stage: Initiation, Preliminary Determination, Final Determination, Order, Administrative Review, Sunset Review, Circumvention/Scope Inquiry, Rescission, Other. Unchanged from 1.0. |
action_subtype | The precise event: Continuation, Revocation, Termination, Postponement, Opportunity to Request, Scope Ruling, Amended, Correction, Panel Review, Suspension Agreement, Alignment, Extension, Initiation, Partial Rescission. null for a plain determination. A continuation of an order and the imposition of an order are both action_type: "Order" and differ here. |
review_stage | Preliminary, Final or Amended Final — the distinction action_type collapses for administrative and sunset reviews. |
product | Best-effort merchandise name (the title segment before "From"). |
countries / country_count | Countries named in the case caption. |
title / abstract | The notice's own text. |
document_type | Notice, Rule or Proposed Rule. |
publication_date | YYYY-MM-DD. |
applicable_dates | The notice's DATES paragraph — when the determination bites. 93.7% coverage. |
action_summary | The ACTION paragraph, where FR publishes one (5.5% of notices). |
correction_of | Document this notice corrects, when it is a correction. |
Identifiers and links
document_number, fr_citation (100% coverage), fr_volume, fr_start_page,
fr_end_page, agency, agency_names, html_url, pdf_url, raw_text_url (plain-text
full text, 100% coverage — use it for scope language and company-specific rates),
source_system, retrieved_at.
The per-source outcome contract
null means not checked. false means checked and negative.
| Field | Meaning |
|---|---|
term_antidumping_status | ok, failed, or not_applicable (a docket lookup runs neither term search). |
term_countervailing_status | Same, for the countervailing search. |
run_complete | true only when every search this run needed succeeded. |
search_scope | "term:antidumping+countervailing" or "docket:A-570-049". |
upstream_result_count | How many documents the Federal Register says match — the exact truncation guard. |
upstream_count_saturated | true when that count hit the API's 10,000 ceiling, so the real total is at least that. |
results_truncated | true when fewer notices came back than match. |
query_term | The extra term this run sent. |
query_in_title_or_abstract | The Federal Register searches the full document text. Live-measured: for query: "steel", only 147 of 300 returned notices name steel in the title or abstract. This flag tells you which. null when no query was set. |
ita_only | Whether the run was restricted to the International Trade Administration. Live-measured for 2025+: ITA 1,412 notices, all agencies 1,853, ITC alone 370 — so the default excludes 23.8%, mostly the ITC injury side of the same cases. Set itaOnly: false to include them. |
Inputs that populate the conditionally-null fields (each verified on a live run):
correction_of — {"query":"correction","maxResults":150} (2 rows). action_summary —
any broad run (32 of 150 rows on that same input). action_subtype /
review_stage — any broad run; {"caseNumber":"A-570-049"} returns Continuation,
Correction and Initiation subtypes in seven rows.
case_number_source: "title_or_abstract"term_*_status: "not_applicable" — any
caseNumber lookup. query_in_title_or_abstract — any run with query set.
results_truncated: true — any run where maxResults is below upstream_result_count.
Live drift assertions
An offline fixture cannot see a silently degraded upstream, because the fixture was shaped
from the degraded data. Before any row is billed, the running Federal Register service is
checked and every measured value is logged (DRIFT PROBE: {...}):
- The echoed filter. The envelope restates the search the API actually ran
(
"Documents matching 'antidumping' and from International Trade Administration"). If the term or the agency is missing from that echo, the filter is not being applied and the run fails. Verified live: a bogus agency slug, a bogus condition key and a bogus date operator all return HTTP 400 — butorder=zzzzreturns HTTP 200 and silently reorders the whole result set, so the ordering is asserted separately. - Descending publication date on page 1.
maxResultstruncation takes the head of the list, so a silently ignoredorderwould return an arbitrary subset rather than the newest notices. - A negative control. A nonsense search term must return exactly 0 documents. This is the counterpart to the FDIC echoed-filter class: a filter that has stopped being applied would return the whole corpus here.
- A positive canary.
conditions[docket_id]=A-570-049must return the Ammonium Sulfate From the People's Republic of China case. If the server-side docket filter breaks, everycaseNumberlookup would silently answer with nothing. - Structured docket coverage. At least 40% of the newest ITA notices must yield a case
number from
docket_ids(live baseline 91–94%). If the Federal Register ever drops or renames the field,case_numberwould silently revert to the 0.21% title-regex hit rate. - Closed vocabulary. An
action_typeoraction_subtypeoutside the declared sets fails the run. So does an"Other"share above 35% on a run of 200+ notices (live baseline 3.1%), which would mean Commerce changed its title conventions. - No silent zero. An unknown
actionTypesvalue, a malformedcaseNumber, a filter combination that matches nothing, or acaseNumberwith no notices in scope all fail the run with an explanatory message, rather than billing an empty success that reads as "no trade-remedy activity".
Use as an MCP tool
This actor is callable by AI agents (Claude, Cursor, etc.) via mcp.apify.com. An agent
can look up a Commerce case number and get its whole documented history in one call, or
filter to action_subtype: "Revocation" to find duties that have ended. The
run_complete, results_truncated and case_number_source fields let an agent judge how
much to trust a row without reading logs.
Pricing
Pay per result — one AD/CVD notice = one dataset item. Graduated discounts apply on paid Apify plans. A run that fails a drift assertion, or whose filters match nothing, emits nothing and bills no result events.
FAQ
How do I follow one case? Set caseNumber to the Commerce number, e.g. A-570-049. It
is a server-side docket query across the whole archive.
Why does a query return notices that don't mention the word? Because the Federal
Register searches the full document text, not the title. Every row carries
query_in_title_or_abstract so you can filter to headline matches.
Why is case_number sometimes null? About 8–9% of ITA notices are published with no
docket ID at all — usually general policy or scope-ruling notices that are not tied to one
case. case_number_source tells you whether a value came from the structured field or from
the weaker title regex.
Am I seeing everything? Check upstream_result_count and results_truncated on any
row. The Federal Register itself caps a result set at 10,000 documents and reports count
saturated at that number; narrow with sinceDate or query for an exact figure.
Does this cover the ITC? Not by default. itaOnly defaults to true (Commerce only,
which is who sets the duties). Set it to false to include ITC injury determinations and
sunset institutions — about 24% more notices.
Do I need an API key? No. The Federal Register API is public and keyless.
Related actors
consolidated-screening-list-delta— OFAC / BIS / State restricted-party changes, the sanctions counterpart to this actor's tariff signal.nhtsa-vpic-vin-decoderandgleif-ownership-graph— entity and product identification for the importers and exporters named in these notices.