· 3 min read
The 97% playbook: a message for every movement of the parcel
A small automation that followed every shipment and told the customer what was happening took our delivery rate to 97%. Here is how it worked and why.
اقرأ بالعربية
In the e-commerce business I co-ran with a family member, I handled media buying and most of the operations. Our ads worked. Our problem was what happened after the ad: parcels that left the warehouse and came back.
The fix that changed the numbers was not a new courier or a bigger discount. It was a small automation that watched every shipment and sent the customer a message each time the parcel moved. Our delivery rate reached 97%.
The idea in one sentence
Customers refuse parcels they have stopped thinking about. If every step of the journey reminds them that the parcel is real, on its way and arriving soon, the door opens.
The four messages that matter
Every courier has its own status names, but the customer only needs four moments:
- Ordered. A confirmation with their name, the items, the total and when it will ship.
- Shipped. The courier, a tracking number and an expected day.
- Out for delivery. “It arrives today. The courier will call you; please keep your phone close.”
- Delivered. A thank-you and an easy way to report a problem.
The third message matters most. Many failed deliveries are simply missed calls. A message that morning turns an unknown number into an expected one.
How the automation worked
We shipped with Egypt Post, whose tracking shows each scan of the parcel. The automation was intentionally boring:
- A scheduled job regularly collected the open shipments.
- For each one, it fetched the latest tracking events.
- It mapped the courier’s statuses to our four moments.
- If the moment had changed since the last check, it sent the matching message once and recorded that it did.
In simplified form:
type Moment = 'ordered' | 'shipped' | 'out_for_delivery' | 'delivered';
function momentOf(status: string): Moment | null {
if (/delivered/i.test(status)) return 'delivered';
if (/out for delivery|with courier/i.test(status)) return 'out_for_delivery';
if (/accepted|in transit|dispatched/i.test(status)) return 'shipped';
return null;
}
for (const s of await openShipments()) {
const next = momentOf(await latestStatus(s.trackingNumber));
if (next && next !== s.lastMoment) {
await sendMessage(s.customer, templates[next](s));
await markMoment(s.id, next);
}
}The important details were not technical. Each message was sent once, at a sensible hour, in plain Arabic, signed by the store. And every message invited a reply, so problems surfaced before the courier arrived.
What it taught me
- Silence is the enemy. The longer a customer goes without news, the easier it becomes to say no at the door.
- Specific beats polite. “Thursday” works better than “soon”.
- The morning message pays for itself. It is the cheapest way to turn a missed call into a delivery.
- Replies are a feature. Customers who answer a message tell you about wrong addresses and changed plans in time to fix them.
From one store to a platform
This is the lesson that made me build nqrah as a system rather than a store builder. Shipping integrations, order updates with every movement and settlement of the cash collected are on the platform roadmap, so every merchant gets the same playbook without writing a single cron job.
If you run a store today, you can start with a spreadsheet and four message templates. Measure your delivery rate for a month before and after. The difference is the cost of silence.



