12 minlesson

Delivery Estimation Overview

Delivery Estimation Overview

Delivery estimation is one of the most user-facing features a parcel tracking API provides. Customers check their tracking page to see when their package will arrive, and that estimate needs to be accurate, transparent, and responsive to changes. In Topic 3, we set a basic estimated delivery date during parcel registration using a simple service-type-to-days lookup. Now we will replace that logic with a dedicated DeliveryEstimationService that provides delivery time windows (earliest and latest dates) instead of a single date, distinguishes domestic from international shipments, includes a confidence level, and supports recalculation when exceptions or delays occur.

Why Estimation Is a Service Layer Concern

Delivery estimation involves complex business logic that does not belong in a controller or a repository. The calculation depends on multiple factors:

  • Service type determines the base transit time
  • Origin and destination determine whether the shipment is domestic or international
  • Current status affects how much of the transit has already elapsed
  • Exceptions and delays require recalculation

Extracting this logic into a dedicated DeliveryEstimationService keeps your controllers thin and your business rules testable in isolation. The service takes in parcel data and returns a structured result with an estimated delivery window.

Transit Time Rules

Real carriers publish transit time tables that map service levels to delivery windows. Our API uses four service types with the following base transit times for domestic shipments:

Service TypeMinimum DaysMaximum Days
Economy57
Standard35
Express12
Overnight11

These are business day counts, not calendar days. Weekends and holidays do not count toward transit time. An Express parcel shipped on Friday would have an earliest delivery of Monday, not Sunday.

International shipments add additional transit time to account for customs processing, cross-border transfers, and longer distances. Our model adds 3 to 5 days to both the minimum and maximum transit time for any shipment where the origin and destination country codes differ.

Domestic vs. International Logic

The distinction between domestic and international shipments is straightforward: compare the CountryCode of the shipper address with the CountryCode of the recipient address. If they match, the shipment is domestic. If they differ, it is international.

1Domestic: Shipper.CountryCode == Recipient.CountryCode
2International: Shipper.CountryCode != Recipient.CountryCode

This simple comparison drives a significant difference in the estimated delivery window. An Economy domestic shipment has a window of 5-7 business days, while an Economy international shipment has a window of 8-12 business days.

Time Windows Instead of Single Dates

A single estimated delivery date is misleading. Real-world delivery involves variability: weather delays, customs processing, sorting facility backups. Returning a time window with an earliest and latest date gives customers a more honest and useful answer.

The API response for a delivery estimate includes three fields:

  • EarliestDelivery: The best-case delivery date assuming no delays
  • LatestDelivery: The worst-case delivery date accounting for normal variability
  • Confidence: A qualitative indicator of how reliable the estimate is

This structured response gives frontend applications the flexibility to display the information in the most appropriate way for their users.

Confidence Levels

Confidence reflects how far along the parcel is in its journey and how likely the estimate is to be accurate. The further a parcel has progressed, the more data points you have and the narrower your uncertainty window becomes.

StatusConfidenceReasoning
LabelCreatedLowParcel has not entered the carrier network yet
PickedUpLowJust started, many unknowns remain
InTransitMediumMoving through the network, some progress confirmed
OutForDeliveryHighOn the delivery vehicle, arrival is imminent
DeliveredHighAlready delivered, estimate is actual
ExceptionLowDisruption occurred, timeline uncertain
ReturnedLowNot being delivered to recipient

Confidence is not a probability. It is a qualitative signal that helps users and frontend applications decide how much weight to give the estimate.

Recalculation After Exceptions

When an exception occurs (failed delivery attempt, weather delay, customs hold), the original estimate becomes stale. The API needs an endpoint that triggers a recalculation and updates the parcel's estimated delivery date.

Recalculation works by:

  1. Looking at the current status and the date of the most recent tracking event
  2. Applying the transit time rules from the current point forward
  3. Adding any delay penalties based on the exception type
  4. Returning the updated delivery window

For example, a Standard domestic parcel that was picked up on Monday and hits a weather delay on Wednesday would have its estimate recalculated from Wednesday with the remaining transit time plus a delay buffer.

The recalculation endpoint is a PUT operation because it modifies the parcel's estimated delivery date in the database. It returns the updated delivery window so the caller can display the new estimate immediately.

Business Day Calculation

Counting business days correctly is essential for accurate estimates. A naive approach that simply adds calendar days will overestimate delivery times for parcels shipped on Fridays or before holidays.

Business day calculation involves:

  • Skipping weekends: Saturday and Sunday do not count
  • Starting from the next business day: If a parcel is shipped on Saturday, day one is Monday
  • Handling holidays: While a full holiday calendar is complex, the basic implementation skips weekends

The calculation takes a start date and a number of business days, then iterates forward, skipping non-business days, until it has counted the required number of business days.

Example: Shipping on Friday

Consider a Standard domestic parcel shipped on a Friday. The base transit time is 3-5 business days:

1Day 1: Monday (business day 1)
2Day 2: Tuesday (business day 2)
3Day 3: Wednesday (business day 3) ← Earliest delivery
4Day 4: Thursday (business day 4)
5Day 5: Friday (business day 5) ← Latest delivery

Saturday and Sunday are skipped entirely. A naive calendar-day calculation would predict delivery on Monday (3 days) through Wednesday (5 days), but the correct business-day calculation predicts Wednesday through Friday. Getting this wrong means your API gives customers inaccurate expectations.

Real-World Considerations

Production delivery estimation systems account for factors beyond what we implement here, but it is worth understanding what a more complete system includes:

  • Holiday calendars: National and regional holidays vary by country and affect transit times. A shipment through a country during a national holiday week experiences delays that a weekend-only calculation misses.
  • Facility processing times: Packages do not teleport between cities. Each sorting facility adds processing time that varies by facility capacity and current volume.
  • Historical data: Carriers with years of shipment data can use machine learning models to predict delivery times based on actual performance for similar routes.
  • Real-time conditions: Weather events, natural disasters, and carrier capacity constraints all affect delivery timing.

Our implementation focuses on the fundamental pattern: service type lookup, domestic/international adjustment, business day calculation, and confidence assessment. This pattern is the foundation that more sophisticated systems build upon.

Endpoint Design

This topic introduces two new endpoints:

MethodRoutePurpose
GET/api/parcels/{id}/delivery-estimateReturns the delivery time window
PUT/api/parcels/{id}/delivery-estimate/recalculateRecalculates after delays

The GET endpoint is a read-only calculation that does not modify any data. The PUT endpoint updates the parcel's EstimatedDeliveryDate field and returns the new window.

Both endpoints return the same response shape: a delivery estimate with earliest date, latest date, and confidence level. This consistency makes the API predictable for consumers.

Summary

In this lesson, you learned:

  • Delivery estimation logic belongs in a dedicated service, not in controllers
  • Transit times are based on service type with adjustments for international shipments
  • Time windows (earliest and latest dates) are more useful than single date estimates
  • Confidence levels reflect how far along the parcel is in its journey
  • Recalculation is needed when exceptions or delays occur
  • Business day calculations must skip weekends to produce accurate estimates
  • Two new endpoints provide delivery estimates and trigger recalculations

Next, you will build the DeliveryEstimationService with the full calculation logic.

Delivery Estimation Overview - Anko Academy