# Trip Status Timeline APIs — developer reference

This document lists the APIs affected by the trip-status timeline changes, with URL, payload, and response examples.

Production reference remains in [API_DOCS.md](../API_DOCS.md).

---

## Summary

A new field is now returned in shipper trip APIs:

- `status_timeline`: ordered array of status records
  - `status`
  - `recorded_at`

Status records are appended when trip status changes through supported server flows.

---

## 1) Get shipper trip list

- **URL:** `GET /api/shipper/trips/`
- **Auth:** Shipper token
- **Payload:** None

### Response `200`

```json
{
  "status_code": 200,
  "message": "Trips retrieved successfully.",
  "error": null,
  "data": [
    {
      "id": 7,
      "shipment_id": 51,
      "status": "IN_TRANSIT",
      "status_timeline": [
        { "status": "ASSIGNED", "recorded_at": "2026-04-16T05:50:38.555438Z" },
        { "status": "EN_ROUTE", "recorded_at": "2026-04-16T06:10:21.114000Z" },
        { "status": "ARRIVED_PICKUP", "recorded_at": "2026-04-16T06:20:01.002000Z" },
        { "status": "LOADED", "recorded_at": "2026-04-16T06:35:17.447000Z" },
        { "status": "IN_TRANSIT", "recorded_at": "2026-04-16T07:53:07.959301Z" }
      ],
      "current_lat": "31.4531200",
      "current_lon": "74.2527900",
      "eta": null,
      "created_at": "2026-04-16T05:50:38.555438Z",
      "updated_at": "2026-04-16T07:53:07.959301Z"
    }
  ]
}
```

---

## 2) Get shipper trip detail

- **URL:** `GET /api/shipper/trips/{trip_id}/`
- **Auth:** Shipper token
- **Payload:** None

### Response `200`

```json
{
  "status_code": 200,
  "message": "Trip retrieved successfully.",
  "error": null,
  "data": {
    "id": 7,
    "shipment": { "id": 51, "status": "IN_TRANSIT" },
    "accepted_bid": { "id": 23, "amount": "4300.00", "status": "ACCEPTED" },
    "transporter": 32,
    "status": "IN_TRANSIT",
    "status_timeline": [
      { "status": "ASSIGNED", "recorded_at": "2026-04-16T05:50:38.555438Z" },
      { "status": "EN_ROUTE", "recorded_at": "2026-04-16T06:10:21.114000Z" },
      { "status": "ARRIVED_PICKUP", "recorded_at": "2026-04-16T06:20:01.002000Z" },
      { "status": "LOADED", "recorded_at": "2026-04-16T06:35:17.447000Z" },
      { "status": "IN_TRANSIT", "recorded_at": "2026-04-16T07:53:07.959301Z" }
    ],
    "current_lat": "31.4531200",
    "current_lon": "74.2527900",
    "eta": null,
    "created_at": "2026-04-16T05:50:38.555438Z",
    "updated_at": "2026-04-16T07:53:07.959301Z"
  }
}
```

---

## 3) Transporter updates trip status (writes timeline)

- **URL:** `PATCH /api/transporter/trips/{trip_id}/status/`
- **Auth:** Verified transporter token

### Payload

```json
{
  "status": "IN_TRANSIT",
  "lat": 31.45312,
  "lon": 74.25279,
  "recorded_at": "2026-04-16T07:53:00Z"
}
```

> `lat`, `lon`, `recorded_at` are optional by default (unless server GPS strict mode is enabled).

### Response `200`

```json
{
  "status_code": 200,
  "message": "Trip status updated successfully.",
  "error": null,
  "data": {
    "id": 7,
    "shipment_id": 51,
    "status": "IN_TRANSIT",
    "status_timeline": [
      { "status": "ASSIGNED", "recorded_at": "2026-04-16T05:50:38.555438Z" },
      { "status": "EN_ROUTE", "recorded_at": "2026-04-16T06:10:21.114000Z" },
      { "status": "ARRIVED_PICKUP", "recorded_at": "2026-04-16T06:20:01.002000Z" },
      { "status": "LOADED", "recorded_at": "2026-04-16T06:35:17.447000Z" },
      { "status": "IN_TRANSIT", "recorded_at": "2026-04-16T07:53:07.959301Z" }
    ],
    "current_lat": "31.4531200",
    "current_lon": "74.2527900",
    "eta": null,
    "created_at": "2026-04-16T05:50:38.555438Z",
    "updated_at": "2026-04-16T07:53:07.959301Z"
  }
}
```

---

## 4) Other server flows that also append timeline

These flows change trip status and now write a status record:

- Bid acceptance creates trip at `ASSIGNED`
  - `POST /api/shipper/bids/{bid_id}/accept/`
  - `POST /api/chats/{conversation_id}/accept-bid/`
- POD submission marks trip `DELIVERED`
  - `POST /api/transporter/trips/{trip_id}/pod/`
- Admin override updates to chosen status
  - `PATCH /api/admin/trips/{trip_id}/status-override/`

---

## Notes

- Timeline is ordered oldest → latest.
- Existing trips are backfilled with one initial record (current status at migration time).
- Duplicate consecutive status records are avoided by server helper logic.
