API surface. Facilities, routes, stops, legs and route runs are managed over GraphQL Interface (operations consoles and driver apps). Integrators use REST for POST /v1/journeys/plan and GET /v1/shipments/{id}/journey.
A carrier moves parcels between hubs on scheduled line-haul. A 3PL strings its own trucks together with subcontracted carrier legs. A fleet runs delivery routes through dozens of addresses a day. These are the same structure at different scales: ordered stops, joined by legs, run on a schedule. This chapter models all three with one set of objects. Plans and executions are separate so that the timetable is edited in one place, and what actually happened is recorded in another. The same split appears elsewhere in the spec: pickup schedules and pickups, rate sheets and rates. The diagram below shows how the plan objects (left) relate to the execution objects (right).

1. Facility

  • type is hub, sort_center, depot, gateway, warehouse, fulfillment_center, cross_dock, airport, seaport, rail_terminal, access_point, customs_bonded, or partner.
  • operating_hours is a Recurrence (chapter 01 §13). Here, times holds HH:MM-HH:MM ranges.
  • capabilities is sort, customs_clearance, export_screening, dangerous_goods, cold_chain, returns_processing, pickup_point.
  • functions declares what the facility is for, with a spec per function. A facility may have several functions: a sort hub with a small returns area, or a fulfillment center that also cross-docks.
facilities (GraphQL Interface query) finds candidate facilities. Fulfillment allocation (chapter 29 §4) and journey planning (§4) use functions to decide where goods can be stored, sorted or handed over.
  • GraphQL: facilities, facility, createFacility, updateFacility, deleteFacility. Delete is refused while a route references the facility.

2. Route

The route above, drawn as a network: facilities are stops, and each edge is a leg with its mode and operator.

Legs are derived, then edited

There is exactly one leg between each pair of consecutive stops. When stops are added, removed or reordered, the implementer recomputes the leg list. A leg whose from_stop → to_stop pair survives the change keeps its ID and attributes. New pairs get a new leg with defaults (mode: road, operator: self). Clients edit leg attributes, and never create or delete legs directly. This example inserts a new stop stp_4 between stp_2 and stp_3. The stp_1 to stp_2 pair survives, so leg_a keeps its ID and attributes. The stp_2 to stp_3 pair no longer exists, so leg_b is gone, and the two new pairs get new legs with defaults.

Endpoints

Changes to an active route apply to runs generated after the change. Existing future runs are regenerated only with updateRoute (GraphQL Interface mutation) and apply_to_existing_runs: true. Runs already in progress are never modified.

3. Route run

  • status is planned, dispatched, in_progress, completed, or cancelled.
  • stops[].status is pending, arrived, departed, completed, skipped, or failed (with a reason taken from the tracking status_detail vocabulary).
  • legs[].status is pending, in_transit, arrived, or cancelled.
  • route is null for ad-hoc runs, which are created directly with their own stops (typical in fleet mode).
The run lifecycle, with the endpoint that causes each transition (see Endpoints below):

Endpoints

Run actions write tracking. Every stop and leg action appends canonical tracking_events to the affected shipments’ trackers (chapter 07), with source: "implementer" and carrier_metadata: { run, stop, leg }. For example, arrive at an import facility produces in_transit / arrived_at_destination_country, complete with delivered produces delivered, and fail with recipient_unavailable produces exception / recipient_unavailable. Carrier, 3PL and fleet implementers therefore get tracking from operations without a separate integration, and clients see the same tracker API as in Universal mode. This sequence shows a driver completing or failing a last-mile stop, and the tracking events and webhooks that follow.

4. Journey

A journey is a shipment’s path through the network. It is planned at rating or purchase time and updated as runs execute.
  • segments[].type is first_mile (collection to the first network facility), middle_mile (facility to facility: line-haul road, air, ocean or rail, including customs gateways), or last_mile (final facility to the consignee, or to an access point). A single carrier that covers origin to destination end to end produces one end_to_end segment. linehaul routes (§2) serve middle_mile segments.
  • status is planned, on_track, at_risk (a predicted miss of a downstream cutoff), delayed, rerouted, or completed.
  • Subcontracted segments (the 3PL case) create a child shipment through the connections module. Its tracker events are merged into the parent shipment’s tracker, with source: "carrier_poll" or "carrier_push".
This sequence follows the example journey above: three segments on the implementer’s own runs, then a last-mile segment subcontracted to a carrier.
  • In Carrier and 3PL modes, rate.delivery comes from the planned journey’s planned_delivery, and shipment.tracking.journey is set at purchase.
  • Rerouting: replanShipmentJourney (GraphQL Interface mutation) ({ reason, avoid: { facilities, runs } }) produces a new plan, and journey.rerouted fires.

5. Events

facility.created, facility.updated, route.created, route.updated, route.activated, route.deactivated, route_run.created, route_run.dispatched, route_run.started, route_run.stop_arrived, route_run.stop_completed, route_run.stop_failed, route_run.completed, route_run.cancelled, route_run.delayed, journey.planned, journey.at_risk, journey.delayed, journey.rerouted, journey.completed.