UK Importers and Exporters: HMRC Trade Data
Pricing
from $2.00 / 1,000 traders
UK Importers and Exporters: HMRC Trade Data
Find UK businesses that imported or exported goods by HS code and month, look companies up, and get alerts on traders new to a commodity. HMRC UK Trade Info data under the OGL. Names that are not clearly an organisation's are left out. Not affiliated with HMRC.
Pricing
from $2.00 / 1,000 traders
Rating
0.0
(0)
Developer
Russell Yapp
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
10 hours ago
Last modified
Categories
Share
Not affiliated with HMRC.
This Actor returns one row per trader, flow (imports or exports) and month, with the commodity codes that trader dealt in. The data comes from HMRC UK Trade Info, the monthly lists of UK importers and exporters published by HMRC, published under the Open Government Licence v3.0. Names that are not clearly an organisation's are left out and counted, because sole traders are people.
What a first run costs. The input is prefilled: search HS code 8419 in the latest month HMRC has published, maxItems 20. That costs at most 20 × $0.002 + $0.005 = $0.045. The prefilled run reads the latest month's bulk files (importers and exporters) and makes no API call.
To get more rows, raise maxItems (Maximum rows) in the input. It goes up to 100,000. maxItems caps the trader rows returned. Each row costs $0.002, and the $0.005 run fee is charged on top once the run has read data, so a run costs at most maxItems × $0.002 + $0.005.
What you get
One row per trader, flow and month. A missing value is null (or [] for lists), never an absent key.
An illustrative row (the name, key and district are invented, not a real trader's):
{"traderId": null,"traderKey": "0a1b2c3d4e5f6071","name": "Example Trading Limited","postcodeDistrict": "ZZ1","flow": "imports","month": "2026-07","cn8Codes": ["84198100","84199085"],"hs6Codes": ["841981","841990"],"hs4Codes": ["8419"],"otherCodes": [],"source": "bulk","publishedAt": "2026-09-07T11:14:43Z","matchType": "search","alertFingerprint": null}
Modes
Set mode to search (the default), lookup or alert. flows is ["imports", "exports"] by default; give one of them to read only that flow.
Search
The traders that dealt in some HS codes in a month or a range of months.
{"mode": "search","hsCodes": ["8419"],"flows": ["imports", "exports"],"monthFrom": "2026-01","monthTo": "2026-06","maxItems": 200}
hsCodes: 1 to 20 codes of 2, 4, 6 or 8 digits (chapter, heading, subheading or CN8). A code matches every 8-digit code that starts with it.monthFromandmonthTo(YYYY-MM): give both or neither. With neither, the search reads the latest month HMRC has published.- The latest published month is read from HMRC's bulk file. Older months are read from the HMRC API.
- Each row lists only the codes that matched.
Lookup
What named companies imported or exported.
{"mode": "lookup","companies": ["Example Trading Limited", "123456"],"flows": ["imports"],"monthFrom": "2026-01","monthTo": "2026-06","maxItems": 100}
companies: 1 to 20 entries. Each is a company name, or part of one (at least 3 characters), or an HMRC trader id (digits only).- A name matches any published name that contains it. Up to 10 traders are taken per name; if there are more, the count is in
RUN_SUMMARY.namesWithMoreMatches. - Without
monthFromandmonthTo, lookup covers the 12 months to the latest published month. - Lookup reads the HMRC API. Each row lists every code the trader dealt in that month.
- Lookup does not match a name that fails the organisation test. Names that found nothing are counted in
RUN_SUMMARY.companiesNotFound.
Alert
Traders that are new to your HS codes each time HMRC publishes a month.
{"mode": "alert","alertId": "heat-exchangers","hsCodes": ["8419"],"flows": ["imports"],"lookbackMonths": 12}
alertIdis yours to choose: 1 to 40 characters of lower-case letters, digits and hyphens, starting and ending with a letter or digit.- An alert's
hsCodesare fixed. A run with other codes for the samealertIdis refused before anything is read; use a newalertId. lookbackMonths(1 to 24, default 12): a trader is new when it did not trade your codes in that many months before.monthFromandmonthToare refused in alert mode: an alert reads each new month as it is published.- State is kept in a key-value store named
uk-traders-alert-<alertId>in your own Apify account. It holds hashes, not names. - The first run reads the latest month, records its traders and sends no rows. New traders are sent from the next month on. The first run is charged the
runevent, because it read data. The same applies to a flow you add to an alert later, and to an alert that has not run for longer thanlookbackMonths: that month is recorded, not sent. - Later runs read every month published since the last run (up to
lookbackMonths) and send the traders not seen in thelookbackMonthsbefore. A trader is sent once peralertId, and again only if it comes back after that long. - A run with no new month reads no trader data and costs nothing. You can schedule an alert daily.
- If
maxItemsor your spending limit cuts a run short, the unsent traders are sent on the next run. In alert modemaxItemsis at most 5,000. - An alert remembers up to 20,000 traders. If your codes match more than that in the first month read, the run stops with
tooBroad, saves nothing and charges nothing: use narrower codes. Later months forget the oldest traders first, and the status says how many. - A second run for the same
alertIdthat starts while one is active stops before reading anything.
Output fields
| Field | Type | Meaning |
|---|---|---|
traderId | integer or null | HMRC's trader id on rows read from the API. null on rows read from the bulk file, which has no id |
traderKey | string | A 16-character hash of the published name and the postcode's outward code. The same trader has the same key in the bulk file and the API, unless its name or postcode differs between the two |
name | string | The trader's name as published. Names that are not clearly an organisation's are withheld |
postcodeDistrict | string or null | The outward code of the postcode only (for example ZZ1), never the full postcode |
flow | "imports" or "exports" | The direction of trade |
month | string | The month of trade, YYYY-MM |
cn8Codes | array of strings | 8-digit commodity codes. In search and alert, only the codes that matched your hsCodes |
hs6Codes | array of strings | The 6-digit codes of cn8Codes |
hs4Codes | array of strings | The 4-digit headings of cn8Codes |
otherCodes | array of strings | Two-digit chapter codes (such as 99) that the bulk file lists for the trader |
source | "bulk" or "api" | Where the row was read from |
publishedAt | string or null | The bulk file's last-modified time, ISO 8601 UTC. null on API rows |
matchType | "lookup", "search" or "alert" | The mode that returned the row |
alertFingerprint | string or null | Set in alert mode only; null otherwise |
There is no address field.
Pricing
Pay per event. Both events are flat prices.
| Event | Charged | Price |
|---|---|---|
run | Once per run that read trader data | $0.005 |
trader | Each row returned | $0.002 |
Examples: a 20-row search costs $0.045. A 1,000-row search costs $2.005. A monthly alert that finds 30 new traders costs $0.065.
The run event is charged once a run has read trader data: a bulk file or an answer from the HMRC API. It is charged even if the run returns no rows.
The run event is not charged, and nothing else is, when:
- the input is refused (the run ends as succeeded, with the reason as its status message and
RUN_SUMMARY.statusrefused, and nothing is read); - the pricing is not set as this Actor expects (it needs a flat price for both events, and no per-item dataset price), so the run refuses to start and fails;
- an alert's saved memory was written by a different version of the Actor (the run fails, and nothing is read; use a new
alertId); - an alert finds another run of the same
alertIdactive (locked), or thealertIdwas set up for otherhsCodes; - an alert's codes match too many traders to remember (
tooBroad); - an alert finds no new month since its last run (
noNewMonth). Checking for a new month reads only HMRC's bulk-data page, which is not trader data; - an alert loses its lock part-way (
lockLost): it sends and charges nothing.
The first run of an alert reads the month and is charged run, but sends no rows.
A run can also end with an incomplete note after run was charged: one flow or month was read and another could not be (for example the exports file failed while imports parsed). The run is not marked failed, because data was read; incomplete in RUN_SUMMARY says what was missed. A run that read nothing because every part failed is marked failed, and charges nothing.
Rows are charged only as they are stored. If you set a maximum charge on the run and it is reached, the run stops, and RUN_SUMMARY.chargeLimitReached is true.
Personal data
Sole traders are people, and HMRC publishes their names next to companies'. This Actor does not return them.
- Names. A name is returned only if it carries an organisation marker, such as Limited, Ltd, PLC, LLP, a foreign company form, or a public-body word. A name without one is withheld, and so is a name with a title (Mr, Mrs, Dr) or a trading-as name unless a legal form follows the title or comes before the trading-as name. A name that holds a contact or an address (a "C/O" or "FAO" contact, a postcode, or other words after the company's legal form) is withheld too. In search and alert it is left out and counted in
RUN_SUMMARY.withheldPersons. Lookup never matches it: a company input that matches only such names is reported exactly as one that matches nothing. - Addresses. Address lines are never output or stored. HMRC's bulk files carry five address columns, which the Actor reads past and ignores; name and id lookups ask HMRC's API for the trader's id, name and postcode only, so they receive no address lines. Only the outward code of the postcode is output.
- HMRC's removals. HMRC removes a trader who asks, from the following month's publication. It does not apply this to months already published. Every run reads HMRC's current publication, and no trader name or address is kept between runs. The alert store holds only hashes. So once HMRC stops publishing a trader, this Actor stops returning it, from the month after the request.
- Asking us to remove a trader. Email info@yappman.com with the trader's name as it appears in the results (or its HMRC trader id). We reply to removal requests within one month, and each accepted request is a reviewed change to our removal list. We keep a removal list of our own, alongside HMRC's. Traders on it are never returned and are counted in
RUN_SUMMARY.removedByRequest. - The Open Government Licence does not cover personal data, so sole traders' details are not ours to republish.
Limits
- HS codes: 1 to 20 per run, of 2, 4, 6 or 8 digits.
- Companies: 1 to 20 per run (lookup).
- Months: at most 12 per run, from 2016-01.
monthFromandmonthToare given together. - Freshness: the latest month is about 5 weeks behind. For example, July 2026 was published on 7 September 2026. A month that is not yet published is listed in
RUN_SUMMARY.notPublished. - API queries: a search makes at most 60 (older months × HS codes × flows). A wider search is refused before anything is read, and nothing is charged. Split the months or the codes across runs.
- API use: each run is limited to 200 requests and 15 minutes. Requests are paced at one every 1.5 seconds, inside HMRC's limit of 60 a minute. Each API query reads at most 20 pages of 1,000 items; a query that hits the cap is listed in
RUN_SUMMARY.incomplete. - Rate limit: if HMRC answers 429 or 503, the run stops using the API at once. It does not wait. Rows already read are returned, and the status message says when to retry, for example
rate-limited by HMRC: retry after 14:32 UTC.RUN_SUMMARY.retryAfterhassecondsanduntil. A 403 also stops API use and is never retried. maxItems: 1 to 100,000. The default is 1,000 when left out of an API call; the Console form prefills 20. Rows beyond it are counted inRUN_SUMMARY.truncatedByMaxItems.lookbackMonths(alert): 1 to 24.- The input takes no URLs, headers or query strings: the Actor builds every request itself.
Run summary
Every run writes a RUN_SUMMARY record to its key-value store. Main fields:
| Field | Meaning |
|---|---|
status | ok, refused (input rejected; reason says why; the run ends as succeeded and nothing is charged; a pricing set up wrongly, or an alertId from a different version of the Actor, makes it fail), failed, or for alerts locked, lockLost, tooBroad or noNewMonth |
mode | The mode that ran |
pushed | Rows returned |
readData | Whether the run read trader data and so owes the run fee. An alert that stopped as tooBroad or lockLost reports false even though it opened files, because it charges nothing |
runCharged | Whether the run event was charged |
ownerRun | true only for runs by the Actor owner's own account, which are not charged; false for every other run |
chargeLimitReached | Whether your spending limit stopped the run |
latestPublished | The latest month HMRC has published, per flow |
monthsRead | The months read, per flow (lookup: window) |
notPublished | Months you asked for that HMRC has not yet published |
incomplete | Parts of the run that were not read, and why |
retryAfter | If HMRC rate-limited the run: seconds and until (UTC) |
withheldPersons | Traders left out because the name has no organisation marker |
removedByRequest | Traders left out because they asked us to remove them |
matched | Rows found before maxItems was applied |
truncatedByMaxItems | Rows found but not returned because of maxItems |
companiesNotFound, namesWithMoreMatches | Lookup only: names with no match, and names with more than 10 matches |
api | API use: requests, answers, refusals, stopped, retryAfter, statuses |
bulkBytes | Bytes read from HMRC's bulk site |
firstRun, seeded, emitted, candidates, lastMonth, ledgerPruned | Alert only: whether this was the first run, the flows read for the first time (recorded, not sent), rows sent, new traders found, the last month recorded per flow, and how many of the oldest traders were forgotten because the alert's memory (1 MB) was full |
attribution | The licence statement below |
Licence and attribution
The data is HMRC UK Trade Info, published under the Open Government Licence v3.0. Please keep this attribution:
Contains public sector information licensed under the Open Government Licence v3.0 (HMRC, UK Trade Info).
Sources: HMRC's UK Trade Info bulk files and API only. No proxies are used.