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

# 4. Manage stops

Trips are created in the [Mile web app](/ftl-trips/guides/build-trips). Through the API you read them, and add or remove stops until the trip starts. Every change made through the API re-orders the stops and recalculates the ETA plan, then returns the full trip with `warnings`.

## List trips

[`GET /api/v1/partners/shipment-trips`](/ftl-trips/api-reference/ftl-trips/list-ftl-trips) returns your trips, newest first, without stops.

```bash
curl -G "https://lastmile.milenow.com/index.php/api/v1/partners/shipment-trips" \
  -H "Authorization: Bearer $MILE_TOKEN" \
  --data-urlencode "created_from=2026-10-01" \
  --data-urlencode "limit=20" \
  --data-urlencode "page=1"
```

| Filter                       | Meaning                                                   |
| ---------------------------- | --------------------------------------------------------- |
| `status_id`                  | [Trip status](/ftl-trips/business-rules#trip-statuses) id |
| `driver_id`                  | Trips with this driver                                    |
| `partner_id`                 | Trips outsourced to this transporter                      |
| `created_from`, `created_to` | Day the **trip was created**, `Y-m-d`. Not the pickup day |
| `page`, `limit`              | `limit` is 1 to 50, default 20                            |

Read the next page while `data.has_more` is `true`. Other query parameters are ignored.

## Get a trip

[`GET /api/v1/partners/shipment-trips/{tripId}`](/ftl-trips/api-reference/ftl-trips/get-ftl-trip) returns the trip with its stops, FTLs and ETA plan. The fields are explained in [build trips](/ftl-trips/guides/build-trips#read-the-trip-through-the-api).

```bash
curl "https://lastmile.milenow.com/index.php/api/v1/partners/shipment-trips/412" \
  -H "Authorization: Bearer $MILE_TOKEN"
```

## Add FTLs to a trip

[`POST /api/v1/partners/shipment-trips/{tripId}/stops`](/ftl-trips/api-reference/ftl-trips/add-ftl-trip-stops) adds 1 to 50 stops to a trip you built in the web app.

| Stop field                  | Required         | Meaning                                                               |
| --------------------------- | ---------------- | --------------------------------------------------------------------- |
| `shipment_id` or `shipment` | Yes, one of them | An existing FTL, or a new [FTL object](/ftl-trips/guides/create-ftls) |
| `leg`                       | No               | `outbound` (default) or `return`                                      |
| `pickup_at`                 | Yes              | Start of the pickup window, `H:i`                                     |
| `pickup_to`                 | No               | End of the pickup window. Defaults to `pickup_at`                     |
| `deliver_from`              | No               | Start of the delivery window. Defaults to the `pickup_at` time        |
| `deliver_to`                | No               | End of the delivery window. Defaults to `deliver_from`                |

> **Note**
>
> Send **times only**. The pickup day is the FTL's `created_on` and the delivery day is its `expected_on`. The end of the pickup window must be in the future.

#### Existing FTL

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/shipment-trips/412/stops" \
  -H "Authorization: Bearer $MILE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stops": [
      { "shipment_id": 303, "pickup_at": "10:30", "pickup_to": "11:30", "deliver_from": "13:00", "deliver_to": "15:00" }
    ]
  }'
```

#### New return FTL

Take the empty container from the factory back to the depot. The FTL is created in the same request, and the trip becomes a round trip.

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/shipment-trips/412/stops" \
  -H "Authorization: Bearer $MILE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stops": [
      {
        "leg": "return",
        "pickup_at": "15:00",
        "pickup_to": "16:00",
        "deliver_from": "16:30",
        "deliver_to": "18:00",
        "shipment": {
          "shipment_no": "SHP-1002",
          "bl_no": "BL-55002",
          "created_on": "2026-11-03",
          "expected_on": "2026-11-03",
          "shipping_line": "MAERSK",
          "payment_term": "Company Credit",
          "shipping_charges": 0,
          "other_charges": 0,
          "customer": { "id": 7001021046 },
          "consignee": {
            "name": "Jeddah Port Empty Depot",
            "address": "Jeddah Islamic Port, Jeddah"
          },
          "containers": [
            {
              "category": "Containers",
              "product": "40ft Container - Empty",
              "container_no": "MSKU4821736",
              "seal_no": "SL-77121",
              "size": "40ft",
              "quantity": 1,
              "weight": 3800
            }
          ]
        }
      }
    ]
  }'
```

The customer is the factory, reused by its id, so the empty is picked up there. On a new return FTL, port fields are ignored.

The response is the full trip with `warnings`. The [trip rules](/ftl-trips/guides/build-trips#trip-rules) apply, and the leg order check includes the stops already on the trip. The request is all or nothing: if any stop fails, no stop and no FTL is added.

#### 412: pickup is in the past

`stops[0]: pickup 03-Nov-2026 08:00 is in the past (now 03-Nov-2026 09:15)`. The pickup day comes from the FTL's `created_on`. Send a later `pickup_at`, or use an FTL with a later `created_on`.

#### 412: a date in a time field

`pickup_at is on 2026-11-04 but the shipment created_on is 2026-11-03`. Send only the time, `H:i`.

#### 412: delivery before pickup

`Expected delivery (...) is before the pickup (...)`. Check the FTL's `created_on` and `expected_on`, and the stop's `deliver_from`.

#### 412: return pickup before the outbound delivery

`Return pickup (...) must be on or after the outbound delivery (...)`. Move the return `pickup_at` later.

#### 409: FTL already on a trip

`Shipment SHP-1001 is already on Shipment Trip #358. Remove it from that trip first.` [Remove the stop](#remove-a-stop) from the other trip, or use another FTL.

#### 409: the trip is outsourced or started

`This trip is outsourced to Desert Line Transport. Take it back from the partner before adding stops.` Take the trip back in the Mile web app first. A started trip cannot change.

## Remove a stop

[`POST /api/v1/partners/shipment-trips/{tripId}/stops/remove`](/ftl-trips/api-reference/ftl-trips/remove-ftl-trip-stop) removes one stop by its `order_id`.

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/shipment-trips/412/stops/remove" \
  -H "Authorization: Bearer $MILE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "order_id": 70003943808 }'
```

* The stop must not have started (stop status `1 Scheduled`).
* A trip keeps at least one stop. To drop the last one, add another stop first.
* The FTL is kept. You can put it on another trip.
* The remaining stops are renumbered.

| Error                                                     | Cause                                           |
| --------------------------------------------------------- | ----------------------------------------------- |
| 404 `order_id is not a stop on this trip`                 | Wrong `order_id`, or it belongs to another trip |
| 409 `This stop has already started and cannot be removed` | The driver has started this stop                |
| 409 `A trip needs at least one stop`                      | It is the last stop                             |

## Optimize a trip (web)

In the Mile web app, open the trip and click **Optimize and save sequence**. Mile re-orders the stops and recalculates the [ETA plan](/ftl-trips/business-rules#eta-plan). Stop times do not change.

Adding or removing a stop and assigning a driver through the API already re-optimize the trip. Optimize in the web app when a response had a `warnings` item such as `ETAs could not be calculated: ...`, or to refresh an old plan.

> **Info**
>
> Need to create trips, optimize them or assign them to transporters through the API? Contact Mile support and we will enable it for your account.

## When a trip can change

| Trip state                               | Add stops | Remove a stop | Optimize (web) | Assign your driver        |
| ---------------------------------------- | --------- | ------------- | -------------- | ------------------------- |
| New, no driver                           | Yes       | Yes           | Yes            | Yes                       |
| Your driver assigned, not started        | Yes       | Yes           | Yes            | Yes, to change the driver |
| Outsourced to a transporter, not started | No        | Yes           | Yes            | No                        |
| Started (status 5 or later)              | No        | No            | No             | No                        |

Next: [assign your driver](/ftl-trips/guides/assign-driver).