Each operator asset has a distance meter (the odometer) and an engine-hours meter. You will be able to record readings, confirm or correct a flagged one, replace a meter and read lifetime distance.
Every reading joins an append-only log. Pop Dispatch keeps the history and never edits a row in place. A correction is a new reading that replaces the old one.
Before you start #
- Add the asset first. See fleet-overview-and-setup.
- Know the asset's unit. Each asset has an
odometer_unit(kmormi), taken from your locale when you add it. You type odometer values in that unit, and Pop Dispatch shows them back in it. - Engine hours take up to two decimals, for example 1250.5.
- Fleet writes need the
dispatch_fleetlicense flag.
Steps #
- Add a reading with
POST /fleet/assets/:id/meters. Sendmeter(distanceorhours, defaultdistance),valueand optionallyread_atandnote. The answer holds the readingid, itsflag, itsepochandneeds_confirmation. - List readings with
GET /fleet/assets/:id/meters. Filter with?meter=distanceor?meter=hours. Each row shows the storedvalueand adisplay_valuein the asset's unit. - Read the asset with
GET /fleet/assets/:id. Itsmeterssection shows the current reading,lifetime_distance, whether each meter is stale and how many regressions wait for confirmation. - Resolve a flagged reading with
POST /fleet/meters/:id/correct:- Send a new
valueto correct it. - Send
confirm: trueto accept the reading as it stands. - Send
replacement: trueto mark that a new meter was fitted. The answer names the new reading and the one it replaced (voids_id).
- Send a new
What the flags mean #
- Lower than before (
regression): the value sits below an earlier reading in the same epoch. Pop Dispatch accepts it and asks you to confirm it, correct it or mark a meter replacement. - Unusually large jump (
suspect): the rise exceeds what a vehicle could cover in the days between readings. Pop Dispatch keeps the reading and shows the flag. The limit is 2,000 km of distance or 24 engine hours per day. - Confirmed (
confirmed): you accepted a flagged reading. - Meter replaced (
replaced): a new meter started here.
Replacing a meter #
A replacement reading starts a new epoch, which is a fresh run of the meter. Add the new meter's first value with replacement: true, or mark an existing flagged reading with the correct call. Lifetime distance then continues from the old total. It adds each rise inside one epoch and skips the step between meters, so the total only ever grows.
Readings that arrive from elsewhere #
An odometer typed in another place becomes a reading once for that source: a repair order or completed service (work_order), an inspection, a fuel fill, a trip start or end, an import, or the vehicle record. The source name sits on each row in source. A GPS trip distance is an estimate and never writes the odometer.
Technical details
- Distance is stored in meters and hours in hundredths.
valuein a reading row is the stored figure;display_valueis the distance in the asset's unit. - Readings can arrive in any order. Each one is classified against its neighbours by time.
- Stale means no reading in the last 30 days. A meter with no readings has no stale flag, and the maintenance board shows the missing meter by name.
- The asset's
odometerfield follows the newest live distance reading. - Reading
read_ataccepts a date-time. A value with no offset is read in the business time zone.
If something goes wrong #
validation_failed(422) withfields: ["value"]: send a whole number of at least zero for distance, or a number for hours.validation_failed(422) withfields: ["meter"]: usedistanceorhours.not_found(404): no such asset or reading.conflict(409): that reading was already corrected. Correct the newer one.invalid_date(422): writeread_atas a date-time such as 2026-10-28T09:30:00Z.feature_not_licensed(403) orlicence_read_only(403): see fleet-overview-and-setup.