UK Tariff Watch: Duties, Controls & Measure Changes
Pricing
from $2.00 / 1,000 commodity code checks
UK Tariff Watch: Duties, Controls & Measure Changes
Check UK commodity codes on the official Trade Tariff: duties, controls, conditions, quotas and geographies per code, with changes since the last check. Successful unchanged checks are billed. Unofficial.
Pricing
from $2.00 / 1,000 commodity code checks
Rating
0.0
(0)
Developer
Michal Pšenčík
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
UK Tariff Watchlist: Duty & Measure Changes
Check 1–100 exact declarable UK commodity codes against the official public Trade Tariff API. Each complete stored receipt contains the commodity, all returned import/export measures, the reachable JSON:API resources and any changes since the last delivered snapshot in an optional persistent watch.
The output preserves duty expressions, controls, conditions and components, legal references, additional codes, quota definitions, footnotes, geographical groups and published exclusions. Directions are explicit. A successful unchanged check is billed at the same price as a baseline or revised check.
This is an unofficial factual-data export. It provides no classification, landed-cost arithmetic, customs or legal advice, preference eligibility, quota availability calculation or country filtering. Coverage is the requested UK Global Tariff code only; Northern Ireland/XI is outside scope. Source origin: "eu" describes historical measure provenance, not the origin of your goods.
Input
{"commodityCodes": ["0101210000", "0901210000"],"watchName": "my-uk-portfolio","maxItems": 100,"requestIntervalMs": 2000}
| Field | Meaning |
|---|---|
commodityCodes | 1–100 strings, exactly ten digits after outer trimming. Leading zeroes are preserved. Duplicates are checked once, in first-occurrence order. Default: 0101210000. Numbers, URLs, headings and lists over 100 entries are rejected. |
watchName | Optional persistent namespace, 1–64 ASCII letters, digits, _ or -. Omit/null for stateless checks. Serialize schedules for each name. |
asOf | Optional real YYYY-MM-DD, from 2021-01-01 through today's Europe/London date. Allowed only without a watch. Historical views may be corrected retrospectively. |
maxItems | Integer 1–100, default 100. Caps actually delivered code receipts. SUMMARY lists codes left unattempted. |
requestIntervalMs | Idle time after each completed HTTP attempt, 1500–10000 ms; default 1500. Examples and live tests use 2000. |
Unknown input fields are rejected. There are no credentials, proxies, caller URLs or alternative hosts. Schedule stateless runs at most daily. Apify scheduling and webhooks can consume the results; the actor does not send notifications.
Output
One default-dataset row is one complete code receipt. Measures and deltas are nested within that row, with no separate item charges. Export JSON for the full graph; the table is a compact overview.
| Field | Meaning |
|---|---|
recordId, commodityCode | SHA-256 run/code/date receipt identity and exact requested code. |
schemaVersion, normalizationVersion | Both 1. |
sourceJurisdiction, requestedAsOf | UK_GLOBAL_TARIFF and requested date or null. |
observedAt, previousObservedAt | Successful source observation and prior delivered observation. A reused cached observation retains its original retrieval time. |
changeType, changedFields, changes | baseline, unchanged or revised; sorted entity IDs; whole old/new entity evidence with relative RFC 6901 field paths. Arrays compare as whole normalized values. |
snapshotHash, previousSnapshotHash | Canonical normalized snapshot SHA-256 values. Retrieval times and HTTP headers are excluded. |
snapshot | Commodity attributes/footnotes, measure directions and complete reachable resource graph. Unrelated hierarchy/trade-summary resources are excluded. |
measures | Projection of the same graph: IDs, directions, source origin, type, geography and immediate member IDs, exclusions, raw duty text, conditions/component IDs and source effective dates. |
source | Exact source URL, status 200, original UTF-8 body hash, attribution and licence URL. sourcePublishedAt is null; no authoritative publication timestamp was established. |
coverage, warnings | Complete requested-code response counts, null next page and notReturnedIsDeletion: false; any receipt warnings. |
Duty text such as 121.00 GBP / 1000 kg is preserved, including units and currency. Null remains distinct from an empty string. Published HTML/Markdown stays inert text: escape it when displaying output. Geographical membership and exclusions do not determine preferential-origin eligibility. A resource disappearing from a complete response means no_longer_returned, never a claim of legal repeal or deletion. A wording/audit timestamp change can revise a snapshot without changing any duty.
Free default key-value records SUMMARY and OUTPUT link results and report every original input index, duplicates, not-due checks, errors, delivered/charged counts, HTTP attempts/bytes, stop reasons and remaining codes. Error/status records never enter the default dataset. A 404 does not replace a watch baseline. A valid explicit zero-measure declarable response can produce a receipt; missing relationships cannot.
Watches and delivery
A named watch stores its baseline and cached observations in uk-tariff-watch-v1-<first 40 hex characters of SHA256(watchName)> (59 characters, inside Apify's 63-character store-name limit). The last delivered snapshot advances only after exact receipt readback from the dataset. A row stored with zero charges still advances the baseline; a trimmed/no-op delivery does not. Before delivery, a small per-code recovery checkpoint records the receipt ID and its expected predecessor. Resuming an older run never replaces a newer baseline or resets its due time, even when snapshots and observation times match. A legacy recovered receipt without a checkpoint preserves any existing baseline. An ambiguous delivery stops further work. A post-delivery state error fails the run while preserving delivered rows.
Successfully delivered identities are not due for 24 hours. Successful fetched observations are separately cached for 24 hours and can be reused after failed delivery. A cache write never advances the baseline. Watches support at most 100 identities and 128 MiB of baseline/cache payloads, with no silent eviction. Version mismatches fail rather than resetting state.
Use one active run per watch. The owner lease rejects detected overlap, but KV storage is not a transactional distributed lock: simultaneous starts can race. Cross-run delivery is at least once. A crash between row delivery and state persistence can report a revision again on the next run. Within a resumed run, the deterministic receipt ID is reconciled before another push.
Same-run restarts and late storage writes
This is a known limit. Apify key-value stores have no compare-and-swap, so a storage write sent by the original invocation of a run can land after a same-run restart (a platform migration or a resurrected run) has already read the run's state. Every storage request is sent once, with no client retries and a 20-second client timeout, and a restart that finds an earlier process's journal waits 30 seconds before it reads that journal again and trusts any readback. A write that lands later than that, or one sent by an original invocation that is still running, is not detected. Concretely, it can do two things. A late MANIFEST write can restore a stale watch reservation, so the 128 MiB baseline/cache cap undercounts what is stored. A late RUN-CHECKPOINT-<runId> write can roll the run journal back, for example to before a source 403 stop, so a later process of the same run sends one more source request; a rolled-back journal can likewise forget an unresolved push, which that process could then send again. Callers must let the original invocation and its storage requests stop before restarting a run: run one run at a time per watch, and use a schedule interval longer than the 420-second run timeout. A new run (a new run ID) is not affected by a dead run's journal.
Prices
The Console reference prices are $0.002 per complete stored code check (apify-default-dataset-item) and $0.00005 per platform start unit (apify-actor-start). Successful unchanged checks are billed. Duplicates, not-due checks, errors and free KV output do not incur item events. A failed or zero-item run may still incur a start charge. The platform's displayed pricing governs actual charges; memory above 1 GB can multiply start units.
At one start unit, the event sums for 1/10/100 delivered codes are $0.00205/$0.02005/$0.20005. These are event-fee sums, not measured all-in invoices. Hosted access, spending-cap behavior and cost headroom require prepublication platform validation. Only the two built-in events are used; the code never manually charges them.
Bounds and access
Requests are sequential, with a 20-second attempt timeout, at most two transient retries (2s then 5s backoff, or longer Retry-After), two validated same-route redirects, 125 total attempts, 64 MiB of response traffic and 2 MiB per body. Two consecutive exhausted transient sequences stop source work. Source 403, challenge content or 429 immediately stops further source requests, without bypass; challenge markers are checked in partial and undecodable bodies too, and an encoded HTML document is treated as a challenge. Auth/payment errors and 404s are free errors. Unexpected pagination, unresolved/conflicting resources, partial responses and malformed/media-type errors fail the code free.
Work has a 360-second deadline plus at most 30 seconds for persistence/termination. SDK persistence calls are bounded by that termination deadline; an operation already sent to storage cannot be cancelled. Each storage request is sent once, with the SDK client's retries turned off and a 20-second client timeout, so a dataset push or key-value write whose answer is lost is never resent behind the actor's back. A hard kill can leave the latest SUMMARY and free RUN-CHECKPOINT-<runId> journal. Restarting that run restores its original deadline, counters, receipt and charge accounting, source stops, Retry-After window, pacing and retry/redirect allowances before source work. The item cap and spending limit are recomputed from the dataset and the platform's charged count before every fetch and every push, so a receipt stored just before a kill still counts against the run's maximum charge. A push or state write whose result is unknown (a timeout or a lost answer) is never sent again in the same run. Until readback proves it landed, the run stops with delivery_uncertain or state_write_uncertain, and SUMMARY lists that code's recordId so you can check the dataset. Start a new run to check those codes again. A code whose retries were exhausted is recorded as an error in the same journal write, so a restart never requests it again; a restart after the third attempt already fetched a code ends that code as an error rather than sending a fourth request. Confirmed receipts are counted before any watch read, so a watch outage preserves delivery totals. An unreadable or mismatched journal stops work without overwriting the previous journal or SUMMARY. An interrupted in-flight request reserves its unread body allowance against the traffic budget; after recovery responseBytes can therefore conservatively exceed bytes actually read. Rows over 4 MiB or normalized baselines over 1 MiB fail free and are never truncated. MaxItems/deadlines can leave codes in SUMMARY for explicit caller continuation. No automatic retry run is scheduled.
The public source is https://www.trade-tariff.service.gov.uk/api/v2/commodities/{code}. Availability from one machine does not guarantee Apify/US datacenter access or an SLA. No browser, login, API key, cookies, proxy or challenge workaround is used. Source data is available directly from the free native API.
Source: HMRC UK Trade Tariff; Crown copyright, Open Government Licence v3.0 unless otherwise stated. See the official API field guide. This actor is unaffiliated with HMRC. It does not target personal data; users control their watch inputs, Apify storage retention and downstream processing. Source resource text is preserved as published and may include incidental public contact information.