# Track deliveries

> Share a tracking page with recipients, react to status webhooks, and poll live position and ETA only where you show them.

There are three ways to follow a delivery. Most integrations combine them:

| Need | Use |
| --- | --- |
| The recipient wants to see where the courier is | Share `tracking_url`. Maxmove hosts the page. |
| Your system needs to know the status | [Webhooks](https://maxmove.com/en/developers/docs/webhooks/events). |
| Your own UI shows the courier on a map or an ETA | Poll [`GET /v1/deliveries/{deliveryId}/tracking`](https://api.maxmove.com/v1/docs#tag/deliveries/GET/v1/deliveries/{deliveryId}/tracking). |

Code examples use `BASE_URL` and `headers` from the [Quickstart](https://maxmove.com/en/developers/docs/quickstart).

## Share the tracking page

Every live delivery has a `tracking_url`, for example `https://maxmove.com/de/track/3J8kQ2pVx9`. Send it to the recipient by e-mail or SMS, or link it from your order page. It needs no login and shows the live status, the courier's position when it is available, and the ETA.

## Read the tracking snapshot

The tracking endpoint returns:

| Field | Meaning |
| --- | --- |
| `status` | Current delivery status. |
| `eta_seconds` | Expected seconds until the courier reaches the next waypoint. |
| `distance_meters` | Remaining driving distance to the next waypoint. |
| `route_polyline` | Remaining route as an encoded polyline (Google format). |
| `courier.name`, `courier.photo_url`, `courier.rating` | Courier first name, profile photo, and average rating, so the recipient knows who to expect. |
| `courier.vehicle` | `make`, `model`, `color`, `license_plate`, and `photo_url` of the vehicle. |
| `courier.location` | Latitude, longitude, and `recorded_at`. `null` until `tracking_available_at`. |
| `tracking_available_at` | When the position becomes available. Scheduled deliveries open tracking before pickup. |

## Poll only while it matters

Poll the endpoint only for deliveries a person is looking at, and only while the courier is on the way:

- Start when the status is `courier_assigned`, or at `tracking_available_at` for scheduled deliveries.
- Poll every 15 to 30 seconds. Positions don't change faster than that in a useful way.
- Stop at `delivered` or `cancelled`.
- Use the `delivery.eta_updated` webhook to refresh an ETA you show elsewhere: the event itself carries no ETA.

Each key can make 600 requests per minute in live mode. See [Rate limits](https://maxmove.com/en/developers/docs/concepts/rate-limits).

```ts Node.js
import { decode } from '@googlemaps/polyline-codec';

const ACTIVE = new Set(['courier_assigned', 'at_pickup', 'picked_up', 'in_transit', 'at_dropoff']);

async function pollTracking(deliveryId: string, onUpdate: (snapshot: unknown) => void) {
  while (true) {
    const tracking = await fetch(`${BASE_URL}/deliveries/${deliveryId}/tracking`, { headers }).then(
      (res) => res.json(),
    );
    const route = tracking.route_polyline ? decode(tracking.route_polyline) : [];
    onUpdate({ ...tracking, route });
    if (!ACTIVE.has(tracking.status) && tracking.status !== 'pending') return;
    await new Promise((resolve) => setTimeout(resolve, 20_000));
  }
}
```

```python Python
import time
import polyline  # pip install polyline

ACTIVE = {"courier_assigned", "at_pickup", "picked_up", "in_transit", "at_dropoff"}

def poll_tracking(delivery_id, on_update):
    while True:
        tracking = requests.get(f"{BASE_URL}/deliveries/{delivery_id}/tracking", headers=headers).json()
        route = polyline.decode(tracking["route_polyline"]) if tracking["route_polyline"] else []
        on_update({**tracking, "route": route})
        if tracking["status"] not in ACTIVE and tracking["status"] != "pending":
            return
        time.sleep(20)
```

> **Note:**
> Webhook payloads carry only the courier's name, because they end up in logs. Read the photo, vehicle, and position from the tracking endpoint when you need them.

## In test mode

The Robocourier moves in a straight line from pickup to dropoff and reports a position at every step, so you can test a map view without a real courier.

---

Source: https://maxmove.com/en/developers/docs/guides/tracking
