Business rules and FAQ
Dates and times
- An FTL’s
created_onis its pickup day andexpected_onits delivery day.expected_onmust be the same day or later. - Stop times are times only, in the web app and in the API (
pickup_at,pickup_to,deliver_from,deliver_to, asH:i). The pickup times use the pickup day and the delivery times use the delivery day. If you send a date in front of the time, it must be that same day. - Defaults: the pickup window end is the pickup start; the delivery start is the pickup time; the delivery end is the delivery start.
- Each window must end on or after it starts. The delivery must not start before the pickup.
- When you add stops through the API, the pickup window must end in the future, in your company’s time zone. An FTL created on its own is not checked against the clock.
- On a round trip, every return pickup must be on or after the latest outbound delivery start.
- Response date-times are in your company’s time zone,
Y-m-d H:i:s, with no offset.
FTLs
- Duplicates. An FTL with the same
shipment_no,bl_noand any of its container numbers already in your account returns 409 with the existingshipment_id. Reuse that id. Sending the same new FTL twice in one add-stops request returns 412. - Lookups. Names match without case, for example
maersk. A product name can be the full name or a part that matches only one product. A wrong name returns the valid values. - Unknown fields return 412 with the list of valid fields.
tracking_nois optional and must be unique. Mile generates one when you leave it out.- Return-leg FTLs. On a new FTL inside a
returnstop, port fields are ignored and the container is picked up at the customer. - Status. New FTLs are
Awaiting Approval. Assigning a driver moves them toLocal Dispatch. - No edits. The API cannot change or delete an FTL. Removing a stop keeps the FTL.
Customers and consignees
Send id to reuse a customer or consignee. Use the consigner.id or consignee.id from an FTL response, not merchant.id.
For a new party:
nameandaddressare required. A new customer (the shipper) also needsphone.- Mile locates the address with Google Maps. That sets the coordinates, locality and sub-locality. When Google finds the address, its coordinates are used, not yours.
latitudeandlongitudeare a fallback for addresses Google cannot find. They must be in range: latitude -90 to 90, longitude -180 to 180. If Google cannot find the address and you sent no coordinates, the request fails: send the full address with district and city, or add coordinates.
Phone numbers. Send the phone in the correct format for its country, with the country code. Mile matches it against existing customers in your account.
Trips and stops
- Trips are created in the Mile web app. An add-stops request has 1 to 50 stops. Each stop carries one FTL.
- An FTL can be on one trip only. It can be on both legs of the same trip, but only once per leg.
- Adding stops through the API is all or nothing.
- The API checks the whole request first and returns every problem as 412. Conflicts (409) come after validation passes.
- Optimizing starts the route at your company base. Stops are grouped by day, outbound before return, then ordered by distance. Mile optimizes when you click Optimize and save sequence in the web app, and after every change made through the API.
- A stop’s
tracking_nois its first container number. Repeats get-2,-3and so on. - Multi drop-off trips made in the Mile web app cannot be changed through the API (409).
- See when a trip can change.
Drivers
- Through the API, you assign only your own drivers, to trips you keep. A transporter’s driver returns 412. The transporter assigns its drivers to trips outsourced to it.
- A driver is busy when they are on another FTL trip that is not Completed and whose
busy_fromtobusy_tooverlaps this trip. Assigning a busy driver returns 409 with the other trip. - A trip that is not Completed still blocks its driver up to the current time, even after its planned end.
- A trip without an ETA plan clashes with every other trip of the same driver.
- The API cannot remove a driver from a trip. You can change the driver until the trip starts.
Outsourcing (web)
Trips are outsourced in the Mile web app. See outsource a trip.
- Outsourcing must be enabled for your company.
- A trip can be outsourced or offered only while it has no driver and has not started.
- While a trip is outsourced you cannot add stops or assign your driver. You can still remove stops and optimize.
- You cannot outsource a trip directly to a transporter who rejected its offer. A new send can still offer it to them.
- Taking a trip back works only until the transporter assigns a driver.
- Moving a trip to another transporter tells the previous one it is no longer theirs.
Offers
- Transporters get the offer one at a time, in the order the company listed them.
- Each transporter has the Time to accept set for the send: 5 minutes to 7 days, 2 hours by default. The offer’s
expires_atandseconds_leftshow the deadline. - When a transporter rejects, or the time runs out, the next transporter gets the offer. A later transporter is skipped if it has no free truck during the trip, or no rate for one of the trip’s zones.
- When nobody is left, the trip is Not accepted and stays with the company.
- Without acceptance required, the trip is assigned to its first transporter at once, with no offer to answer.
- A trip with a driver, a started trip, or a trip that already has a waiting offer cannot be offered.
- The company can stop a send. Waiting offers are withdrawn and the transporter is told.
- An offered transporter sees the route, times and containers, but not customer and consignee names and phones until it accepts. See what you can see.
- Accepting outsources the trip to the transporter. Its status stays
nulluntil the transporter assigns a driver.
Trip statuses
A trip can change while its status is null or 1 to 4. From 5 on, it has started. The status_id filter cannot select null trips.
Stop status 1 Scheduled means the stop has not started. Only scheduled stops can be removed.
ETA plan
Every trip has an eta plan: Mile’s estimate of the truck’s work, day by day. It is recalculated after every change and when you optimize in the web app. calculated_at says when.
How it is built
- The truck leaves your company base, timed to reach the first pickup when its window opens, but not before the shift starts.
- The shift comes from the driver’s vehicle service window, then the driver’s shift, then your company shift. Before a driver is assigned, your company shift is used.
- Each stop adds service time: the driver’s service time, or your company’s default.
- Driving and working hours are tracked. When the work runs past the end of the shift, an
Overnight stopis added and the trip continues the next day. - When the delivery day is later than the pickup day, the container goes to your warehouse nearest the pickup (
Gate In) and leaves it on the delivery day (Gate Out). The stop’sstaging_warehousenames it.
Fields
A stop’s eta in stops[] is the planned arrival at the consignee.
The plan is an estimate. A window that closes before the shift starts is always late. For example, an 08:00 to 08:30 pickup is late when the shift starts at 09:30.
FAQ
Why is my trip status null?
New trips have no status until a driver is assigned. Assigning your driver, or the transporter assigning theirs, sets status 4 Dispatch.
Why is a stop late when its time is fine?
The plan starts at your shift start. A pickup window that ends before the truck can get there is late. Check the shift times in the Mile web app, or move the window later.
How do I pick up on another day?
The day comes from the FTL created_on, and the API cannot edit FTLs. Change the date in the Mile web app.
How do I move an FTL to another trip?
Remove the stop from the first trip, then add it to the other trip with its shipment_id.
How do I take my driver off a trip?
You cannot through the API. You can only change to another driver, until the trip starts.
I created an FTL twice by mistake. What now?
The second call returns 409 with the first shipment_id, so nothing is duplicated. Use that id.
Why do I get 401 invalid access with a fresh token?
The company token works only on company endpoints, and the transporter token only on /transporters endpoints. Check you are using the right one.
What happens when an offer expires?
It moves to the next transporter on its own and leaves the expired transporter’s offers list. Accepting after expires_at fails with Time to accept has run out. The company sees the result on the Trip Offers page, and in the trip’s offer through the API.
Why are some coordinates strings?
Some come from stored text fields. Parse latitude and longitude as numbers whether they arrive as numbers or strings.
The call succeeded but has warnings. Is it saved?
Yes. A warning means a follow-up step failed, such as dispatching FTLs or calculating ETAs. Optimize the trip in the web app to retry the ETA plan.

