Authentication, rate limits and errors
Base URL
All paths below start with /api/v1/partners.
Company login
Log in with your company API user. This is the existing login endpoint.
- The token is in
access_tokenat the top level of the response, not insidedata. - A token lasts 90 minutes.
- While your token is still valid, logging in again returns the same token with
error_msgset toYour Previous Token Already Exist. Within 90 minutes only one token is allowed. The status is 200. This is not an error. - Keep the token and reuse it. Log in again when a call returns 401
Your token expired.
Transporter login
Transporters log in with the email or username and password they use on the Mile web app. Owners and team members can both log in.
- The token is in
data.access_token. It lasts 90 minutes and cannot be refreshed. Log in again when it expires. - Each login returns a new token. Earlier tokens keep working until they expire.
- Changing the password ends every token for that login.
- A team member (
is_owner: false) acts for the whole transporter: same offers, trips and drivers.
Send the token
Send the token in the Authorization header:
You can also send it as an access_token query parameter, or as an access_token field in a JSON body. The examples in these docs use $MILE_TOKEN for the company token and $TRANSPORTER_TOKEN for the transporter token.
The company token works only on company endpoints. The transporter token works only on /api/v1/partners/transporters/.... The wrong token returns 401 invalid access.
Rate limits
Mile sets a limit of requests per minute for your company. Each login has its own counter. The minute starts with your first request and resets 60 seconds later.
FTL trip and transporter endpoints return these headers once the token is accepted:
When you go over the limit you get 429 with a Retry-After header in seconds. Wait that long, then retry.
Response envelope
Every response has the same four fields. The HTTP status code and status are always equal.
Status codes
Validation errors (412)
Mile checks the whole request and returns every problem at once in msgs. Each item says where the problem is, for example stops[1].shipment: containers[0].weight is required (0 or more). Fix them all before you retry.
Unknown fields are rejected, and the message lists the valid ones. Field names are snake_case.
Conflicts (409)
A 409 means the request is valid but cannot be done in the trip’s current state. Validation runs first, so you only see a 409 once the request passes validation. Common conflicts:
- An FTL is already on another trip.
- An FTL with the same
shipment_no,bl_noand container already exists. The message gives itsshipment_id. - The trip is outsourced, so you cannot add stops or assign your driver.
- The trip has started.
- The driver is busy on another trip at the same time.
- The stop has started, or it is the last stop on the trip.
- No offer in the request could be accepted or rejected.
The business rules explain each one.
Warnings
Requests that change a trip return data.warnings. A warning means the change was saved but a follow-up step failed, for example ETAs could not be calculated: .... Optimize the trip in the Mile web app to retry.
Formats
- Request dates:
Y-m-d, for example2026-11-03. - Request times:
H:iin 24-hour time, for example09:00. - Response date-times:
Y-m-d H:i:sin your company’s time zone, with no offset. - Coordinates can come back as numbers or numeric strings. Accept both.
order_idcan be larger than a 32-bit integer. Store ids as 64-bit integers.

