Service levels

Updated May 31, 20265 min read

Service levels are timing SLAs attached to every shipment: the customer promise (what you tell the shopper to expect) plus three internal milestones that underpin it. Each SLA is the output of a service-level rule matched against the shipment data at a specific lifecycle moment. Reporting compares each prediction against the actual time taken to show where SLAs are met, missed, or drifting.

The four service levels

Service levelComputed whenReference timestampStored on Shipment
Customer promiseShipment is createdOrder timepromised_delivery_date
Estimated processing timeShipment is createdOrder timeestimated_process_date
Estimated collection timeShipment is bookedBooking time (keyMilestones.booked)post_shipping_info.estimated_ship_date
Estimated delivery timeShipment moves to shippedShipping time (keyMilestones.shipped)post_shipping_info.estimated_delivery_date

Two fire at creation, one at booking, one at shipped. Each uses a different reference timestamp because each measures a different phase. Together they give a timeline of the parcel's journey against the customer promise.

What an SLA value looks like

A service-level rule's target is an EstimationSLA, which comes in two shapes:

Time-based SLA. Used for short-horizon SLAs measured in hours and minutes. The target carries duration: { hour, minute }, an optional workingSchedule (working-hours windows per weekday, supporting cross-midnight windows), and optional blackoutDates (skip entirely). The result is in the shipment's source timezone. Typical use: "Same-day delivery within Dubai", with a promise of 4 hours from order time, counting only working hours.

Day-based SLA. Used for longer SLAs measured in calendar days. The target carries duration: { day }, an optional cutoffSchedule (per-weekday cutoff time; past cutoff, the count advances to the next day), an optional etaTime (final time-of-day for the result), and blackoutDates. The result is in the destination timezone. Typical use: "Next-day delivery if ordered before 2pm, otherwise day-after".

Both shapes also accept an optional deliveryWindow that produces a from date in addition to the point estimate. Useful when the customer-facing promise is a window ("Tuesday–Wednesday") rather than a single date.

Rule sequencing and fall-through

Service-level rulesets work like shipping rulesets:

  • A ruleset is scoped per (merchant, country, entityType). Country means pickup country for forward shipments, dropoff country for reverse.
  • Rules within a ruleset have a sequence. Lower sequence means higher priority.
  • Conditions on each rule are AND-combined. They can match on pickup / dropoff geography, delivery type, order type, partner location, weight (gross or volumetric), and custom conditions.
  • The first rule whose conditions match wins. There's no eligibility filtering layer; service-level rules pick a value, they don't reason over carrier viability.

Unlike shipping rules (which select a carrier), service-level rules don't fall through on viability. The first match wins unconditionally.

When no rule matches

If no service-level rule matches the shipment, the SLA field is left null. There's no default, no error, no event. Same outcome in three other situations:

  • The tenant's subscription doesn't include service-level estimation. Every SLA computation short-circuits at the subscription check.
  • No ruleset exists for the (merchant, country, entityType) tuple (Carriyo also tries _UNSPECIFIED as a country fallback before giving up).
  • Multiple rulesets match the tuple (misconfiguration). The lookup throws, the engine catches, and the SLA stays null.

The failure mode is silent. If you expect SLAs and aren't seeing them, check (in order): the subscription, the ruleset configuration for the merchant + country, and whether the shipment data matches any rule's conditions.

Customer promise has its own precedence

For the customer promise specifically, the rule engine is the last fallback. The platform layers three sources, in priority order:

  1. Scheduled delivery date sync. If the caller (or the Dashboard) sets a scheduled-delivery date on the shipment, the customer promise mirrors that date.
  2. Caller-supplied input_promised_delivery_date. If the request body or update includes this field, it wins over the rule engine. The original is preserved in original_promised_delivery_date so subsequent recomputations don't overwrite it.
  3. Rule engine. Only if neither of the above is set does the service-level rule for PROMISED fire.

This matters for integrations that set their own promise upstream. If checkout already chose a delivery option with its own promise, the platform won't second-guess you.

Lifecycle hooks

TriggerWhat gets computedWhen
Shipment created or draft updatedestimated_process_date, promised_delivery_dateOn every draft create / patch / put / confirm
Carrier booking succeedsestimated_ship_date (collection time)When the carrier returns a booking response
Status moves to shippedestimated_delivery_dateWhen the shipped status event applies

Process- and promise-dates are recomputed on every draft edit, so editing a shipment can move the promise. Estimated ship and estimated delivery are set once, gated on field-is-null plus the relevant milestone being present, and aren't overwritten by subsequent updates. Carrier-supplied ETA is stored in a separate carrier_estimated_delivery_date field so it can co-exist with Carriyo's own computation.

Cancellation doesn't clear or recompute SLAs. A cancelled shipment keeps the SLA values that were on it at cancellation time.

Customer-facing vs internal

SLAVisible toHow
Customer promiseThe shopperTracking pages, notifications, checkout delivery-option delivery_estimation
Estimated processing timeInternal onlyDashboard, reporting
Estimated collection timeInternal onlyDashboard, reporting
Estimated delivery timeInternal onlyDashboard, reporting

The customer promise is the only SLA shoppers see. The three internal estimates exist to drive ops dashboards and SLA reporting: are warehouses processing within target, are carriers collecting on time, are deliveries hitting their projected dates. They never appear in customer-facing pages.

How it fits with other modules

  • Automation. The shared rule engine (rulesets, sequence, conditions) that powers both service-level rules and shipping rules.
  • Shipping rules. The booking-time sister rule type, picking carrier accounts rather than SLA values.
  • Delivery options. Each delivery option carries its own delivery_estimation, which the customer-promise SLA mirrors when a delivery option is chosen at checkout.
  • Post-purchase CX. Where the customer promise is shown to the shopper.