Skip to content

Storefronts and marketplaces

Let the carrier update the order, not a person

The tracking number exists in three places — the carrier's system, a spreadsheet, and eventually the order — and someone moves it between them by hand. That copying is where "where is my parcel" tickets come from: not from late parcels, but from orders whose status stopped updating two days ago. Carrier status arrives as a lookup rather than a push, so the shape here is a poll, and the one step that matters is writing it back where the customer can see it.

Triggers
Two
Runs
Every 30 minutes
Stack
4 tools
Durable execution
Not required

The flow

The top track captures the tracking number once, at fulfilment. The bottom track asks the carrier on a timer and writes back only when the status actually moved.

Platform

An order is fulfilled

Shopify Admin API

Orchestration

Record the tracking number

n8n · Make

Data

Write the shipment row

Sheets · Airtable

Orchestration

Every 30 minutes

n8n 排程

Platform

Ask the carrier

DHL Shipment Tracking API

Orchestration

Status changed?

n8n IF

Platform

Write it back on the order

Shopify Admin API

Orchestration

Leave the row as is

Step by step

  1. 01

    An order is fulfilled

    Shopify Admin API

    A webhook fires when the shipment is created. Treat it as the moment a tracking number came into existence, not as the last word on it — the number is sometimes corrected an hour later.

  2. 02

    Record the tracking number

    n8n · Make

    Store the number with the carrier it belongs to and the order it came from. The carrier matters as much as the number: the same string means nothing without knowing whose system to ask.

  3. 03

    Write the shipment row

    Sheets · Airtable

    One row per shipment, holding the last status seen and when it was seen. That second column is what stops the flow re-notifying a customer about a status they already received.

  4. 04

    Every 30 minutes

    n8n 排程

    Poll rather than wait, because carrier status is a lookup. Pace it against your carrier's quota rather than against how fresh you would like the data to be — the quota is the real constraint, and it is smaller than most people assume.

  5. 05

    Ask the carrier

    DHL Shipment Tracking API

    Query only shipments that are still in transit. Delivered ones never change again, and a poll that keeps asking about them spends a quota you will want on the parcels that are still moving.

  6. 06

    Status changed?

    n8n IF

    Compare against the last status in the row, not against a fixed list. A carrier that reports the same scan twice must not read as movement, or the customer gets the same email twice and trusts the next one less.

  7. 07

    Write it back on the order

    Shopify Admin API

    Update the tracking information on the fulfilment, and decide deliberately whether this particular change is worth an email. Every intermediate scan is not; dispatch, out for delivery, and a failed attempt are.

What the platform will not allow

Two ceilings sit on this flow: how often a carrier will answer, and what the storefront does with the answer once you write it back.

  • fulfillmentTrackingInfoUpdate "Updates tracking information for a fulfillment, including the carrier name, tracking numbers, and tracking URLs." With notifyCustomer enabled, "customers receive shipping update emails with tracking details and receive notifications about future updates to the fulfillment" — and if the field is left unspecified, no notification is sent. Whether the customer hears about a scan is a decision the flow has to make on purpose.

    Shopify Admin GraphQL API — fulfillmentTrackingInfoUpdate
  • Supplying a supported carrier name in the company field makes Shopify generate the tracking URL for you. Single-package shipments use number and url; multi-package shipments use the numbers and urls arrays — so a split shipment is one call carrying several numbers, not several calls.

    Shopify Admin GraphQL API — fulfillmentTrackingInfoUpdate
  • The initial DHL tracking allocation is "250 calls per day, with a maximum of 1 call every 5 seconds", which the documentation itself describes as "intended for initial development and is not suitable for production use"; over the limit the API returns 429. A half-hourly poll across a few hundred open parcels exceeds that before it becomes a real workflow.

    DHL API — Shipment Tracking (Unified)
  • Carriers batch differently, and the batch size sets your poll design. FedEx documents that you should "Limit the number of tracking numbers in a single-track request to 30" — so a thousand open shipments is at least thirty-four calls per pass, per carrier.

    FedEx Developer Portal — Track API

When this is not worth building

Three cases where the upkeep costs more than the copying.

  • Your carrier already writes status back into the storefront. If the integration exists, this flow is a second writer on the same field, and the two will eventually disagree in front of a customer.

  • You ship a handful of parcels a day with one carrier. Pasting a tracking number takes seconds; a polling loop with a quota, a carrier mapping, and a notification rule does not.

  • Nobody has decided which statuses deserve a message. Without that decision the flow defaults to notifying on every scan, and customers learn to ignore your shipping emails — which costs more than never having sent them.

Related reading

Talk to us

Which of these should you actually build?

We run these flows for Hong Kong operators every week. Tell us the process that is costing you, and we will say whether automating it is worth the upkeep.

Start a conversation