Carrier management operations
MVMNT API (1.1.0)
The MVMNT API enables you to automate freight brokerage workflows by integrating directly with our Transportation Management System.
Postman setup guide: API Clients.
OAuth 2.0 client credentials flow. See Authentication Guide for details.
Headers:
Content-Type: application/x-www-form-urlencodedBody Parameters:
grant_type=client_credentials
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRETcurl -X POST https://api.mvmnt.io/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"Status: 200 OK
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}Response Fields:
access_token: JWT Bearer token to use for API requeststoken_type: AlwaysBearerexpires_in: Token lifetime in seconds (3600 = 1 hour)
Mutating requests (POST, PATCH, DELETE) accept an optional Idempotency-Key header (up to 255 characters). Retrying a request with the same key and the same body returns the original result instead of repeating the operation; reusing a key with a different body fails. Keys are scoped to your organization — keys chosen by other tenants can never collide with yours. Use a stable identifier from your system (for example your own record id plus the action) rather than a random value per attempt.
Reference Data
Read-only catalogs (equipment, charge codes, special requirements) referenced by id from other resources.
Every catalog also answers on its short top-level path, so GET /v1/charge-codes and GET /v1/reference-data/charge-codes are the same endpoint. The documented /reference-data/* form is canonical — it keeps the catalogs grouped here as more are added (port codes, cities, zip codes) — and the short form is a convenience alias.
Request
Search for stops using filter criteria.
- By location:
{ "filter": { "shipperLocationId": { "equalTo": "uuid" } } } - By postal code:
{ "filter": { "postalCode": { "equalTo": "60601" } } } - Recently updated:
{ "filter": { "updatedAt": { "greaterThan": "2025-01-01T00:00:00Z" } } }
To list the stops of one shipment, read the shipment instead: its orders carry them in route order, which a filter cannot express.
- Productionhttps://api.mvmnt.io/v1/stops/filter
- Demo (non-production)https://api.demo.mvmnt.io/v1/stops/filter
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://api.mvmnt.io/v1/stops/filter \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'Content-Type: application/json' \
-d '{
"filter": {
"shipperLocationId": {
"equalTo": "550e8400-e29b-41d4-a716-446655440000"
}
}
}'{ "data": [ { … } ], "pagination": { "pageSize": 50, "hasNextPage": true, "hasPreviousPage": false, "endCursor": "eyJpZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCJ9" }, "errors": [ { … } ] }
Request
Create a stop on an order.
A stop is placed exactly one way — by location, postalCode, cityId or airportCode. Only a location carries a street address; the other three exist because freight is routinely tendered before an address is known.
- The stop is created and attached to the order
sequencedecides where it falls in the route
Stops are normally created with their shipment. Use this endpoint to add one to an order that already exists.
Whether freight is collected or delivered at this stop. PICKUP and DELIVERY are accepted as aliases and stored as PICK and DROP.
Position in the route, starting at 1. Must fall inside the existing route or immediately after it: a two-stop route accepts 1, 2 or 3. Stops already at or after the position shift up by one to make room. A position past the end is rejected rather than clamped — it would leave the skipped positions empty.
The route is every order sharing the shipment detail, not just the order named here, so a consolidated shipment counts all of its stops.
A route consolidated inside the TMS is numbered from 0 rather than 1. Its first position is therefore not addressable here — 1 is the lowest this contract accepts — and a stop sent at 1 lands immediately after it. Every other position behaves the same on both.
Set only on create: renumbering an existing route is not a patchable column, and sending sequence to PATCH /stops/{id} is rejected.
Reference to an existing location. The only placement carrying a street address. Mutually exclusive with the three below.
- Productionhttps://api.mvmnt.io/v1/stops
- Demo (non-production)https://api.demo.mvmnt.io/v1/stops
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://api.mvmnt.io/v1/stops \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'Content-Type: application/json' \
-d '{
"orderId": "550e8400-e29b-41d4-a716-446655440000",
"stop": {
"type": "DROP",
"sequence": 3,
"location": {
"id": "660e8400-e29b-41d4-a716-446655440001"
},
"requestedStartDate": "2025-01-25"
}
}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "type": "PICK", "sequence": 0, "location": { "id": "550e8400-e29b-41d4-a716-446655440000", "key": "ERP-USER-12345" }, "address": { "line1": "123 Main St", "line2": "Suite 400", "city": "Chicago", "state": "IL", "zipCode": "60601", "country": "USA", "market": "CHI", "latitude": "41.8781", "longitude": "-87.6298", "isAirportOrAirbase": false, "isConstructionOrUtilitySite": false, "isSmartyValidated": true, "obeysDst": true, "cityId": null }, "postalCode": "string", "city": { "name": "string", "stateProvince": "string" }, "airportCode": "string", "requestedStartDate": "2019-08-24", "requestedEndDate": "2019-08-24", "requestedStartTime": "string", "requestedEndTime": "string", "actualArrival": "2019-08-24T14:15:22Z", "actualDeparture": "2019-08-24T14:15:22Z", "dropTrailer": true, "notes": "string", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" }
- Productionhttps://api.mvmnt.io/v1/stops/{id}
- Demo (non-production)https://api.demo.mvmnt.io/v1/stops/{id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
'https://api.mvmnt.io/v1/stops/{id}' \
-H 'Authorization: Bearer <YOUR_JWT_HERE>'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "type": "PICK", "sequence": 0, "location": { "id": "550e8400-e29b-41d4-a716-446655440000", "key": "ERP-USER-12345" }, "address": { "line1": "123 Main St", "line2": "Suite 400", "city": "Chicago", "state": "IL", "zipCode": "60601", "country": "USA", "market": "CHI", "latitude": "41.8781", "longitude": "-87.6298", "isAirportOrAirbase": false, "isConstructionOrUtilitySite": false, "isSmartyValidated": true, "obeysDst": true, "cityId": null }, "postalCode": "string", "city": { "name": "string", "stateProvince": "string" }, "airportCode": "string", "requestedStartDate": "2019-08-24", "requestedEndDate": "2019-08-24", "requestedStartTime": "string", "requestedEndTime": "string", "actualArrival": "2019-08-24T14:15:22Z", "actualDeparture": "2019-08-24T14:15:22Z", "dropTrailer": true, "notes": "string", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" }
Re-place the stop at a location. A stop sits in exactly one place, so naming any one of location, postalCode, cityId or airportCode replaces the placement outright and clears the other three — there is no need to null them individually. A patch that clears the only placement without naming a replacement is rejected, because a stop with nowhere to be is a state creation will not produce either.
Re-place the stop at a location. A stop sits in exactly one place, so naming any one of location, postalCode, cityId or airportCode replaces the placement outright and clears the other three — there is no need to null them individually. A patch that clears the only placement without naming a replacement is rejected, because a stop with nowhere to be is a state creation will not produce either.
Re-place the stop at a location. A stop sits in exactly one place, so naming any one of location, postalCode, cityId or airportCode replaces the placement outright and clears the other three — there is no need to null them individually. A patch that clears the only placement without naming a replacement is rejected, because a stop with nowhere to be is a state creation will not produce either.
- Productionhttps://api.mvmnt.io/v1/stops/{id}
- Demo (non-production)https://api.demo.mvmnt.io/v1/stops/{id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X PATCH \
'https://api.mvmnt.io/v1/stops/{id}' \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'Content-Type: application/json' \
-d '{
"requestedStartDate": "2025-01-26",
"requestedStartTime": "08:00"
}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "type": "PICK", "sequence": 0, "location": { "id": "550e8400-e29b-41d4-a716-446655440000", "key": "ERP-USER-12345" }, "address": { "line1": "123 Main St", "line2": "Suite 400", "city": "Chicago", "state": "IL", "zipCode": "60601", "country": "USA", "market": "CHI", "latitude": "41.8781", "longitude": "-87.6298", "isAirportOrAirbase": false, "isConstructionOrUtilitySite": false, "isSmartyValidated": true, "obeysDst": true, "cityId": null }, "postalCode": "string", "city": { "name": "string", "stateProvince": "string" }, "airportCode": "string", "requestedStartDate": "2019-08-24", "requestedEndDate": "2019-08-24", "requestedStartTime": "string", "requestedEndTime": "string", "actualArrival": "2019-08-24T14:15:22Z", "actualDeparture": "2019-08-24T14:15:22Z", "dropTrailer": true, "notes": "string", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" }
- Productionhttps://api.mvmnt.io/v1/stops/{id}
- Demo (non-production)https://api.demo.mvmnt.io/v1/stops/{id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X DELETE \
'https://api.mvmnt.io/v1/stops/{id}' \
-H 'Authorization: Bearer <YOUR_JWT_HERE>'