MVMNT Quotes API
Quote management operations. Quotes are pricing requests/responses that can be converted to shipments.
Quote management operations. Quotes are pricing requests/responses that can be converted to shipments.
openapi: 3.1.0
info:
title: MVMNT Bill Payments Quotes API
version: 1.0.0
description: "The MVMNT API enables you to automate freight brokerage workflows by integrating\ndirectly with our Transportation Management System.\n\n## Authentication\n\nOAuth 2.0 client credentials flow. See [Authentication Guide](/getting-started/authentication)\nfor details.\n\n### Token Endpoint\n\n```\nPOST https://api.mvmnt.io/oauth2/token\n```\n\n#### Request\n\n**Headers:**\n```http\nContent-Type: application/x-www-form-urlencoded\n```\n\n**Body Parameters:**\n```\ngrant_type=client_credentials\nclient_id=YOUR_CLIENT_ID\nclient_secret=YOUR_CLIENT_SECRET\n```\n\n#### Example Request\n\n```bash\ncurl -X POST https://api.mvmnt.io/oauth2/token \\\n -H \"Content-Type: application/x-www-form-urlencoded\" \\\n -d \"grant_type=client_credentials\" \\\n -d \"client_id=YOUR_CLIENT_ID\" \\\n -d \"client_secret=YOUR_CLIENT_SECRET\"\n```\n\n#### Success Response\n\n**Status:** `200 OK`\n\n```json\n{\n \"access_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 3600\n}\n```\n\n**Response Fields:**\n- `access_token`: JWT Bearer token to use for API requests\n- `token_type`: Always `Bearer`\n- `expires_in`: Token lifetime in seconds (3600 = 1 hour)\n"
contact:
name: MVMNT Support
email: support@mvmnt.io
url: https://docs.mvmnt.io
license:
name: Proprietary
url: https://mvmnt.io/legal/terms
x-parsed-md-description:
result:
- $$mdtype: Node
errors: []
lines:
- 0
- 2
inline: false
attributes: {}
children:
- $$mdtype: Node
errors: []
lines:
- 0
- 2
inline: false
attributes: {}
children:
- $$mdtype: Node
errors: []
lines:
- 0
- 2
inline: true
attributes:
content: The MVMNT API enables you to automate freight brokerage workflows by integrating
children: []
type: text
annotations: []
slots: {}
- $$mdtype: Node
errors: []
lines:
- 0
- 2
inline: true
attributes: {}
children: []
type: softbreak
annotations: []
slots: {}
- $$mdtype: Node
errors: []
lines:
- 0
- 2
inline: true
attributes:
content: directly with our Transportation Management System.
children: []
type: text
annotations: []
slots: {}
type: inline
annotations: []
slots: {}
type: paragraph
annotations: []
slots: {}
- $$mdtype: Node
errors: []
lines:
- 3
- 4
inline: false
attributes:
level: 2
children:
- $$mdtype: Node
errors: []
lines:
- 3
- 4
inline: false
attributes: {}
children:
- $$mdtype: Node
errors: []
lines:
- 3
- 4
inline: true
attributes:
content: Authentication
children: []
type: text
annotations: []
slots: {}
type: inline
annotations: []
slots: {}
type: heading
annotations: []
slots: {}
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: false
attributes: {}
children:
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: false
attributes: {}
children:
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: true
attributes:
content: 'OAuth 2.0 client credentials flow. See '
children: []
type: text
annotations: []
slots: {}
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: true
attributes:
href: /getting-started/authentication
children:
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: true
attributes:
content: Authentication Guide
children: []
type: text
annotations: []
slots: {}
type: link
annotations: []
slots: {}
redocly:::linkOriginal:href: /getting-started/authentication
- $$mdtype: Node
errors: []
lines:
- 5
- 6
inline: true
attributes:
content: ' for details.'
children: []
type: text
annotations: []
slots: {}
type: inline
annotations: []
slots: {}
type: paragraph
annotations: []
slots: {}
servers:
- url: https://api.mvmnt.io/v1
description: Production
security:
- BearerAuth: []
tags:
- name: Quotes
description: 'Quote management operations.
Quotes are pricing requests/responses that can be converted to shipments.
'
paths:
/quotes/filter:
post:
summary: Filter quotes
description: 'Search for quotes using filter criteria.
## Common Filters
- Active quotes: `{ "filter": { "status": { "in": ["DRAFT", "REQUESTED", "QUOTED"] } } }`
- Won quotes: `{ "filter": { "status": { "equalTo": "WON" } } }`
- By customer: `{ "filter": { "customerId": { "equalTo": "uuid" } } }`
- Expiring soon: `{ "filter": { "expiresAt": { "lessThanOrEqualTo": "2025-01-20T00:00:00Z" } } }`
'
operationId: filterQuotes
tags:
- Quotes
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QuoteFilterRequest'
examples:
activeQuotes:
summary: Filter active quotes
value:
filter:
status:
in:
- DRAFT
- REQUESTED
- QUOTED
pageSize: 50
byCustomer:
summary: Filter by customer
value:
filter:
customerId:
equalTo: 550e8400-e29b-41d4-a716-446655440000
responses:
'200':
description: Quotes matching filter criteria
content:
application/json:
schema:
type: object
required:
- data
- pagination
properties:
data:
type: array
items:
$ref: '#/components/schemas/Quote'
pagination:
$ref: '#/components/schemas/PaginationInfo'
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'422':
$ref: '#/components/responses/ValidationError'
/quotes:
post:
summary: Create a quote
description: 'Create a new quote with order details.
## How it works
Creating a quote also creates an associated Order containing the route and freight details.
The Order is embedded in the Quote and cannot be managed separately.
## Required fields
- `customer`: Reference to the customer (shipper profile)
- `order`: Order details including stops and mode
## Example workflow
1. Create quote with customer and order details
2. Add pricing (amount) via PATCH
3. Send to customer (status changes to QUOTED)
4. Convert to shipment when accepted (POST /quotes/{id}/convert-to-shipment)
'
operationId: createQuote
tags:
- Quotes
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QuoteInput'
examples:
basicQuote:
summary: Basic TL quote
value:
customer:
id: 550e8400-e29b-41d4-a716-446655440000
order:
mode: TL
stops:
- type: PICKUP
address:
street1: 123 Warehouse Ave
city: Los Angeles
stateProvince: CA
postalCode: '90210'
country: US
requestedStartDate: '2025-01-20'
- type: DELIVERY
address:
street1: 456 Distribution Center
city: New York
stateProvince: NY
postalCode: '10001'
country: US
requestedStartDate: '2025-01-25'
freight:
handlingUnitQuantity: 10
handlingUnitType: PALLET
weight: 15000
amount: 2500
expiresAt: '2025-01-18T23:59:59Z'
responses:
'201':
description: Quote created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Quote'
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'422':
$ref: '#/components/responses/ValidationError'
/quotes/{id}:
get:
summary: Get a quote
description: 'Retrieve a quote by ID or key.
The response includes embedded order details (route, freight, equipment).
'
operationId: getQuote
tags:
- Quotes
parameters:
- $ref: '#/components/parameters/IdOrClientKey'
- $ref: '#/components/parameters/LookupBy'
responses:
'200':
description: Quote retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Quote'
'401':
$ref: '#/components/responses/UnauthorizedError'
'404':
$ref: '#/components/responses/NotFoundError'
patch:
summary: Update a quote
description: 'Update quote fields including status changes.
## Status changes
Status changes use this endpoint (not separate action endpoints):
- Set to QUOTED: `{ "status": "QUOTED", "amount": 2500 }`
- Set to WON: `{ "status": "WON" }`
- Set to LOST: `{ "status": "LOST", "lostReason": "TOO_HIGH" }`
## Validation rules
- When setting `status` to `LOST`, `lostReason` is required
- When `lostReason` is `OTHER`, `lostReasonText` is required
## Note
To convert a won quote to a shipment, use POST /quotes/{id}/convert-to-shipment
'
operationId: updateQuote
tags:
- Quotes
parameters:
- $ref: '#/components/parameters/IdOrClientKey'
- $ref: '#/components/parameters/LookupBy'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QuotePatch'
examples:
setQuoted:
summary: Set quote as quoted
value:
status: QUOTED
amount: 2500
setWon:
summary: Mark quote as won
value:
status: WON
setLost:
summary: Mark quote as lost
value:
status: LOST
lostReason: TOO_HIGH
setLostOther:
summary: Mark lost with custom reason
value:
status: LOST
lostReason: OTHER
lostReasonText: Customer chose competitor with faster transit time
responses:
'200':
description: Quote updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Quote'
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'404':
$ref: '#/components/responses/NotFoundError'
'422':
$ref: '#/components/responses/ValidationError'
delete:
summary: Delete a quote
description: 'Soft delete a quote.
The quote record is marked as deleted but not permanently removed.
Associated orders are also soft deleted.
'
operationId: deleteQuote
tags:
- Quotes
parameters:
- $ref: '#/components/parameters/IdOrClientKey'
- $ref: '#/components/parameters/LookupBy'
responses:
'204':
description: Quote deleted successfully
'401':
$ref: '#/components/responses/UnauthorizedError'
'404':
$ref: '#/components/responses/NotFoundError'
/quotes/{id}/convert-to-shipment:
post:
summary: Convert quote to shipment
description: 'Convert an accepted quote into a shipment.
## What happens
1. Quote status is set to WON (if not already)
2. A new Shipment is created
3. The Order from the quote is linked to the shipment
4. Optionally, additional orders can be added
## Prerequisites
- Quote must be in QUOTED or WON status
- Quote cannot already have a shipment
## Response
Returns the IDs of both the quote and the newly created shipment.
'
operationId: convertQuoteToShipment
tags:
- Quotes
parameters:
- $ref: '#/components/parameters/IdOrClientKey'
- $ref: '#/components/parameters/LookupBy'
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ConvertToShipmentRequest'
examples:
simpleConvert:
summary: Simple conversion
value: {}
withAdditionalOrder:
summary: Add additional order
value:
additionalOrders:
- mode: TL
stops:
- type: PICKUP
location:
id: 550e8400-e29b-41d4-a716-446655440001
requestedStartDate: '2025-01-22'
- type: DELIVERY
location:
id: 550e8400-e29b-41d4-a716-446655440002
requestedStartDate: '2025-01-27'
responses:
'200':
description: Quote converted to shipment successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ConvertToShipmentResponse'
examples:
converted:
summary: Successful conversion
value:
quoteId: 550e8400-e29b-41d4-a716-446655440000
quoteStatus: WON
shipmentId: 660e8400-e29b-41d4-a716-446655440001
shipmentKey: SHP-12345
orderId: 770e8400-e29b-41d4-a716-446655440002
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'404':
$ref: '#/components/responses/NotFoundError'
'409':
description: Quote already converted or in invalid status
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Error'
example:
type: https://api.mvmnt.io/problems/conflict
title: Conflict
status: 409
detail: Quote has already been converted to shipment SHP-12345
components:
schemas:
FloatFilter:
type: object
description: Filter options for float/number fields
properties:
equalTo:
type: number
format: float
description: Exact match
notEqualTo:
type: number
format: float
description: Not equal to
lessThan:
type: number
format: float
description: Less than
lessThanOrEqualTo:
type: number
format: float
description: Less than or equal to
greaterThan:
type: number
format: float
description: Greater than
greaterThanOrEqualTo:
type: number
format: float
description: Greater than or equal to
isNull:
type: boolean
description: Field is null (true) or not null (false)
ConvertToShipmentResponse:
type: object
required:
- quoteId
- quoteStatus
- shipmentId
- shipmentKey
- orderId
properties:
quoteId:
type: string
format: uuid
description: Quote ID that was converted
quoteStatus:
type: string
enum:
- WON
description: Quote status after conversion (always WON)
shipmentId:
type: string
format: uuid
description: Created shipment ID
shipmentKey:
type: string
description: Created shipment friendly ID
orderId:
type: string
format: uuid
description: Order ID from the quote
QuoteStatus:
type: string
enum:
- DRAFT
- REQUESTED
- QUOTED
- RECEIVED_REPLY
- SENT_REPLY
- RECEIVED_COUNTER
- SENT_COUNTER
- WON
- LOST
- PASS
- CANCELED
description: 'Current status in the quote lifecycle.
Initial states:
- `DRAFT`: Quote being drafted
- `REQUESTED`: Customer requested a quote (needs pricing)
Active states:
- `QUOTED`: Price sent to customer
- `RECEIVED_REPLY`: Received reply from customer
- `SENT_REPLY`: Sent reply to customer
- `RECEIVED_COUNTER`: Received counter-offer
- `SENT_COUNTER`: Sent counter-offer
Final states:
- `WON`: Customer accepted the quote
- `LOST`: Quote not accepted
- `PASS`: Broker declined to quote
- `CANCELED`: Quote canceled
'
ValidationError:
type: object
required:
- error
- message
- details
properties:
error:
type: string
description: Error code
example: validation_error
message:
type: string
description: Human-readable error message
details:
type: array
description: Validation error details
items:
type: object
required:
- field
- message
properties:
field:
type: string
description: Field name that failed validation
message:
type: string
description: Validation error message
Error:
type: object
required:
- error
- message
properties:
error:
type: string
description: Error code
message:
type: string
description: Human-readable error message
QuoteSide:
type: string
enum:
- SELL
- BUY
description: 'Quote direction.
- `SELL`: Selling to shipper (customer quote)
- `BUY`: Buying from carrier (carrier quote)
'
CarrierReference:
type: object
description: 'Enhanced reference to a carrier resource (returned in responses).
Includes full carrier details in addition to id/key.
Note: Does NOT include nested references (contacts, etc.) to prevent recursion.
Maximum nesting depth: 1 level.
'
required:
- id
- name
- createdAt
- updatedAt
properties:
id:
type: string
format: uuid
description: Carrier UUID
example: 550e8400-e29b-41d4-a716-446655440000
key:
type:
- string
- 'null'
maxLength: 512
description: Client-defined reference ID if set
example: ERP-CARRIER-SWIFT
name:
type: string
description: Carrier company name
example: Swift Transportation
phoneNumber:
type:
- string
- 'null'
description: Primary phone number
example: +1-555-987-6543
email:
type:
- string
- 'null'
format: email
description: Primary email address
example: dispatch@swifttrans.com
createdAt:
type: string
format: date-time
description: When the carrier was created
example: '2025-01-15T10:00:00Z'
updatedAt:
type: string
format: date-time
description: When the carrier was last updated
example: '2025-01-15T14:30:00Z'
deletedAt:
type:
- string
- 'null'
format: date-time
description: When the carrier was soft deleted (null if active)
example: null
TransportMode:
type: string
enum:
- TL
- LTL
- AIR
- OCEAN
- RAIL
- INTERMODAL
- DRAYAGE
description: 'Transportation mode.
- `TL`: Full Truckload
- `LTL`: Less than Truckload
- `AIR`: Air freight
- `OCEAN`: Ocean freight
- `RAIL`: Rail freight
- `INTERMODAL`: Intermodal (multiple modes)
- `DRAYAGE`: Drayage/cartage
'
QuoteLostReason:
type: string
enum:
- EXPIRED
- NO_REASON
- NO_RESPONSE
- TOO_HIGH
- TOO_SLOW
- TRUCK_NOT_AVAILABLE
- OTHER
description: 'Reason why the quote was lost.
- `EXPIRED`: Quote expired without response
- `NO_REASON`: No specific reason given
- `NO_RESPONSE`: Customer didn''t respond
- `TOO_HIGH`: Price was too high
- `TOO_SLOW`: Response was too slow
- `TRUCK_NOT_AVAILABLE`: Capacity not available
- `OTHER`: Other reason (see lostReasonText)
'
PaginationInfo:
type: object
required:
- pageSize
- hasNextPage
properties:
pageSize:
type: integer
description: Number of items per page
example: 50
hasNextPage:
type: boolean
description: Whether there are more pages
example: true
hasPreviousPage:
type: boolean
description: Whether there are previous pages
example: false
endCursor:
type:
- string
- 'null'
description: Cursor for the next page (null if no next page)
example: eyJpZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCJ9
QuoteSideFilter:
type: object
properties:
equalTo:
$ref: '#/components/schemas/QuoteSide'
notEqualTo:
$ref: '#/components/schemas/QuoteSide'
in:
type: array
items:
$ref: '#/components/schemas/QuoteSide'
QuoteFilter:
type: object
properties:
id:
$ref: '#/components/schemas/UUIDFilter'
status:
$ref: '#/components/schemas/QuoteStatusFilter'
side:
$ref: '#/components/schemas/QuoteSideFilter'
customerId:
$ref: '#/components/schemas/UUIDFilter'
carrierId:
$ref: '#/components/schemas/UUIDFilter'
assigneeId:
$ref: '#/components/schemas/UUIDFilter'
amount:
$ref: '#/components/schemas/FloatFilter'
expiresAt:
$ref: '#/components/schemas/DatetimeFilter'
createdAt:
$ref: '#/components/schemas/DatetimeFilter'
updatedAt:
$ref: '#/components/schemas/DatetimeFilter'
and:
type: array
items:
$ref: '#/components/schemas/QuoteFilter'
or:
type: array
items:
$ref: '#/components/schemas/QuoteFilter'
not:
$ref: '#/components/schemas/QuoteFilter'
QuoteFilterRequest:
type: object
properties:
filter:
$ref: '#/components/schemas/QuoteFilter'
pageSize:
type: integer
minimum: 1
maximum: 100
default: 50
cursor:
type: string
UUIDFilter:
type: object
description: Filter options for UUID fields (all operations)
properties:
equalTo:
type: string
format: uuid
description: Exact match
notEqualTo:
type: string
format: uuid
description: Not equal to
in:
type: array
items:
type: string
format: uuid
description: Matches any UUID in the array
notIn:
type: array
items:
type: string
format: uuid
description: Does not match any UUID in the array
isNull:
type: boolean
description: Field is null (true) or not null (false)
AddressInput:
type: object
description: Address data for creating a new location
required:
- line1
- city
- country
- market
properties:
line1:
type: string
description: Primary street address line
example: 123 Main St
line2:
type: string
description: Secondary address line (suite, floor, etc.)
example: Suite 400
city:
type: string
description: City name
example: Chicago
country:
type: string
description: Country name or code
example: USA
market:
type: string
description: Market or region identifier
example: CHI
latitude:
type: string
description: Latitude coordinate
example: '41.8781'
longitude:
type: string
description: Longitude coordinate
example: '-87.6298'
isAirportOrAirbase:
type: boolean
default: false
description: Whether this location is an airport or airbase
example: false
isConstructionOrUtilitySite:
type: boolean
default: false
description: Whether this location is a construction or utility site
example: false
isSmartyValidated:
type: boolean
default: false
description: Whether address has been validated by SmartyStreets
example: true
obeysDst:
type: boolean
default: true
description: Whether this location observes daylight saving time
example: true
cityId:
type: string
format: uuid
description: Reference to standardized city record (internal use)
Quote:
type: object
required:
- id
- key
- side
- status
- createdAt
properties:
id:
type: string
format: uuid
description: Unique identifier
example: 550e8400-e29b-41d4-a716-446655440000
key:
type: string
description: Human-readable quote ID (e.g., "Q003602")
example: Q003602
side:
$ref: '#/components/schemas/QuoteSide'
status:
$ref: '#/components/schemas/QuoteStatus'
amount:
type:
- number
- 'null'
description: Quoted price
example: 2500
target:
type:
- number
- 'null'
description: Target price for margin calculation
example: 2200
margin:
type:
- number
- 'null'
description: Calculated margin percentage
example: 12
expiresAt:
type:
- string
- 'null'
format: date-time
description: Quote expiration timestamp
customer:
$ref: '#/components/schemas/CustomerReference'
description: Customer (for SELL quotes)
carrier:
$ref: '#/components/schemas/CarrierReference'
description: Carrier (for BUY quotes)
order:
$ref: '#/components/schemas/OrderSummary'
description: Order details (route, freight)
lostReason:
oneOf:
- $ref: '#/components/schemas/QuoteLostReason'
- type: 'null'
description: Why the quote was lost
lostReasonText:
type:
- string
- 'null'
description: Additional text for lost reason
closedTime:
type:
- string
- 'null'
format: date-time
description: When the quote was closed (won/lost)
assignee:
$ref: '#/components/schemas/UserReference'
description: Assigned sales rep
shipmentId:
type:
- string
- 'null'
format: uuid
description: Shipment ID if converted
shipmentKey:
type:
- string
- 'null'
description: Shipment friendly ID if converted
createdAt:
type: string
format: date-time
updatedAt:
type:
- string
- 'null'
format: date-time
CustomerReference:
type: object
description: 'Enhanced reference to a customer resource (returned in responses).
Includes full customer details in addition to id/key.
Note: Does NOT include nested references (paymentTerm, contacts, etc.) to prevent recursion.
Maximum nesting depth: 1 level.
'
required:
- id
- name
- friendlyId
- status
- createdAt
- updatedAt
properties:
id:
type: string
format: uuid
description: Customer UUID
example: 550e8400-e29b-41d4-a716-446655440000
key:
type:
- string
- 'null'
maxLength: 512
description: Client-defined reference ID if set
example: ERP-CUSTOMER-ACME
name:
type: string
description: Customer company name
example: Acme Manufacturing Corp
friendlyId:
type: string
description: Human-readable customer identifier
example: A123456
status:
type: string
description: Customer status
enum:
- PROSPECT
- ACTIVE
- INACTIVE
- CHURNED
example: ACTIVE
phoneNumber:
type:
- string
- 'null'
description: Primary phone number
example: +1-555-123-4567
website:
type:
- string
- 'null'
description: Customer website URL
example: https://acme-manufacturing.com
createdAt:
type: string
format: date-time
description: When the customer was created
example: '2025-01-15T10:00:00Z'
updatedAt:
type: string
format: date-time
description: When the customer was last updated
example: '2025-01-15T14:30:00Z'
deletedAt:
type:
- string
- 'null'
format: date-time
description: When the customer was soft deleted (null if active)
example: null
UserReference:
type: object
description: 'Enhanced reference to a user resource (returned in responses).
Includes full user details in addition to id/key.
Note: Does NOT include nested references (t
# --- truncated at 32 KB (47 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/mvmnt/refs/heads/main/openapi/mvmnt-quotes-api-openapi.yml