Courier Tracking Status Update

Twice a day, this automation asks every carrier we use where our undelivered orders have got to, and writes the answer onto the fulfilment record in NetSuite. It is what makes the delivery status a member of staff sees current, without anyone opening seven different carrier websites. It only ever moves a delivery forward — where the carrier cannot be read, or where somebody has already recorded something newer by hand, NetSuite is left exactly as it was.

Rules & IDs

Rule ID Rule Reading
LI-BL-FUL-018 Which deliveries we chase Business logic
LI-BL-FUL-019 Matching a delivery to its carrier Business logic
LI-BL-FUL-020 Which event counts as "now" Business logic
LI-BL-FUL-021 Turning the carrier's words into our status Business logic
LI-BL-FUL-022 Never overwrite something good with nothing Business logic
LI-BL-FUL-023 Never move a delivery backwards Business logic
LI-BL-FUL-024 What actually gets written Business logic
LI-BL-FUL-025 Finish what fits, hand the rest to the next run Business logic
LI-BL-FUL-026 Proving each carrier can still be read Business logic

Project owner
Kim Hoang Nguyen
Developers
Kim Hoang Nguyen
Claude
For department
Customer Service and Fulfilment Team
Status
draft
Documented
created 2026-08-31 · updated 2026-09-28this registry entry
Script created / updated
created 2026-08-25 · updated 2026-08-28from GitHub
Verified against production
2026-08-31d81a450 · d81a450 · d81a450 · d81a450 · d81a450 · d81a450 · d81a450 · d81a450 · d81a450
Systems touched
aws-lambdanetsuiteaws-eventbridgeaws-cloudwatch
Rules
Terms

Three readings of the same rules. Nothing is duplicated between them. Printing gives you the business reading followed by the diagrams.

What it does. Twice a day it takes every delivery that has left the warehouse but has not yet been marked delivered, asks the carrier who is carrying it where it has got to, and records the answer against the delivery in NetSuite — the stage it has reached, the carrier's own words for the latest thing that happened, the date it was delivered if it has been, how many cartons the carrier is holding, and a link to the carrier's tracking page. Seven carriers are covered. Nothing is written unless the carrier is genuinely ahead of what NetSuite already holds.

Which couriers this covers. Only these. A delivery on anything else keeps whatever status it already has, indefinitely and without any warning that it has stopped moving — so a frozen status on a courier below the line is expected, not a fault to report.

Courier Kept up to date? What to know
Hunter Express Yes
VT Freight Express Yes
Air Road Yes
Designer Transport Yes
Aramex Yes Still called Fastway by many people; both names are recognised
Australia Post Yes, ours only Deliveries booked under a supplier's own Australia Post account cannot be tracked — Australia Post only tells us about our own account. These show as no data every run
Couriers Please No — not since 25 August 2026 Couriers Please closed their tracking to us. Existing statuses are kept but will not move. Look these up on the Couriers Please website by hand until this is restored. Getting it back needs an account-manager conversation, not a fix at our end
Direct Freight No Their tracking blocks automated reading. Look up by hand
Xtreme Freight No Tracking requires a portal login
COPE No They publish no tracking at all

Why it exists. Delivery status is the single question Customer Service is asked most, and until this ran, answering it meant opening a different website for every carrier and pasting in a consignment number. That is slow at best, and at worst it is wrong: staff quote the last thing anyone happened to look up. The cost of it going wrong runs both ways. Stale statuses mean customers are told a delivery is in transit when it failed three days ago, and the failure is only found when they call again. Statuses that are confidently wrong are worse — a delivery marked delivered when it has not been closes the record, stops the chasing, and the loss surfaces weeks later as a claim the carrier will no longer accept.

Who it affects. Customer Service notices first, because they read the status to answer "where is my order". The Fulfilment Team notices next, because failed deliveries and returns are theirs to act on and they only see them here. Customers feel it indirectly, through the accuracy of what they are told. The carriers themselves are affected in one narrow way: we are reading their public tracking pages, deliberately slowly and under a contact-carrying name, so that any of them can email us before they block us.

When it runs. On a schedule, twice a day — early morning and early evening. A delivery is eligible when it appears in the saved search of undelivered fulfilments, has a consignment number on it, and was booked on a ship method one of the seven carriers is registered against. Deliveries drop out of the search once they are marked delivered, so the automation naturally stops chasing them. Nothing about this runs on demand: a delivery that moved an hour ago will not show here until the next run.

How it decides.

  • It starts from a list of undelivered deliveries and, for each one, works out which carrier to ask from the ship method the delivery was booked on. If no carrier matches the ship method, or there is no consignment number, the delivery is left alone entirely.
  • It asks that carrier about the consignment and takes the most recent thing that has already happened — scheduled future steps are ignored, and where a delivery and an earlier step share a day, the delivery wins.
  • It translates the carrier's own wording into our own twenty-stage list. Every carrier says it differently; "ATL", "POD captured" and "Authority To Leave" all mean delivered. Wording nothing recognises is left untranslated, and nothing is written.
  • Before writing, it checks it is not making things worse. If the carrier could not be read at all and NetSuite already holds a sensible status, NetSuite is kept. If somebody has recorded something by hand more recently than the carrier's latest event, NetSuite is kept — unless the carrier is reporting a delivery or a return, which is progress rather than a regression.
  • It writes only when the stage or the wording of the latest event has genuinely changed. A fresh timestamp on an unchanged event is not a change.
  • It works to a clock. Reading carriers is deliberately slow, so if it runs out of time it writes back everything it has finished and hands the remainder to the next run, rather than being cut off with nothing saved.

Outcomes. For each delivery, exactly one of:

Outcome What is written What it means
Updated Status, comment, and where they apply the delivery date, carton count and tracking link The carrier is ahead of NetSuite
No change Nothing The carrier agrees with what NetSuite already says
Kept Nothing The carrier could not be read, or NetSuite already holds something newer
No data Nothing The carrier does not recognise the consignment number
Not recognised Nothing The carrier answered, but in wording our list has no translation for
Skipped Nothing No consignment number, or a ship method no carrier is registered against
Deferred Nothing this run The run ran out of time before reaching this delivery

Which deliveries we chase LI-BL-FUL-018

# If… Then… Because
1 The delivery is in the undelivered-fulfilments saved search It is in scope for this run The search is the only definition of scope; nothing else selects deliveries
2 The delivery has no consignment number Skip it, write nothing There is nothing to ask the carrier about
3 The delivery's ship method matches no registered carrier Skip it, write nothing, and count it It is not a fault in the delivery — it means a carrier has not been set up yet, and the count is how that gets noticed
4 The delivery has since been marked delivered It has already left the search Delivered deliveries stop being chased automatically, which is also what lets a backlog drain

Matching a delivery to its carrier LI-BL-FUL-019

Seven couriers are set up — the list is above, along with the ones that are not. What follows is how a delivery is matched to one of them, which is worth understanding because the commonest way a delivery goes untracked is a ship method nobody recognised rather than a courier nobody supports.

# If… Then… Because
1 The ship method exactly matches one a carrier claims Use that carrier Exact names are unambiguous and are checked first
2 The ship method is not an exact match but mentions a carrier's name Use that carrier Ship methods are renamed constantly — new regions, new size bands, new prefixes — and a name-based fallback survives that where a fixed list does not
3 The ship method mentions no carrier we know Skip the delivery Guessing a carrier would produce a confidently wrong status, which is worse than none
4 Two carriers could both claim the ship method The one registered earlier wins The order the carriers are registered in is the tie-break; it is fixed, not alphabetical

Which event counts as "now" LI-BL-FUL-020

A carrier returns a delivery's whole history, not its current state. Choosing which line of that history is the current state is a decision in its own right.

# If… Then… Because
1 An event is dated in the future Ignore it Some carriers list a scheduled delivery run alongside what has happened; treating one as current would mark a delivery as out for delivery tomorrow
2 Several events have already happened Take the most recent This is the ordinary case
3 A delivery or a return shares its day with a later-looking ordinary step The delivery or return wins Freight does not get un-delivered. A delivery recorded with a date but no time otherwise loses to an earlier step that carried a clock time, and the delivery would sit on the wrong status permanently
4 No event carries a date we can read Take the last one the carrier listed Something is better than nothing, and the carrier lists them in order

Turning the carrier's words into our status LI-BL-FUL-021

# If… Then… Because
1 The carrier is one with a small, fixed vocabulary of its own Match its exact wording first Two carriers use words that mean something specific to them and nothing to anyone else — a run that has "started", a parcel "staged for delivery"
2 No exact match applies Try the general wording patterns, in order, and take the first that fits Most carriers describe the same handful of events in slightly different English
3 Still nothing fits, but the carrier gave an overall state Fall back to that A coarse answer beats no answer
4 Nothing fits at all Write nothing, and record that the wording was not recognised This is the signal that a carrier has introduced new wording. It is an engineering fix, not a data problem, and it must be visible as such

Never overwrite something good with nothing LI-BL-FUL-022

# If… Then… Because
1 The carrier could not be read, and NetSuite already holds a recognised status Keep what NetSuite has A carrier's website being down for ten minutes must not erase a week of known progress
2 The reason was that the carrier's page could no longer be understood Keep NetSuite's value, and raise it as a fault This is how a carrier rebuilding their website shows up. Left silent it looks identical to a delivery with nothing new to report — which is exactly how one carrier's rebuild went unnoticed for weeks
3 The reason was a network or rate-limit error Keep NetSuite's value, and note the error against the delivery Expected, self-correcting, but never silent
4 The reason was that the carrier simply had nothing to say Keep NetSuite's value The ordinary quiet case

Never move a delivery backwards LI-BL-FUL-023

# If… Then… Because
1 The last note on the delivery in NetSuite is newer than the carrier's latest event Keep what NetSuite has Somebody has been told something more recent, usually by phone. Overwriting it with older carrier data throws away better information
2 …unless the carrier is now reporting a delivery or a return we do not already hold Write it Arriving at delivered is progress, not a regression. Without this exception a delivery recorded with a date but no time reads as older than a note made that morning, and the delivery would never land no matter how many times we ran
3 The note in NetSuite carries no readable timestamp Treat the carrier as newer There is nothing to compare against, and the carrier is the better source by default

What actually gets written LI-BL-FUL-024

# If… Then… Because
1 The stage or the wording of the latest event has changed Write the stage and the comment These are the two things anyone reads
2 Only the timestamp has changed Write nothing Every run would otherwise rewrite every delivery, which buries the real changes
3 The delivery has reached delivered and the carrier's event carried a readable date Also write the delivery date It is the date claims and reporting are counted from
4 The carrier publishes a carton count above zero Also write it Not all of them do; a blank leaves whatever was there
5 Anything at all is being written Also write the link to the carrier's tracking page So the next person does not have to work out which carrier it was
6 Nothing above applies Write nothing at all A no-op write still costs an audit-trail entry on the record

Finish what fits, hand the rest to the next run LI-BL-FUL-025

# If… Then… Because
1 Time is running short Stop taking on new deliveries Reading carriers is deliberately slow, so a large day's list may not fit in one run
2 A carrier has finished its share Write that carrier's results back immediately A slower carrier still running must not cost us work already done
3 Time runs out mid-carrier Write back what that carrier finished, and record how many were not reached The unreached ones are deferred, not failed, and the distinction matters when reading a run
4 Deliveries were deferred The next run picks them up Anything written back drops out of the search, so successive runs drain the backlog instead of re-doing the same head of the list
5 One carrier fails outright The others still complete and still write back One carrier's bad day is not an outage

Proving each carrier can still be read LI-BL-FUL-026

# If… Then… Because
1 Every run finishes Re-check one long-settled delivery per carrier and confirm it still reads as expected A carrier changing their website does not raise an error — deliveries just quietly stop updating. This turns silent staleness into one line anybody can search for
2 A check disagrees with what is expected Record it as a failure against that carrier The delivery chosen can no longer change, so a disagreement always means us, never the freight
3 The run is nearly out of time Skip the checks They are the part we can most afford to lose
4 A carrier has no settled delivery recorded to check against It is not checked at all Which is itself worth knowing, and is recorded as skipped rather than passed

Field registry

Every field this automation reads or writes, by the name it carries in the system — what it means, and what changes when it changes. Field ids are in the developer reading.

Inputs — what it reads

Values the automation looks at to make its decision. Change one of these and the decision changes.

FieldWhat it meansWhat it changesStatus
needs confirmingItem Fulfillment The NetSuite record this delivery belongs to. Identifies the record every write-back targets. A row without one cannot be written back at all. needs confirming
needs confirmingItem Fulfillment The fulfilment number staff quote to each other and to customers. Used only to label the row in the run log, so one delivery can be found across runs. Nothing is decided from it. needs confirming
needs confirmingItem Fulfillment The carrier's own reference for this delivery — the number printed on the label. This is what is looked up with the carrier. A blank one drops the row from the run entirely, and a number the carrier does not recognise ends the row with nothing written. needs confirming
Ship ViaItem Fulfillment Which carrier and service the delivery was booked on. Decides which carrier is asked about the delivery. A ship method no carrier is registered against is skipped, so the delivery is never tracked until someone adds it. needs confirming
needs confirmingItem Fulfillment Where the carrier says this delivery has got to, on a fixed list of twenty stages. The field the automation exists to keep current. It is read to decide whether the carrier is actually ahead of NetSuite, and only written when it is. Customer Service reads it to answer "where is my order". needs confirming
needs confirmingItem Fulfillment The carrier's latest tracking event in words, with the time it happened. Carries the timestamp the no-regression rule compares against, so it decides whether a carrier update is allowed to land. Rewritten whenever the status or the wording of the latest event changes; a change to the timestamp alone is not enough to trigger a write. needs confirming

Outputs — what it writes

Values the automation puts back. Everything downstream of this rule reads them, so a wrong value here travels.

FieldWhat it meansWhat it changesStatus
needs confirmingItem Fulfillment Where the carrier says this delivery has got to, on a fixed list of twenty stages. The field the automation exists to keep current. It is read to decide whether the carrier is actually ahead of NetSuite, and only written when it is. Customer Service reads it to answer "where is my order". needs confirming
needs confirmingItem Fulfillment The carrier's latest tracking event in words, with the time it happened. Carries the timestamp the no-regression rule compares against, so it decides whether a carrier update is allowed to land. Rewritten whenever the status or the wording of the latest event changes; a change to the timestamp alone is not enough to trigger a write. needs confirming
needs confirmingItem Fulfillment The date the delivery actually completed. Written only when the status becomes Delivered and the carrier's delivery event carried a date the automation could read. A delivered consignment whose event time cannot be parsed reaches Delivered with this left blank. needs confirming
needs confirmingItem Fulfillment How many cartons the carrier records against this consignment. Written only where the carrier publishes an item count, and only when that count is above zero. Carriers that do not publish one leave whatever NetSuite already held. needs confirming
needs confirmingItem Fulfillment A link straight to the carrier's own tracking page for this delivery. Written on every update, so anyone looking at the fulfilment can open the carrier's page without first working out which carrier it is. needs confirming