Automate shipping exception alerts so customers hear from you before they ask
Updated · By Ecomsellertool editorial team
To automate shipping exception alerts, collect every tracking event from Shopify or your carrier, add a scheduled check for parcels with no new scan, and run each one through a short exception table. Each row sends the customer a message before they write in, such as a delay notice with the new estimate, and sends anything that costs money, like a reship, refund or carrier claim, to a person.
- Shopify's FulfillmentEventStatus has 11 values, including DELAYED, ATTEMPTED_DELIVERY, FAILURE and READY_FOR_PICKUP, but no returned-to-sender, lost or damaged status (checked October 19, 2026).
- Shopify Flow's Fulfillment event created trigger runs on tracking updates from third-party fulfillment services; manual fulfillment events do not start it.
- Shopify's built-in shipping notifications cover shipping confirmation, shipping update, out for delivery and delivered; none covers a delay or a failed delivery.
- Flow's Scheduled time trigger can run at most once every 10 minutes and needs a Get action, such as Get order data, to bring in orders.
- Tracking services report more detail than Shopify stores: EasyPost lists statuses such as return_to_sender and failure, and details such as weather_delay, lost and damaged.
The step map: who runs each step
Trigger: A new tracking event on a fulfillment (from the 3PL's app, the carrier or a tracking service), plus a scheduled check every hour for parcels with no new scan and parcels past their estimated delivery date.
| Step | What happens | Who runs it |
|---|---|---|
| 1 | Each tracking event is saved against its order with the status, the carrier's message, the time it happened and the estimated delivery date, from Shopify's fulfillment events or the carrier's webhook. | Rule |
| 2 | A scheduled check finds the silent problems: labels with no carrier scan, parcels with no new scan for the rule's day count, and parcels still in transit after their estimate. | Rule |
| 3 | When the status is generic, such as in transit, an AI model reads the carrier's free-text message for an address problem, damage or a hold and suggests an exception row. It never messages the customer or decides a reship. | AI model |
| 4 | The exception table runs top to bottom and the first matching row wins: it tags the order, sends the customer message for that row from your template, and records the exception with its age. | Rule |
| 5 | Rows that need a decision post to one exception queue with the tracking history, the order value, the customer's earlier claims and a link to the order. | Person |
| 6 | A person decides each queued case: wait, reship, refund or store credit, ask the customer for a new address, or open a trace or claim with the carrier. | Person |
| 7 | Once the decision is recorded, the workflow sends the matching follow-up message, creates the replacement as a draft order or flags the refund for approval, and logs the carrier claim deadline for the person who files it. | Rule |
| 8 | A morning report lists open exceptions by age and carrier, parcels delivered after a delay notice, and messages that bounced. | Rule |
5 rule steps · 1 AI model step · 2 person steps. A rule follows fixed logic you approve; an AI model handles messy input and its output is checked by rules; a person makes the calls listed below.
What stays with a person
- Every reship, refund or store credit, and anything above the order value limit your team sets
- Carrier traces and damage or loss claims, which a person files with the carrier
- Parcels returned to sender: confirming the address before anything ships again
- Customers with earlier lost-parcel claims, before a second replacement goes out
- Changes to the exception table, the day counts and the message templates
Which tools can run it
- Shopify Flow with your 3PL's app: Fulfillment event created for status rows, Scheduled time with Get order data for stalled parcels
- Zapier, Make or n8n with a tracking service's webhooks, for stores that ship their own labels or use several carriers
- Custom code on your accounts, for the full table, business-day clocks per carrier, marketplace orders and claim deadlines
Systems it connects
- Shopify fulfillments and fulfillment events
- Shopify Flow
- 3PL fulfillment service app
- Carrier or tracking service API
- Email or SMS tool for customer messages
- Helpdesk
- Slack or email for the exception queue
Build size: Medium
Each rule is simple; the work is getting reliable events from every carrier, timing the no-scan checks and keeping the messages, the queue and the helpdesk in step.
A parcel stops moving on a Tuesday. Nobody notices until Friday, when the customer writes "where is my order?" in a tone that is already halfway to a chargeback. Support looks up the tracking, sees the parcel has not scanned in four days, asks operations what to do, and operations asks the carrier. Every step is reactive. This recipe turns it around: the workflow watches every shipment, spots the exception the day it happens, tells the customer first, and hands your team a short queue of decisions instead of an inbox of angry tickets. It is one page of our automation library.
Which shipping exceptions should trigger an alert, and what happens next?
Write the table before you build anything. Each row is a signal the workflow can read, what it means, what the customer hears, what your team does, and who decides. The Shopify statuses are values of Shopify's FulfillmentEventStatus enum (checked October 19, 2026); the carrier statuses are examples from EasyPost's tracker statuses (checked October 19, 2026), and your carrier or tracking service will use its own names. Every day count is illustrative: tune it per carrier and service.
| # | Signal (Shopify event status or carrier status) | What the workflow detects | Customer message | Internal action | Who decides |
|---|---|---|---|---|---|
| 1 | Shopify DELAYED, or carrier detail delayed or weather_delay | The parcel is moving but late; the new estimated delivery date is after the one you showed at checkout | "Your order is running late. The carrier's new estimate is Thursday. Here is your tracking link." | Tag the order; no other action | The rule, unless the order paid for express shipping (row 13) |
| 2 | Label purchased or printed, no carrier pickup scan after, for example, 2 business days | The label exists but the parcel never left the warehouse | None yet | Ask the 3PL or your packing team to confirm the parcel was handed over | Operations |
| 3 | In transit, then no new scan for, for example, 4 business days on domestic ground | The parcel has stalled in the network | "We noticed your parcel has not moved for a few days. We are checking with the carrier and will update you by Friday." | Open a trace with the carrier | Operations |
| 4 | Still in transit, for example, 5 business days past the carrier's estimate | The parcel is probably lost | Holding message from row 3, then the decision message | Reship, refund or wait; start the carrier claim | Support lead for the customer; operations for the claim |
| 5 | Shopify ATTEMPTED_DELIVERY | The carrier tried and could not deliver | "The carrier tried to deliver today. Here is what to do next, from your tracking page." | Watch for a second attempt; a second failed attempt moves to row 7 | The rule |
| 6 | Shopify READY_FOR_PICKUP, or carrier available_for_pickup | The parcel is waiting at a pickup point | "Your parcel is ready to collect at the location on your tracking page." A reminder after, for example, 3 days | None unless it is not collected | The rule |
| 7 | Carrier detail address_correction or delivery_exception about the address | The address is wrong or incomplete | "The carrier needs a corrected address. Reply with it, or update it on your tracking page." | Pass the corrected address to the carrier if your account allows it | Support |
| 8 | Carrier status return_to_sender, or detail refused | The parcel is on its way back to you | "Your parcel is being returned to us. Please confirm your address so we can send it again." | Hold any reship until the address is confirmed; log the parcel as an expected return | Support lead |
| 9 | Carrier detail damaged or lost | The carrier has reported the parcel damaged or lost | "Your parcel was damaged in transit. We are sorting out a replacement or refund and will confirm today." | Reship or refund; gather photos and invoice for the claim | Support lead; operations files the claim |
| 10 | Shopify FAILURE | Shopify describes it as "the fulfillment request failed" | None until a person has read it | Check with the 3PL or carrier what failed | Operations |
| 11 | Carrier status error or unknown for more than, for example, 1 day | The tracking number may be wrong or not registered | None yet | Check the tracking number on the order | Operations |
| 12 | Shopify DELIVERED after any row above | The exception resolved itself | "Good news: your parcel was delivered today." | Close the exception; keep it in the carrier report | The rule |
| 13 | Any row on an express order, an order above your limit (for example $250), or a customer with an earlier lost-parcel claim | A case where the default action is not safe | As the matching row says | Queue for a person before any reship or refund | Support lead |
Three choices make the table work. The customer hears about the problem before your team has solved it, because "we are on it" is what stops the ticket. Money never moves from a row on its own: rows 4, 8 and 9 queue a decision, and row 13 runs on top of every other row. And the silent rows, 2, 3, 4 and 11, come from a clock, not from an event, because a parcel that has stopped moving sends no event at all. The day counts and the $250 limit are examples for your brand to set, not facts and not advice for your store.
What does Shopify give you to build this?
Two pieces of data and two triggers. Every fulfillment can carry fulfillment events, each with a status, the time it happened, an estimated delivery date, the city and a free-text message (checked October 19, 2026). A 3PL app or a custom integration writes them with the fulfillmentEventCreate mutation, which needs the write_fulfillments access scope. The status enum has 11 values: label purchased, label printed, confirmed, carrier picked up, in transit, out for delivery, attempted delivery, ready for pickup, delayed, delivered and failure. There is no returned-to-sender, lost or damaged value, which is why rows 7 to 9 read the carrier.
In Shopify Flow, a free app on the Basic, Grow, Advanced and Plus plans (checked October 19, 2026), the Fulfillment event created trigger starts a workflow when a third-party fulfillment service reports a status change, such as picked up, in transit or delivered (checked October 19, 2026). Manual fulfillment events do not start it, so a store that ships its own labels needs the carrier's or a tracking service's webhooks instead. For the clock rows, the Scheduled time trigger runs at most once every 10 minutes and brings in no data by itself, so it is paired with Get order data (checked October 19, 2026). Our guide to what Shopify Flow automates covers where Flow stops in general.
Why are Shopify's built-in shipping emails not enough?
Because they cover the happy path. Shopify's customer notifications include a shipping confirmation when an order is fulfilled, a shipping update when tracking information is updated, an out-for-delivery email and a delivered email, and Shopify notes that tracking event sources, accuracy and timing vary by carrier (checked October 19, 2026). None of them is sent for a delay, a failed delivery attempt, a parcel waiting at a pickup point or a parcel going back to the sender. Those are exactly the moments a customer starts to worry.
Keep Shopify's emails for the normal journey and add your own messages for the exceptions, from the email or SMS tool you already use for order messages. Write each template once, in your brand's voice, with the tracking link, a plain statement of what happened and the date by which you will update the customer. Never promise a delivery date the carrier has not given you. A message that says "we are checking and will update you by Friday" is honest and still stops most follow-up emails.
What stays with a person, and how does the queue work?
Everything that spends money or stock. A reship sends a second unit; a refund returns revenue; a carrier claim has its own evidence and deadlines. The workflow prepares each of these with the facts attached, but a person decides and a person files the claim. That keeps one lost parcel from turning into two free products for a customer who reports every order as missing, which is why row 13 checks for earlier claims.
Put every queued case in one place, such as a Slack channel or a helpdesk view, with the reason, the tracking history, the order value and a link to the order. Set a target time per row: a damaged-parcel case can be decided the same day; a stalled parcel can wait for the carrier's trace. When a customer writes in anyway, the ticket should land next to the exception, not in a fresh queue. That is where our support-ticket triage recipe takes over: it matches the ticket to the order and drafts the reply, so the person sees both at once. Parcels that come back to you under row 8 then follow the returns recipe for receiving and restocking.
Where does a custom build earn its cost?
When your shipments come from more than one source. A brand that ships through a 3PL app gets Shopify events; a brand that also ships its own labels, sends marketplace orders from the same warehouse or uses several carriers needs each carrier's statuses mapped to one set of exception types. Business-day clocks per carrier and service, holiday calendars and claim deadlines per carrier are also hard to express in Flow conditions. A custom integration keeps the table, the clocks and the log in one place. If orders reach the 3PL through our Shopify-to-3PL recipe, the same integration already knows which fulfillment belongs to which warehouse. It can run on Ecomsellertool Growth OS beside your other order flows, and the order routing and 3PL reconciliation pages cover the neighboring gaps.
Who builds shipping exception alerts for ecommerce brands?
Ecomsellertool builds workflow automation on your own Shopify store, 3PL and carrier accounts. We have built software on Amazon's seller APIs since 2017 and shipped 50+ tools for 100+ teams. For shipping exceptions we write your exception table with you first, then connect the tracking events, the clocks, the customer messages and the queue, in Flow where it fits and in code where it does not. Send a project brief or read how our workflow automation service works.
The building blocks are work we have shipped:
- Event-driven alerts, as rule-based automation we built. For AccountDr we built push and email notifications that tell Amazon sellers about account changes, from ASIN changes and hijackers to stranded inventory and listing faults.
- Carriers in one layer. Ecom Global, a global listing and shipping platform, was built for 100M+ products, 20+ marketplaces and 13+ carriers, with carriers, warehouses and routing rules kept in one place.
Get your exception alerts built
Send us your carriers and your exception rules
Describe the workflow you want automated. We reply with a written plan: scope, timeline and a fixed price.
Frequently asked questions
How do I notify customers about delayed shipments automatically in Shopify?
Shopify's built-in emails cover shipped, tracking updated, out for delivery and delivered, but not delays. Use Shopify Flow's Fulfillment event created trigger, which runs on tracking updates from third-party fulfillment services, with a condition on the delayed status, and send your own message from an email or SMS tool. For parcels that simply stop moving, add a scheduled check that looks for no new scan after a set number of days.
What is a shipping exception?
Any parcel that is not on its way to a normal delivery: delayed, stuck with no new scan, a failed or attempted delivery, held at a pickup point, damaged, lost or sent back to the sender. Carriers name these differently, so a workflow maps each carrier's status to one of your own exception types before it decides what to tell the customer.
Can Shopify detect a package returned to sender?
Not as its own status. Shopify's fulfillment event statuses include delayed, attempted delivery, failure and ready for pickup, but no returned-to-sender value. Tracking services and carrier APIs report it, for example EasyPost's return_to_sender status, so a workflow reads it from there or from the carrier's message on the event.
Should the workflow reship or refund a lost package on its own?
No. Money and stock decisions stay with a person. The workflow can detect the likely loss, tell the customer you are on it, and put the case in a queue with the tracking history and the order value. A person then picks a reship, a refund or a wait, and files any carrier claim.
How many days without a scan means a package is stuck?
There is no fixed number. It depends on the carrier, the service level and the route, so set a day count per carrier and service and tune it with your own tracking history. A domestic ground parcel that has not moved in several business days deserves a look; an international parcel in customs may simply be slow.
Does this replace a where-is-my-order support flow?
It reduces those tickets but does not replace the flow. Customers still write in, so a support triage workflow still matches tickets to orders and drafts replies. Proactive exception alerts mean that, for the parcels that went wrong, the customer has usually heard from you before the ticket arrives.
