> 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.

# 7. Transporter side

This page is for transporters: trucking companies that run trips for a Mile company. The company outsources trips to you, or offers them to you, from the Mile web app. You answer and assign your drivers through the API, with your own login and token, and only the `/api/v1/partners/transporters` endpoints.

The company can also outsource a trip to you directly, without an offer. It then appears in [your trips](#your-trips), ready for a driver, and you skip steps 2 and 3.

#### Log in

Log in with the email or username and password you use on the Mile web app. See [transporter login](/ftl-trips/authentication#transporter-login).

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/login" \
  -H "Content-Type: application/json" \
  -d '{"user": "dispatch@desertline.example", "password": "YOUR_PASSWORD"}'
```

Send `data.access_token` as `Authorization: Bearer ...` on every other call. It lasts 90 minutes.

#### Read your open offers

[`GET /api/v1/partners/transporters/offers`](/ftl-trips/api-reference/transporter-api/list-transporter-offers) lists the trips offered to you that wait for an answer, soonest to expire first.

```bash
curl "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/offers" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN"
```

```json
{
  "status": 200,
  "msg": "Offers fetched successfully",
  "msgs": [],
  "data": [
    {
      "offer_id": 42,
      "expires_at": "2026-10-28 16:45:22",
      "seconds_left": 7183,
      "trip": {
        "id": 413,
        "type": "outbound",
        "busy_from": "2026-11-03 09:30:00",
        "busy_to": "2026-11-03 13:40:00",
        "customer_details_hidden": true,
        "stops": [
          {
            "order_id": 70003943809,
            "leg": "outbound",
            "pickup": { "address": "Jiddah", "from": "2026-11-03 10:00:00", "to": "2026-11-03 11:00:00" },
            "delivery": { "address": "South Industrial Area, Jeddah", "from": "2026-11-03 12:00:00", "to": "2026-11-03 14:00:00" },
            "shipment": { "containers": [{ "container_no": "MSKU4821736", "size": "40ft", "weight": "26000" }] }
          }
        ]
      }
    }
  ]
}
```

You see the route, times and containers. Customer and consignee names and phones are hidden until you accept.

#### Accept or reject

Send the `offer_id` values, not the trip ids. You can answer several offers at once.

#### Accept

[`POST /api/v1/partners/transporters/offers/accept`](/ftl-trips/api-reference/transporter-api/accept-transporter-offers)

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/offers/accept" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "offer_ids": [42] }'
```

```json
{
  "status": 200,
  "msg": "Accepted 1 trip. Please assign a driver.",
  "msgs": [],
  "data": { "accepted_trip_ids": [413], "failed": [] }
}
```

The trip is now outsourced to you.

#### Reject

[`POST /api/v1/partners/transporters/offers/reject`](/ftl-trips/api-reference/transporter-api/reject-transporter-offers)

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/offers/reject" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "offer_ids": [43] }'
```

```json
{
  "status": 200,
  "msg": "Rejected 1 trip.",
  "msgs": [],
  "data": { "rejected_trip_ids": [414], "failed": [] }
}
```

The trip goes to the next transporter on the company's list. The company can no longer outsource that trip to you directly.

If some offers fail, the call still returns 200 and lists them in `failed`. If all of them fail, it returns 409, for example `Offer 42 (trip 413): Offer is no longer open`.

| `failed[].reason`                   | Meaning                                                      |
| ----------------------------------- | ------------------------------------------------------------ |
| `Offer not found`                   | Not an offer to you                                          |
| `Offer is no longer open`           | Already answered, withdrawn by the company, or moved on      |
| `Time to accept has run out`        | `expires_at` has passed                                      |
| `Trip was assigned to someone else` | The company gave the trip to a driver or another transporter |

#### Assign your driver

List your drivers with [`GET /api/v1/partners/transporters/drivers`](/ftl-trips/api-reference/transporter-api/list-transporter-drivers), then call [`POST /api/v1/partners/transporters/trips/{tripId}/driver`](/ftl-trips/api-reference/transporter-api/assign-transporter-trip-driver).

```bash
curl "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/drivers" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN"
```

```json
{
  "status": 200,
  "msg": "Drivers fetched successfully",
  "msgs": [],
  "data": [
    { "id": 7019258, "name": "Yusuf Ali", "phone": "+966500000000", "vehicle": { "id": 7012246, "name": "Desert Line Truck 1", "plate": "DLT 5123" } }
  ]
}
```

```bash
curl -X POST "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/trips/413/driver" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "driver_id": 7019258 }'
```

The response is the full trip with `status` `4 Dispatch`, your `driver`, and a new ETA plan. Send another `driver_id` to change the driver until the trip starts.

## Your trips

[`GET /api/v1/partners/transporters/trips`](/ftl-trips/api-reference/transporter-api/list-transporter-trips) lists trips outsourced to you and trips with an open offer to you, newest first. `offer` is set on trips you have not answered yet. It takes the same filters as the company list, except `partner_id`.

```bash
curl -G "https://lastmile.milenow.com/index.php/api/v1/partners/transporters/trips" \
  -H "Authorization: Bearer $TRANSPORTER_TOKEN" \
  --data-urlencode "page=1"
```

[`GET /api/v1/partners/transporters/trips/{tripId}`](/ftl-trips/api-reference/transporter-api/get-transporter-trip) returns one trip with stops and ETA plan. `customer_details_hidden` is `true` while the trip is only offered.

## What you can see

|                                         | Offered to you        | Outsourced to you          |
| --------------------------------------- | --------------------- | -------------------------- |
| Stops, times, addresses, coordinates    | Yes                   | Yes                        |
| Containers and FTL numbers              | Yes                   | Yes                        |
| Customer and consignee names and phones | No                    | Yes                        |
| Names in the ETA plan                   | Replaced by addresses | Yes                        |
| Assign a driver                         | No                    | Yes, until the trip starts |

## Errors

| Error                                                                     | Cause                                                       |
| ------------------------------------------------------------------------- | ----------------------------------------------------------- |
| 401 `invalid access`                                                      | Missing token, or a company token on a transporter endpoint |
| 401 `Your token expired.`                                                 | Log in again                                                |
| 403 `Your partner account is disabled`                                    | The company disabled your account                           |
| 404 `Trip not found`                                                      | The trip is not outsourced or offered to you                |
| 409 `... is busy on Shipment Trip #...`                                   | Your driver has an overlapping trip. Pick another driver    |
| 409 `This trip has already started, the driver can no longer be changed.` | Status 5 or later                                           |
| 412 `You can only assign your own drivers.`                               | The driver is not in your drivers list                      |