Email API

Shipping and Delivery Notification Emails from Your App via API

Send shipping and delivery notification emails from your own code: which events deserve an email, tracking links, timing, and a working send API request.

Between "order confirmed" and "delivered" there are up to a dozen carrier events, and emailing every one of them trains customers to ignore you. This guide picks the events worth an email, shows what each message needs, and gives you the API request so the whole sequence runs from your fulfilment code.

Quick answer

Send three emails at most: shipped (with tracking number and link), out for delivery (optional, only if your carrier gives you the event reliably), and delivered (with what to do if the parcel is missing). Fire each one from the carrier webhook or your fulfilment system, deduplicate on the event, and send from a shipping@ or orders@ address on your own domain.

Which events get an email

  • Label created: no email. The parcel has not moved and "shipped" would be a lie that generates "where is it?" tickets.
  • Carrier picked up / in transit: yes, this is the shipped email. Include the tracking number as text, a tracking link, carrier name, and the estimated delivery date.
  • Hub scans: no email. Nobody needs to know it reached a sorting centre.
  • Out for delivery: optional, useful for items that need a signature or for perishables.
  • Delivered: yes. Include where it was left if the carrier reports it, and a clear line about what to do if it is not there.
  • Exception (address problem, failed attempt, returned to sender): yes, immediately, with the action the customer must take.

The shipped email

Subject: "Your order #10482 has shipped". Lead with the estimated delivery date, then the tracking number in plain text (people paste it into the carrier app), then the link. List the items in this shipment, because split shipments are common and "your order shipped" when only one of three items shipped is a complaint waiting to happen. Repeat the shipping address so a wrong address is caught while the carrier can still redirect it.

curl -X POST https://api.oqumail.com/api/v1/emails \
  -H "Authorization: Bearer $OQUMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"shipping@yourdomain.com","to":"customer@example.com","subject":"Your order #10482 has shipped","html":"<p>Estimated delivery: Thu 24 Jul.</p><p>Tracking number: <strong>1Z999AA10123456784</strong><br><a href=\"https://www.ups.com/track?tracknum=1Z999AA10123456784\">Track this parcel</a></p><p>In this shipment: 1 x Trail Jacket (M), 2 x Wool Socks</p>","text":"Estimated delivery: Thu 24 Jul. Tracking number 1Z999AA10123456784: https://www.ups.com/track?tracknum=1Z999AA10123456784"}'

Wiring it to your fulfilment flow

  1. Store shipments as their own table with carrier, tracking_number, status, and a JSON list of the events you have already emailed.
  2. Subscribe to carrier webhooks (UPS, FedEx, DHL, Royal Mail and most aggregators like EasyPost or Shippo offer them) or poll tracking every few hours if you must.
  3. Map carrier status codes to your three or four events. Carriers use different vocabularies; normalise once.
  4. Before sending, check the event is not already in the emailed list. Carrier webhooks repeat.
  5. Enqueue the send with the OquMail API request, then record the event and the returned message id.
  6. For delivered, wait 30 to 60 minutes before sending. Carriers sometimes mark delivered a few minutes early, and a customer at the door with no parcel is a bad moment for that email.

Timing and quiet hours

Shipping emails are informational, so send them when the event happens, but hold "delivered" notifications between 22:00 and 07:00 in the customer's local time and release them in the morning. Nobody needs a 3 a.m. notification about a parcel in their porch. Derive the time zone from the shipping address country and postcode rather than from the browser at checkout, which may be a VPN.

Deliverability notes

Tracking links to carrier domains are fine; the spam filters see them on every legitimate shop. What hurts is a from address on a domain with no DKIM, or a from domain that differs from the storefront. Send from your shop's own domain with SPF, DKIM and DMARC set up (OquMail guides those records with live verification when you add the domain) and check the per-message delivery log if a customer says the shipped email never arrived. The log shows the receiving server's SMTP response, which usually settles it in ten seconds.

Mistakes to avoid

  • Emailing on label creation and then having the parcel sit for two days.
  • Tracking numbers only as links. Include the number as text.
  • One "your order shipped" for split shipments without saying which items.
  • No exception emails. A failed delivery attempt with no email means a returned parcel.
  • Product recommendations in shipping emails. Keep them transactional.

Common questions

Should I email or SMS for out-for-delivery?

SMS is more useful for same-day events because it is read within minutes. If you only have email, send it anyway; the open rate on shipping emails is high.

What about local pickup orders?

Replace the shipped email with "ready for pickup" including the address, opening hours, what ID to bring, and how long the order is held. Send a reminder after 3 days if it is uncollected.

How do I get the estimated delivery date?

Most carrier APIs and aggregators return it with the label or first scan. If you do not have it, give a range based on the service level ("3 to 5 working days") rather than omitting it.

Free business email on your own domain

OquMail gives you up to 15 mailboxes on your domain — free — with guided SPF/DKIM/DMARC, webmail, IMAP/SMTP for any mail app, and a send API. Most teams are live in under fifteen minutes. Start at oqumail.com.

Get started free

Ready for business email on your domain?

Up to 15 free mailboxes, guided DNS, webmail, and a transactional API — start in minutes.

Create your free workspace