<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: iCustoms</title>
    <description>The latest articles on DEV Community by iCustoms (@icustoms12).</description>
    <link>https://dev.to/icustoms12</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1232603%2F6a981ff1-ca81-485d-bb0f-9c58ae141981.png</url>
      <title>DEV Community: iCustoms</title>
      <link>https://dev.to/icustoms12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/icustoms12"/>
    <language>en</language>
    <item>
      <title>Automating Intrastat Returns in Ireland From ERP Data</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Tue, 13 Oct 2026 08:22:17 +0000</pubDate>
      <link>https://dev.to/icustoms12/automating-intrastat-returns-in-ireland-from-erp-data-o52</link>
      <guid>https://dev.to/icustoms12/automating-intrastat-returns-in-ireland-from-erp-data-o52</guid>
      <description>&lt;p&gt;You can automate Intrastat returns in Ireland by extracting monthly EU movements from your ERP, mapping them to the five fields Revenue expects, validating codes and values before upload and filtering out Great Britain trade. Submission is the easy part. Reshaping ERP export data the same way every month is the real engineering problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Data Model
&lt;/h2&gt;

&lt;p&gt;Each movement on the return needs five fields. Here is where they usually live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nature of transaction (sale, return, repair): order or document type&lt;/li&gt;
&lt;li&gt;8-digit CN commodity code: item master&lt;/li&gt;
&lt;li&gt;Partner member state: ship-from or ship-to country&lt;/li&gt;
&lt;li&gt;Net mass or supplementary quantity: item master or delivery, depending on the commodity&lt;/li&gt;
&lt;li&gt;Statistical value: invoice or delivery value&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Validation Must Happen Upstream
&lt;/h2&gt;

&lt;p&gt;Revenue's Return Preparation Facility (RPF) and its arrival and dispatch templates do not validate commodity codes or value consistency. Whatever your pipeline sends is what gets filed. The rules these checks enforce come from the full guide to &lt;a href="https://www.icustoms.ai/blogs/intrastat-reporting-ireland/" rel="noopener noreferrer"&gt;Intrastat reporting for Irish importers and exporters&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Minimal Pre-Filing Check
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;THRESHOLD_EUR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;750_000&lt;/span&gt;  &lt;span class="c1"&gt;# confirm the current figure with Revenue
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cn_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cn_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CN code must be 8 digits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;partner_state&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB trade goes on AIS/AES, not Intrastat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;net_mass_kg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;supp_qty&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Net mass or supplementary quantity missing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;must_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction_total_eur&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;direction_total_eur&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;THRESHOLD_EUR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keep Separate Totals Per Direction
&lt;/h2&gt;

&lt;p&gt;Store arrivals and dispatches as two running totals. Each crosses the threshold on its own, and the obligation starts from that point, not retroactively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull Codes From One Master Record
&lt;/h2&gt;

&lt;p&gt;If a product carries different codes on AIS, AES and Intrastat, the datasets stop matching. Read the CN code from a single source for every filing.&lt;/p&gt;

&lt;p&gt;Want this pipeline without building and maintaining it yourself? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>intrastat</category>
      <category>ai</category>
      <category>automation</category>
      <category>python</category>
    </item>
    <item>
      <title>Pre-Submission Checks for Irish AIS Customs Declarations</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Mon, 12 Oct 2026 11:17:53 +0000</pubDate>
      <link>https://dev.to/icustoms12/pre-submission-checks-for-irish-ais-customs-declarations-4epp</link>
      <guid>https://dev.to/icustoms12/pre-submission-checks-for-irish-ais-customs-declarations-4epp</guid>
      <description>&lt;p&gt;AIS declaration validation is the most practical way to cut customs penalty risk in Ireland. Most penalties trace back to data problems a pre-submission check can catch: an inconsistent commodity code, an origin claim with no evidence attached or a declared value that doesn't reconcile with the invoice. This post outlines a validation workflow for declarations filed through Revenue's Automated Import System (AIS).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Errors That Replicate
&lt;/h2&gt;

&lt;p&gt;Revenue's Audit and Examination Programme reviews declarations after clearance and can look back across a business's history. A defect in your data pipeline, such as the wrong code mapped to a product, is not a single error. It is replicated on every filing that touches that product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four Checks to Run Before Submission
&lt;/h2&gt;

&lt;p&gt;Each check below maps to one of the four violations behind most &lt;a href="https://www.icustoms.ai/blogs/ireland-customs-penalties/" rel="noopener noreferrer"&gt;Irish customs penalty triggers&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Classification consistency
&lt;/h3&gt;

&lt;p&gt;Compare the commodity code on the new declaration with the codes used for the same product in previous filings. Flag any change for human review.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Origin evidence
&lt;/h3&gt;

&lt;p&gt;If a preferential rate is claimed, confirm that proof of origin is attached and still current.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Value reconciliation
&lt;/h3&gt;

&lt;p&gt;Check declared values against the commercial invoice and packing list. They should reconcile every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Licence requirements
&lt;/h3&gt;

&lt;p&gt;Flag restricted goods that need a licence and hold submission until one is recorded.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Validation Sketch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;issues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="n"&gt;prior_codes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;codes_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prior_codes&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commodity_code&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prior_codes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Commodity code differs from previous filings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;preference_claimed&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_current_origin_proof&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Preferential origin claimed without proof of origin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;reconciles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customs_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Declared value does not reconcile with invoice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requires_licence&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;licence_ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Licence required but not recorded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;issues&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling a NOT_RELEASED Status
&lt;/h2&gt;

&lt;p&gt;If a declaration is flagged before release and returns a NOT_RELEASED status, treat it as a priority. An unresolved NOT_RELEASED outcome is one of the most direct routes into a penalty discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Log Every Correction
&lt;/h2&gt;

&lt;p&gt;Keep a consistent record of every declaration and every fix. Errors you find and correct yourself are viewed very differently from errors a Revenue review finds first.&lt;/p&gt;

&lt;p&gt;Want to see this kind of validation logic running on live AIS declarations? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>customs</category>
      <category>compliance</category>
      <category>automation</category>
      <category>python</category>
    </item>
    <item>
      <title>Modelling the Irish Customs Declaration Lifecycle in AIS</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Fri, 09 Oct 2026 11:00:23 +0000</pubDate>
      <link>https://dev.to/icustoms12/modelling-the-irish-customs-declaration-lifecycle-in-ais-5d0e</link>
      <guid>https://dev.to/icustoms12/modelling-the-irish-customs-declaration-lifecycle-in-ais-5d0e</guid>
      <description>&lt;p&gt;An Irish customs declaration moves through a defined set of statuses in Revenue's AIS (imports) and AES (exports). Once submitted, it is registered, then accepted after automated checks. Revenue risk-scores it, and it is either released or selected for a documentary or physical control. Treating that lifecycle as a state model helps forwarders build reliable, alert-driven workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Status Model
&lt;/h2&gt;

&lt;p&gt;Each status tells you who has to act next. Here is a simple reference table you can drop into a tracking tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STATUS                  MEANING                                        WHO ACTS
REGISTERED              Declaration received by Revenue                Wait
ACCEPTED                Passed initial automated checks                Wait
UNDER_CONTROL           Selected for documentary or physical checks    Monitor closely
AWAITING_SUPPLEMENTARY  More information or documents needed           You
RELEASED                Cleared, goods can be released                 Move the goods
NOT_RELEASED            Not cleared, goods cannot be released          Investigate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A control is not automatically a problem. It does need to be understood rather than ignored, so route &lt;code&gt;UNDER_CONTROL&lt;/code&gt; and &lt;code&gt;AWAITING_SUPPLEMENTARY&lt;/code&gt; straight to a person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate Before You Submit
&lt;/h2&gt;

&lt;p&gt;Most rejections and checks trace back to data that was wrong before submission. The &lt;a href="https://www.icustoms.ai/blogs/ireland-customs-freight-forwarders-guide/" rel="noopener noreferrer"&gt;AIS and AES filing guide for Irish freight forwarders&lt;/a&gt; lists the common causes, and they translate neatly into pre-submission checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pre_submission_checks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;issues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eori&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registered_eori&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EORI does not match registration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;claims_preference&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_origin_proof&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Preference claimed without proof of origin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wants_pva&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pva_elected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Postponed VAT Accounting not elected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;export&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lodged_before_departure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AES declaration must be lodged before departure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authorisations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# AEO, special procedures, PVA
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;referenced&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; authorisation not referenced&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;issues&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is illustrative logic, not Revenue's rule set, but it mirrors the mistakes the source guide flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set Realistic Timing Alerts
&lt;/h2&gt;

&lt;p&gt;Most declarations that are not flagged clear within minutes to hours. A documentary or physical control can add days. Alert on anything sitting in &lt;code&gt;ACCEPTED&lt;/code&gt; longer than your normal window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan for AIS V2
&lt;/h2&gt;

&lt;p&gt;AIS V2 introduces Centralised Clearance for Import and a revised Annex B data structure. If you map data into AIS, plan for that structural change now.&lt;/p&gt;

&lt;p&gt;Want to see pre-submission validation running on real AIS and AES workflows? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt; of iAIS and iAES.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>tooling</category>
      <category>logistics</category>
      <category>customs</category>
    </item>
    <item>
      <title>TSS Portal Validation Rules: Rule-Based vs Content Checks</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Thu, 08 Oct 2026 10:32:28 +0000</pubDate>
      <link>https://dev.to/icustoms12/tss-portal-validation-rules-rule-based-vs-content-checks-3475</link>
      <guid>https://dev.to/icustoms12/tss-portal-validation-rules-rule-based-vs-content-checks-3475</guid>
      <description>&lt;p&gt;TSS Portal validation rules are deterministic checks that confirm a customs declaration's structure: required fields are present, codes exist, formats match and references resolve. They cannot test semantic correctness. A valid commodity code can still be the wrong code for the goods, which is why a content validation layer before the Portal matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Portal's rules are layered
&lt;/h2&gt;

&lt;p&gt;Validation runs at two scopes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Field level:&lt;/strong&gt; some checks fire as each field is filled in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declaration level:&lt;/strong&gt; others run across the whole declaration before submission.
The rule set covers six types: format and completeness, goods-line business rules, consignment-level checks, item-level controlled goods, CERTEX certificate matching, and scheme and authorisation checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What a rule can and can't assert
&lt;/h2&gt;

&lt;p&gt;A rule can assert presence, existence, format and reference. It can't assert truth, which is why three classes of error pass the &lt;a href="https://www.icustoms.ai/blogs/tss-customs-data-validation/" rel="noopener noreferrer"&gt;TSS Portal validation rules&lt;/a&gt; untouched.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Why the rule passes it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wrong commodity code for the goods&lt;/td&gt;
&lt;td&gt;The code exists and is current&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certificate that doesn't cover the consignment&lt;/td&gt;
&lt;td&gt;The reference matches the expected format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description too vague to classify&lt;/td&gt;
&lt;td&gt;The field is complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Adding a content validation layer
&lt;/h2&gt;

&lt;p&gt;Think of the workflow as a pipeline with two validation stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;declaration
  -&amp;gt; content validation (before the Portal)
       commodity code     vs goods description
       certificate ref    vs certificate data
       preference claim   vs evidence on file
  -&amp;gt; TSS Portal rules
       format, completeness, goods-line, consignment,
       controlled goods, CERTEX, scheme/authorisation
  -&amp;gt; submission
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI-powered validation handles the first stage by reading content instead of checking format. The Portal then handles the second.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why order matters
&lt;/h3&gt;

&lt;p&gt;Automating submission without validating first produces wrong declarations faster. Catching an error upstream costs less than handling a rejection downstream.&lt;/p&gt;

&lt;p&gt;Want to see a content validation layer running ahead of TSS? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tss</category>
      <category>portal</category>
      <category>validation</category>
      <category>ai</category>
    </item>
    <item>
      <title>Validating TSS Controlled Goods Data Before Submission</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Wed, 07 Oct 2026 11:03:44 +0000</pubDate>
      <link>https://dev.to/icustoms12/validating-tss-controlled-goods-data-before-submission-1he1</link>
      <guid>https://dev.to/icustoms12/validating-tss-controlled-goods-data-before-submission-1he1</guid>
      <description>&lt;p&gt;TSS controlled goods data validation means checking, before you submit, that every controlled line carries the right licence or certificate, the correct document and status codes, item-level data and, for SPS goods, a Net Mass. It also means confirming the reference numbers match the certificate itself, because health certificates are checked against CERTEX and a mismatch is likely to trigger an inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where controlled goods logic lives
&lt;/h2&gt;

&lt;p&gt;Control status isn't a field you set. It comes from the measures and conditions attached to a commodity code on the Northern Ireland Online Tariff, for the correct country of origin, plus any footnotes on the commodity page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data model for a controlled goods line
&lt;/h2&gt;

&lt;p&gt;A controlled line needs more fields than a standard movement. The field list below follows iCustoms' write-up on &lt;a href="https://www.icustoms.ai/blogs/tss-licensed-regulated-goods/" rel="noopener noreferrer"&gt;TSS customs data for controlled goods&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;When it applies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Consignment and item-level entry summary data&lt;/td&gt;
&lt;td&gt;Controlled goods (standard movements need consignment level only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document code and status code&lt;/td&gt;
&lt;td&gt;Every certificate or licence (GOV.UK Appendix 5A and 5B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;National Additional Code&lt;/td&gt;
&lt;td&gt;Where the commodity code lookup returns one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Net Mass at item level&lt;/td&gt;
&lt;td&gt;All SPS controlled goods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Goods Domestic Status = &lt;code&gt;NIDOM&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;GB to NI domestic movements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status code &lt;code&gt;XW&lt;/code&gt; with "Waiver claimed"&lt;/td&gt;
&lt;td&gt;Products of animal origin or high-risk food where a CHED isn't required&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Image suggestion:&lt;/strong&gt; Image 4, "One Mismatch, One Outcome" | Alt text: Validation outcome where a declaration matching its certificate clears and a mismatch is referred&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A pre-submission check in pseudocode
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;measures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ni_online_tariff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commodity_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;measures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require_document&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;          &lt;span class="c1"&gt;# read conditions and footnotes too
&lt;/span&gt;        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;document_code&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;document_ref&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reference&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;net_mass&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB_TO_NI_DOMESTIC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goods_domestic_status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NIDOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting TSS controlled goods data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inspection referral:&lt;/strong&gt; compare the declaration reference with the health certificate, since CERTEX checks one against the other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missed control:&lt;/strong&gt; re-read the footnotes on the commodity page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unexpected measures:&lt;/strong&gt; re-run the lookup with the correct country of origin.
Want to see these checks run automatically inside a TSS workflow? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tss</category>
      <category>ai</category>
      <category>automation</category>
      <category>logistics</category>
    </item>
    <item>
      <title>B2B Parcel Declaration Workflow: Decision Logic for TSS</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Tue, 06 Oct 2026 10:29:31 +0000</pubDate>
      <link>https://dev.to/icustoms12/b2b-parcel-declaration-workflow-decision-logic-for-tss-3k34</link>
      <guid>https://dev.to/icustoms12/b2b-parcel-declaration-workflow-decision-logic-for-tss-3k34</guid>
      <description>&lt;p&gt;A B2B parcel declaration workflow for Northern Ireland is a short chain of decisions: classify the movement, test whether the goods are at risk, check UKIMS cover, then route the data to the right declaration. If you build or maintain systems that feed TSS, it helps to model this logic explicitly so every rule is easy to trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Classify the Movement
&lt;/h2&gt;

&lt;p&gt;Only business to business parcels enter this workflow. Consumer parcels for personal use need no customs declaration, and correspondence sits outside the rules entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Model At-Risk Status and Route
&lt;/h2&gt;

&lt;p&gt;Goods can count as not at risk on duty rates alone, or move under UKIMS held by either party. Here is the logic as Python-style pseudocode, based on the published rules for &lt;a href="https://www.icustoms.ai/blogs/tss-b2b-parcels-northern-ireland/" rel="noopener noreferrer"&gt;declaring B2B parcels through TSS&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;not_at_risk_by_duty_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in_gb_free_circulation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eu_rate&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_outside_eu_uk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# UK rate no more than 3 points below the EU rate
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uk_rate&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eu_rate&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;declaration_route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ukims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_ukims&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_ukims&lt;/span&gt;  &lt;span class="c1"&gt;# one side is enough
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ukims&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at_risk_of_moving_to_eu&lt;/span&gt; \
            &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;goods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;for_uk_end_consumers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IMMI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# no full declaration, no duty
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FULL_DECLARATION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# EU-rate duty may apply
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Pick the EORI Prefix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;eori_prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;established_in_ni&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixed_place_in_ni&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Pass the Right Data
&lt;/h2&gt;

&lt;p&gt;In TSS, goods that qualify under UKIMS go through Internal Market Movement Information (IMMI). Others need a full declaration. Either way, goods are still categorised as Standard, Category 1 or Category 2. If a carrier declares for you, pass it the UKIMS authorisation number and the associated EORI number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Store the Evidence
&lt;/h2&gt;

&lt;p&gt;TSS does not decide UKIMS eligibility or at-risk status. Store the evidence behind each decision for five years against the movement it supports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge Cases Worth Coding For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mixed order books:&lt;/strong&gt; flag each parcel as B2B or consumer, because carriers handle the two differently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entry summary declarations:&lt;/strong&gt; only some parcel movements need one, so don't reuse a freight rule here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declaration channel:&lt;/strong&gt; TSS, a carrier's service or a customs intermediary can submit, and each must apply the same duty-rate, UKIMS and processing conditions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UKIMS-EIDR users:&lt;/strong&gt; businesses declaring with their own software can apply the same UKIMS conditions to parcel movements.
Prefer not to build this logic yourself? iCustoms runs the UKIMS eligibility and not-at-risk checks against your goods data for you. &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>logistics</category>
      <category>ai</category>
      <category>automation</category>
      <category>python</category>
    </item>
    <item>
      <title>Modelling the TSS At-Risk Decision Logic in Pseudocode</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Mon, 05 Oct 2026 10:32:08 +0000</pubDate>
      <link>https://dev.to/icustoms12/modelling-the-tss-at-risk-decision-logic-in-pseudocode-4gag</link>
      <guid>https://dev.to/icustoms12/modelling-the-tss-at-risk-decision-logic-in-pseudocode-4gag</guid>
      <description>&lt;p&gt;The TSS at-risk decision logic can be modelled as an ordered set of rules. Hard stops come first and always return at risk. The duty-rate test comes next and can return not at risk without any authorisation. UKIMS conditions follow. Anything left over is at risk and pays the applicable EU rate of duty.&lt;/p&gt;

&lt;h2&gt;
  
  
  The inputs the decision needs
&lt;/h2&gt;

&lt;p&gt;If you build or maintain tools that prepare GB to NI declarations, these are the fields the rules depend on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;origin&lt;/code&gt;: &lt;code&gt;GB_FREE_CIRCULATION&lt;/code&gt; or &lt;code&gt;OUTSIDE_EU_UK&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eu_rate&lt;/code&gt; and &lt;code&gt;uk_rate&lt;/code&gt;: duty rates, compared in percentage points&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;processed_in_ni&lt;/code&gt;: whether the goods will be processed in Northern Ireland before sale or use&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;processing_condition_met&lt;/code&gt;: turnover under £2 million, quota sheepmeat, poultry or beef, or an approved purpose&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trade_remedies&lt;/code&gt;: whether EU trade remedies such as anti-dumping or countervailing duty apply&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;importer_holds_ukims&lt;/code&gt; and &lt;code&gt;uk_end_consumer&lt;/code&gt;
## The decision function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The order below follows the &lt;a href="https://www.icustoms.ai/blogs/tss-at-risk-not-at-risk-customs-duty/" rel="noopener noreferrer"&gt;TSS at-risk decision rules&lt;/a&gt; published by iCustoms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;at_risk_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Hard stops: UKIMS cannot offset these
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trade_remedies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processed_in_ni&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processing_condition_met&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OUTSIDE_EU_UK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eu_rate&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uk_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# Duty-rate test: no authorisation needed
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB_FREE_CIRCULATION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eu_rate&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NOT_AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OUTSIDE_EU_UK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uk_rate&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eu_rate&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NOT_AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# UKIMS route
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;importer_holds_ukims&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uk_end_consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NOT_AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Image suggestion:&lt;/strong&gt; Image 3, &lt;em&gt;Two Routes to Not at Risk&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Alt text:&lt;/strong&gt; Flow showing the duty-rate test and UKIMS authorisation as two routes to not at risk, with processing and trade remedy blocks&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Mapping the result to duty
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;duty_basis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AT_RISK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Applicable EU rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GB_FREE_CIRCULATION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No duty&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UK duty&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where TSS fits in the workflow
&lt;/h2&gt;

&lt;p&gt;TSS does not run this logic for you. It is where the result is declared, using the Additional Information code, and where the Trader Goods Profile and IMMI or declaration data come together. The judgement and the evidence behind it stay with the trader.&lt;/p&gt;

&lt;p&gt;That evidence means commercial receipts and invoices, VAT invoices, commercial contracts and, where relevant, Northern Ireland end-use declarations, kept for five years and accessible in the UK.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note on scope
&lt;/h2&gt;

&lt;p&gt;This is a simplified model to show the rule order. It explains the logic; it does not replace a proper assessment of each movement.&lt;/p&gt;

&lt;p&gt;Building GB to NI declaration workflows and want to see how iCustoms approaches them? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tss</category>
      <category>ai</category>
      <category>logistics</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>TSS Trader Goods Profile Fields: A Technical Breakdown</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Fri, 02 Oct 2026 08:04:04 +0000</pubDate>
      <link>https://dev.to/icustoms12/tss-trader-goods-profile-fields-a-technical-breakdown-2j82</link>
      <guid>https://dev.to/icustoms12/tss-trader-goods-profile-fields-a-technical-breakdown-2j82</guid>
      <description>&lt;p&gt;A TGP entry in the Trader Support Service is a structured record with six data points: product reference, goods description, commodity code, country of origin, category and an optional supplementary unit. Four are entered by the user, one is conditional and one (category) is assigned by TSS. A computed IMMI Ready flag then shows whether the record is usable on an IMMI submission.&lt;/p&gt;

&lt;h2&gt;
  
  
  The TGP as a Data Model
&lt;/h2&gt;

&lt;p&gt;Think of the Trader Goods Profile as a table scoped to an EORI. Each row is one product. The profile is created automatically once a business holds UKIMS authorisation and a Customs Declaration Service subscription, so the container exists before you add any rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Field Rules and Validation
&lt;/h2&gt;

&lt;p&gt;Each field has its own rule, and getting these right at entry time avoids rework later. You manage all of them through the &lt;a href="https://www.icustoms.ai/blogs/tss-trader-goods-profile/" rel="noopener noreferrer"&gt;TGP entries in the TSS portal&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product Reference&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Must be unique. Duplicates are not permitted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Goods Description&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Clear and specific. Generic terms slow HMRC review.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commodity Code&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;6, 8 or 10 digits, validated against the Northern Ireland Online Tariff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country of Origin&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Where the goods were produced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplementary Unit&lt;/td&gt;
&lt;td&gt;User, conditional&lt;/td&gt;
&lt;td&gt;Added only where the goods require one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Category&lt;/td&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;Standard, Category 1 or Category 2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  System-Derived Values
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Category
&lt;/h3&gt;

&lt;p&gt;On save, TSS assigns the category from the commodity code and origin. Category exemptions can move goods to a lower-risk category, so the default is worth reviewing.&lt;/p&gt;

&lt;h3&gt;
  
  
  IMMI Ready
&lt;/h3&gt;

&lt;p&gt;A boolean (true or false). It reports data quality only. It does not evaluate whether a movement is eligible for IMMI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Record Lifecycle
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create:&lt;/strong&gt; select Create New TGP Entry on the Management page, complete the fields and save.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read:&lt;/strong&gt; find entries with keyword search or column sorting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update:&lt;/strong&gt; edit the fields, click Categorise to re-run categorisation, then save.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete:&lt;/strong&gt; select Delete and confirm. The record is removed from HMRC's Trader Goods Profile and TSS screens.
Write access to all four operations depends on portal permissions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want to see TGP data kept accurate and IMMI ready at scale? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt; of iCustoms.&lt;/p&gt;

</description>
      <category>tss</category>
      <category>ai</category>
      <category>dataquality</category>
      <category>customs</category>
    </item>
    <item>
      <title>EIDR Data Flow Explained for Developers and Ops Teams</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Thu, 01 Oct 2026 08:29:52 +0000</pubDate>
      <link>https://dev.to/icustoms12/eidr-data-flow-explained-for-developers-and-ops-teams-2c4b</link>
      <guid>https://dev.to/icustoms12/eidr-data-flow-explained-for-developers-and-ops-teams-2c4b</guid>
      <description>&lt;p&gt;The EIDR data flow starts with a record in your own commercial books and ends with a supplementary declaration that closes. EIDR, Entry in Declarant's Records, replaces the upfront submission to customs for standard, non-controlled goods. If you build or maintain customs tooling, this is the sequence of identifiers and data your systems need to handle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flow at a glance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Movement happens
  -&amp;gt; Record in own books (EIDR created, via TSS or your own tooling)
  -&amp;gt; LRN + MRN + procedure code passed to transporter
  -&amp;gt; Goods movement reference created on GVMS
  -&amp;gt; Goods arrive in Northern Ireland
  -&amp;gt; Draft supplementary declaration appears in your account
  -&amp;gt; Complete and submit by the 10th calendar day of the next month
  -&amp;gt; Declaration closes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Identifiers to carry through
&lt;/h2&gt;

&lt;p&gt;The Local Reference Number (LRN) is generated when the EIDR form is saved. If you created the EIDR yourself, hand that LRN to the haulier or intermediary handling the entry summary declaration. The Movement Reference Number (MRN) and the procedure code go to the transporter too. For a deeper walkthrough, see the &lt;a href="https://www.icustoms.ai/blogs/tss-eidr-entry-in-declarants-records/" rel="noopener noreferrer"&gt;TSS EIDR explained&lt;/a&gt; guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data for the supplementary declaration
&lt;/h2&gt;

&lt;p&gt;The supplementary declaration needs parties, goods and transport information. These come from commercial invoices, packing lists and transport documents. TSS pre-fills some fields from your EIDR, so store the original EIDR data in a form you can compare against.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat the LRN, MRN and procedure code as required fields on any hand-off to a transporter.&lt;/li&gt;
&lt;li&gt;Model the supplementary declaration as a dated obligation tied to the movement.&lt;/li&gt;
&lt;li&gt;Keep the trader as the accountable party in your data model, even when TSS submits.
Want to see how iCustoms connects these steps? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>customs</category>
      <category>dataflow</category>
      <category>logistics</category>
    </item>
    <item>
      <title>Trader Goods Profile Fields Explained for UKIMS Users</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Wed, 30 Sep 2026 08:03:00 +0000</pubDate>
      <link>https://dev.to/icustoms12/trader-goods-profile-fields-explained-for-ukims-users-7c3</link>
      <guid>https://dev.to/icustoms12/trader-goods-profile-fields-explained-for-ukims-users-7c3</guid>
      <description>&lt;p&gt;A Trader Goods Profile is created automatically when a business registers for UKIMS. Each record holds five fields: goods description, commodity code, product reference, country of origin and category. When you complete an IMMI, you can select a profile entry instead of retyping the commodity data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a profile record holds
&lt;/h2&gt;

&lt;p&gt;Think of each entry as one row of product master data. This sketch shows the shape of a record. It is illustrative, not an official schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"goods_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;text&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"commodity_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;code&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_reference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your own reference&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"country_of_origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;country&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;Standard | Category 1 | Category 2&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What populates and what you type
&lt;/h2&gt;

&lt;p&gt;When you select a profile entry in an IMMI, the commodity code, origin and description populate automatically. You enter the product reference or a simple description by hand, plus the usual commercial detail: quantity, weight and value. For a business that moves the same range of products repeatedly, this is the biggest reduction in manual entry that IMMI offers. The wider context sits in this &lt;a href="https://www.icustoms.ai/blogs/ukims-tss-customs-declarations/" rel="noopener noreferrer"&gt;UKIMS and TSS customs declarations&lt;/a&gt; guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping the profile useful
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep one entry for each product you regularly move.&lt;/li&gt;
&lt;li&gt;Check the category field carefully. Category 1 goods are always excluded from the UKIMS routes.&lt;/li&gt;
&lt;li&gt;Review commodity code and origin before you rely on them, because they populate straight into the declaration.
### Is a Trader Goods Profile created automatically?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes. It is created when a business registers for UKIMS, so you do not build it from scratch.&lt;/p&gt;

&lt;p&gt;Want a single place for UKIMS numbers, profiles and eligibility checks? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tradergoodsprofile</category>
      <category>ukims</category>
      <category>fields</category>
      <category>logistics</category>
    </item>
    <item>
      <title>IMMI Submission Workflow in TSS: Six Steps Before the Move</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Tue, 29 Sep 2026 07:17:10 +0000</pubDate>
      <link>https://dev.to/icustoms12/immi-submission-workflow-in-tss-six-steps-before-the-move-3g1</link>
      <guid>https://dev.to/icustoms12/immi-submission-workflow-in-tss-six-steps-before-the-move-3g1</guid>
      <description>&lt;p&gt;The IMMI submission workflow has six steps: confirm eligibility, create the movement, add the consignment, complete the goods record, attach documents and submit. When it finishes, TSS issues two reference numbers and the status changes to Authorised for Movement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Submitting before the movement is the more typical route. It also produces the reference numbers the haulier needs. Vehicle and trailer details can be updated up to four hours before arrival, but goods data should be right earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six steps
&lt;/h2&gt;

&lt;p&gt;For a detailed walkthrough, see iCustoms' guide to &lt;a href="https://www.icustoms.ai/blogs/tss-and-immi-what-is-internal-market-movement-information/" rel="noopener noreferrer"&gt;step-by-step IMMI submission through TSS&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm eligibility.&lt;/strong&gt; Goods are not at risk, in free circulation, the right category, with UKIMS authorisation on the correct side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create the movement.&lt;/strong&gt; Enter transport details and an arrival date within 14 days. Later dates save as a draft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add the consignment.&lt;/strong&gt; Validate the importer's EORI number against the UKIMS authorisation in use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete the goods record.&lt;/strong&gt; Select a Trader Goods Profile entry or enter data by hand, then confirm the procedure and additional procedure code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attach documents.&lt;/strong&gt; Include the document code that confirms not-at-risk status.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Submit.&lt;/strong&gt; Status moves to Authorised for Movement.
## State changes to watch&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Draft&lt;/td&gt;
&lt;td&gt;Arrival date is more than 14 days away&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authorised for Movement&lt;/td&gt;
&lt;td&gt;Submitted; TSS has issued both reference numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  After submission
&lt;/h2&gt;

&lt;p&gt;TSS issues the Entry Summary Declaration and IMMI Movement Reference Numbers. Roll-on roll-off hauliers use both to build the Goods Movement Reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the order matters
&lt;/h2&gt;

&lt;p&gt;Eligibility comes first because a failed condition changes the route. If any condition fails, the movement falls back to the TSS Simplified Procedure or a full frontier declaration. For roll-on roll-off movements, the haulier then needs both reference numbers to build the Goods Movement Reference before the vehicle can board.&lt;/p&gt;

&lt;p&gt;Want to walk through this workflow with a specialist? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Watch a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>immi</category>
      <category>tss</category>
      <category>workflow</category>
      <category>logistics</category>
    </item>
    <item>
      <title>The NCTS Declaration-to-Discharge Workflow</title>
      <dc:creator>iCustoms</dc:creator>
      <pubDate>Mon, 28 Sep 2026 07:58:08 +0000</pubDate>
      <link>https://dev.to/icustoms12/the-ncts-declaration-to-discharge-workflow-5e88</link>
      <guid>https://dev.to/icustoms12/the-ncts-declaration-to-discharge-workflow-5e88</guid>
      <description>&lt;p&gt;A transit movement passes through a clear sequence of states, and each one is tied to a reference number or message. Understanding the order makes it obvious why the LRN and MRN cannot be swapped.&lt;/p&gt;

&lt;h2&gt;
  
  
  The state sequence
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Draft declaration created and tagged with an LRN.&lt;/li&gt;
&lt;li&gt;GRN and access code validated against the principal's details.&lt;/li&gt;
&lt;li&gt;Declaration accepted, MRN issued, guarantee reduced.&lt;/li&gt;
&lt;li&gt;Movement travels through offices of transit under the MRN.&lt;/li&gt;
&lt;li&gt;Office of destination confirms arrival and match.&lt;/li&gt;
&lt;li&gt;IE045 discharge message sent, guarantee restored.
## Where it can stall&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the GRN or access code is wrong, the declaration is rejected before the MRN is issued. If no IE045 arrives within 60 days, the movement enters an enquiry procedure that ends with a discharge letter.&lt;/p&gt;

&lt;p&gt;This walk through the &lt;a href="https://www.icustoms.ai/blogs/ncts-lrn-mrn-explained/" rel="noopener noreferrer"&gt;NCTS declaration to discharge workflow&lt;/a&gt; covers each handoff in order.&lt;/p&gt;

&lt;h2&gt;
  
  
  The guarantee state
&lt;/h2&gt;

&lt;p&gt;The guarantee tracks the movement: reduced at MRN issue, restored at discharge. Treating discharge as a state to confirm, not assume, keeps the balance accurate.&lt;/p&gt;

&lt;p&gt;Ready to see the workflow in one view? &lt;a href="https://www.icustoms.ai/book-a-demo/" rel="noopener noreferrer"&gt;Book a demo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>workflow</category>
      <category>logistics</category>
      <category>ncts</category>
      <category>customs</category>
    </item>
  </channel>
</rss>
