> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.chrt.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.chrt.com/_mcp/server.

# Tracking

> The tracking model on chrt — driver-based tracking on orders, standalone tracker sessions for independent devices, the milestone events emitted by each task action, how ETA is calculated, and public tracking links.

chrt tracks shipments through a mix of **driver location** (the chrt mobile
app reporting the driver's GPS), **flight data** (FlightAware feeds), and
**tracker devices** (Tive and similar hardware reporting independently of any
phone). On any active order, all three streams can flow at once. This page is
the model behind every map, timeline, and ETA badge in the product.

## The two tracking surfaces

| Surface                        | Driven by                                                               | Used for                                                                            |
| ------------------------------ | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **On-order tracking**          | The driver app + flight integrations + any tracker linked to the cargo. | Watching a chrt order in flight: map, timeline, ETA, milestones, proof of delivery. |
| **Standalone tracker session** | A registered tracker device with no order attached.                     | Monitoring a shipment chrt isn't dispatching — your own cargo, or a partner's.      |

The two surfaces share the same underlying objects but are entered from
different routes (`/orders/<order-ref>` versus `/tracking/sessions/<id>`).

## Tracker session

A **tracker session** is a window of recording for a single tracker device.
Sessions have a start time, an optional end time (or auto-termination after
three days by default), a status (active or ended), and a stream of timestamped
**data points** — latitude, longitude, battery, temperature when supported.

| Surface    | How a session is created                                                                                              |
| ---------- | --------------------------------------------------------------------------------------------------------------------- |
| Standalone | Manually from [chrt.com/tracking/devices](https://chrt.com/tracking/devices) or via the [tracker API](/trackers/api). |
| On-order   | Automatically when a tracker device is linked to cargo on the order.                                                  |

Each session can optionally be associated with one or more **flights** so chrt
can alert you if the device's location is inconsistent with the flight (for
example, the device hasn't reached the airport in time for boarding).

## Milestones

Every task on a task group emits a **milestone event** when its state changes.
The set of possible milestones depends on the task-group type:

* **Ground tasks** — `pickup`, `deliver`, `tender_to_airline`,
  `recover_from_airline`, `consolidate`, `hold`, `other`.
* **Flight tasks** (auto-completed from FlightAware) —
  `cargo_received_by_airline`, `cargo_loaded_onto_flight`, `flight_departed`,
  `flight_arrived`, `cargo_offloaded_from_flight`, `cargo_cleared_customs`,
  `cargo_ready_for_recovery`.
* **OBC tasks** — the courier-and-cargo lifecycle from
  `courier_departed_for_pickup_location` through
  `courier_arrived_at_delivery_location`.

Milestones become entries on the **order timeline** (the Details tab on the
order page) and trigger any matching email or webhook notifications. See
[Orders, task groups, segments, stops](/docs/concepts/orders) for the full
task model.

## ETA

The **ETA** for each upcoming task on an order is calculated live and shown on
the order timeline and on stop event panels. The calculation differs for
ground-only orders versus orders that include a flight.

### Ground-only orders

For each task in order, chained:

```
ETA(task[0])     = staged_at_timestamp + 2 hours          (live)
                   = now + 1 hour                          (draft preview)
ETA(task[n])     = ETA(task[n-1]) + drivingDuration + 20 min buffer
```

`drivingDuration` comes from the Mapbox Directions API; the buffer is 20
minutes between consecutive tasks. If a task group is **in progress** and a
driver location is known, the next ETA is recalculated from the driver's
current position via Mapbox routing.

### Orders with flight task groups

Flight legs override the chain at their boundary:

| Task                               | ETA                                                                                                                        |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `tender_to_airline`                | Flight departure time − 2 hours.                                                                                           |
| `recover_from_airline`             | Flight arrival time.                                                                                                       |
| Tasks after `recover_from_airline` | Previous ETA + drivingDuration + **30-minute** buffer (longer than the ground default to account for offload and customs). |

Flight departure and arrival times pull from FlightAware in this priority:

* **Departure** — `actual_out` > `estimated_out` > `scheduled_out`.
* **Arrival** — `actual_in` > `estimated_in` > `predicted_in` > `scheduled_in`.

### Time windows override ETA

Every task can have a **time window** with `left_boundary_timestamp` (earliest
acceptable) and `right_boundary_timestamp` (latest acceptable). When a time
window is set, ETA prefers `right_boundary_timestamp` (the deadline) over the
routed estimate, and uses the latest of multiple overlapping windows.

### Constants

| Constant                           | Value                                  |
| ---------------------------------- | -------------------------------------- |
| First task buffer (live)           | 2 hours after stage                    |
| First task buffer (draft preview)  | 1 hour after now                       |
| Default buffer between tasks       | 20 minutes                             |
| Post-recover buffer                | 30 minutes                             |
| Default driving duration fallback  | 30 minutes (when Mapbox routing fails) |
| Flight pre-departure tender buffer | 2 hours                                |

## Public links

A **public tracking link** is a chrt-hosted page anyone can open with just
the URL — no chrt account required. Two flavors:

| Public link kind    | URL pattern                                              | What it shows                                                                                                                                                   |
| ------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Order public page   | `https://chrt.com/orders/public/<order-ref>`             | A stripped-down view of an order: planned route, current driver position, milestone timeline. The order owner controls which segments / map layers are visible. |
| Session public page | `https://chrt.com/tracking/sessions/public/<session-id>` | The current and historical position of one tracker session, with an optional "See History" pane.                                                                |

Public links are revocable at any time. The on-order public link uses a
share dialog with per-segment toggles; the standalone-session public link is
created from the session detail page.

See [Public tracking links (shippers)](/shippers/public-tracking) and
[Share a tracking session](/trackers/sharing)
for the share flows.

## Map layers

The Map tab on an order page can show three layers simultaneously:

| Layer                    | Source                                                              |
| ------------------------ | ------------------------------------------------------------------- |
| **Task group by driver** | Driver phone location, one path per task group.                     |
| **Cargo by driver**      | Cargo position inferred from the driver carrying it.                |
| **Cargo by device**      | Independent tracker device pings, when a device is linked to cargo. |

Use the layer toggle in the top-left of the map to switch between them.

## Related guides

* [Orders, task groups, segments, stops](/docs/concepts/orders) — the task
  and milestone model.
* [Tracking shipments (shippers)](/shippers/tracking) — reading the order
  page as a shipper.
* [Public tracking links (shippers)](/shippers/public-tracking) — sharing
  on-order tracking.
* [Standalone trackers](/trackers/standalone) — creating sessions for your
  own cargo.
* [Tracker API](/trackers/api) — programmatic access to sessions and data
  points.
* [Trackers on orders](/trackers/on-orders) — attaching devices to cargo on
  a chrt order.