API surface. The fleet module is a GraphQL Interface back-office surface. Telematics and driver devices report positions through REST POST /v1/device_events (chapter 22).
Fleet mode adds the operational layer for organizations that run their own vehicles. It reuses route and route_run (chapter 16) for the work, tracker (chapter 07) for customer-visible progress, and zone (chapter 14) for service areas. It adds only what is specific to running a fleet.
The diagram below shows where fleet data comes from and where it goes. Dispatchers plan and dispatch runs, drivers and telematics report progress, and recipients and webhook endpoints see the result through trackers.
1. Vehicle
typeiscar,van,truck,trailer,bike,cargo_bike,scooter,walker,drone,aircraft,vessel, orrail_car.statusisactive,maintenance, orretired.classholds type-specific attributes (§1.1). The rest of the object is the same for every type, so an airline, a drone operator and a van fleet share dispatch, runs, positions and tracking.featuresisrefrigerated,liftgate,dangerous_goods_lq,dangerous_goods_full,electric,secure,oversize.- GraphQL:
vehicles,vehicle,createVehicle,updateVehicle,deleteVehicle,vehiclePosition.
1.1 Vehicle classes
Airlines are carriers like any other. An airline implementer, or an airline member of a network (chapter 21), publishes air services in its catalog, models flights as
routes with mode: "air" legs whose recurrence is the timetable, and runs each departure as a route_run with its aircraft as the vehicle. Flight specifics go on the leg: legs[].air = { flight_number, awb_prefix, uld_assignments: [{ uld_id, uld_type, position, handling_units: ["hu_..."] }] }.
Drone runs are ordinary last_mile route runs. Their dispatch checks add the drone’s payload, range and operating_area (409 qualification_missing with param naming the failed constraint). Positions arrive from the drone’s autopilot as a device (chapter 22).
2. Driver
shiftsis aRecurrence(chapter 01 §13).- Qualifications constrain dispatch. A run with dangerous-goods parcels can only be dispatched to a driver holding a valid
adrqualification and a vehicle with a matching feature. OtherwisedispatchRouteRun(GraphQL Interface mutation) returns409 qualification_missing.
- The spec never stores driver credentials.
app_userlinks to the implementer’s own identity system. - GraphQL:
drivers,driver,createDriver,updateDriver,deleteDriver.
3. Optimization (planning runs)
objectiveisminimize_duration,minimize_distance,minimize_vehicles, orbalance_load.statusispending,completed, orfailed. Large jobs are asynchronous and emitoptimization.completed.- With
commit: true, or later withcommitOptimization(GraphQL Interface mutation), the implementer createsroute_runs (ad-hoc,route: null) fromproposed_runs, and fillsruns[]with their IDs. - Re-optimizing an in-progress run, for example after a vehicle breakdown:
optimizeRouteRun(GraphQL Interface mutation) with{ "lock_completed_stops": true }.
4. Positions and ETAs
- It accepts batches of up to 500 points.
sourceisdriver_app,telematics, ormanual. Telematics providers can push instead throughPOST /v1/inbound/{connection_id}with a telematics connection (chapter 08 §6). - Positions update
route_run.stops[].eta, and from that theestimated_delivery.windowon each affected shipment’s tracker. When a stop’s ETA moves by more than the implementer’s threshold (default 15 minutes),route_run.eta_updatedandtracker.updatedfire. - Privacy. Positions are retained for at most 30 days unless the implementer publishes a longer period. Recipient-facing tracking (
tracker.public_url) MAY show the vehicle’s position only while the recipient’s stop is next or one stop away, and MUST NOT expose the driver’s full route.
5. Proof of delivery and exceptions
Stop completion carries proof using the existingProofOfDelivery shape (chapter 07 §8): signed_by, signature_file, photo_files, location. Failed stops use the tracking status_detail reasons (recipient_unavailable, access_restricted, refused, address_issue…). The driver app needs no vocabulary beyond what tracking already defines.
6. Service areas and pricing
- Service areas are
zoneobjects with purposeservice_area. Rating rejects addresses outside every active service area withaddress_unserviceable. - Fleet pricing uses rate sheets (chapter 15), typically with distance or zone bands. A
per_unitband may useper: { value: 1, unit: "km" }, priced on the planned route distance from the depot to the stop. This requires capabilitypricing.distance.
7. Events
vehicle.created, vehicle.updated, driver.created, driver.updated, optimization.completed, optimization.failed, route_run.eta_updated, route_run.position_stale (no position received for 10 minutes while the run is in progress).