Primus Integration Guide
Integrate FTM with Primus REST API to request LTL rate quotes and book shipments directly from the Lane Quote page in Salesforce.
Overview
The Primus Freight integration allows FTM users to:
- Retrieve real-time LTL rate quotes (multiple carriers)
- View rate details such as total cost, transit days, and service level
- Instantly book shipments using the selected quote
This integration connects to Primus via HTTPS using JSON-based REST APIs.
All requests are made through secure Bearer Token authentication.
1️⃣ User Information
Purpose
This integration streamlines carrier selection and shipment booking by bringing Primus LTL rates and booking directly into the Lane Quote workflow.
With a single click:
- Users can fetch rates from multiple carriers
- Review pricing, service levels, and transit times
- Select a quote and book the shipment instantly

Workflow (User Perspective)
- Open any Lane Quote record in Salesforce.
- Click the “Get Rates” button on the Visualforce page.
- Calls PrimusOnLaneQuote.CalloutToPrimus().
- Returns multiple LTL rate options (carriers, total cost, transit days).
- Select a quote and click “Book”.
- Calls PrimusOnLaneQuote.CalloutToBook() or PrimusBooking.CalloutToBook().
- Sends a booking request to Primus using the selected vendorId and quoteNumber.
- Shipment is confirmed through the API response and logged in Salesforce.
Key Features
✅ Real-time multi-carrier LTL rates
✅ Supports rate types (LTL, GUARANTEED, SP, VOL)
✅ Instant booking via Primus API
✅ Parses rate breakdowns, remarks, transit days
✅ Displays results directly on the Lane Quote Visualforce page
What You’ll See in Salesforce
After running the rate call:
- List of available rates displayed on the page (carrier name, service level, total, transit days)
- Each row includes details like:
- Rate Name
- Total Cost
- Transit Days
- Guaranteed flag
- Vendor ID
- Users can then click “Book” to finalize the shipment.
Supported Use Cases
- Rate discovery for LTL shipments
- Direct shipment booking using the selected quote
- Integration with Quote Cargo line items for multi-piece freight details


Prerequisites
Before using this integration:
- Lane Quote record must include:
- Pickup & Delivery City, State, Zip, Country
- Freight Weight, Class, and Dimensions
- At least one Quote Cargo record must exist under the Lane Quote.
These are used to build the freightInfo payload for Primus. - Internet-accessible Salesforce org (for REST callouts).
- Remote Site Setting:
- https://restapi.shipprimus.com
- Proper Apex Class Access:
- PrimusOnLaneQuote
- PrimusBooking
2️⃣ Developer Information
Apex Components
| Component | Purpose |
| PrimusOnLaneQuote | Main controller for rate retrieval & booking |
| PrimusBooking | Optional standalone class for direct booking (used for testing) |
Authentication
Primus uses a two-step authentication process:
- POST /api/v1/login
- Sends username/password JSON to obtain an access token.
- Bearer Token Authorization
- Token is passed in headers for subsequent requests.
Sample Login Payload
{
"username": "FTMCLOUD",
"password": "DGL123*"
}
Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs..."
}
}
The returned accessToken is valid for subsequent API calls.
Endpoints
| Purpose | Method | URL |
| Login | POST | https://restapi.shipprimus.com/api/v1/login |
| Rate Quote | GET | https://restapi.shipprimus.com/api/v1/rate/multiple |
| Book Shipment | GET | https://restapi.shipprimus.com/api/v1/book?vendorId=<id>"eNumber=<num> |
Rate Request Structure
- Example Query (GET)
/api/v1/rate/multiple?
destinationCity=Irving
&destinationCountry=US
&destinationState=TX
&destinationZipcode=75063
&freightInfo=[{...}]
&originCity=Beverly
&originCountry=US
&originState=MA
&originZipcode=01915
&rateTypesList[]=LTL|GUARANTEED|SP|VOL
&uom=us
- Freight Info JSON
[{
"qty": "1",
"dimType": "PLT",
"weight": "100",
"weightType": "each",
"length": "48",
"width": "48",
"height": "48",
"stack": false,
"volume": "64.00",
"hazmat": false,
"freightClass": "300"
}]
Response Example
{
"data": {
"results": {
"rates": [
{
"name": "FedEx Freight",
"total": 1120.50,
"serviceLevel": "Standard",
"transitDays": "2",
"guaranteed": false,
"vendorId": 502885124,
"quoteNumber": "75190672"
},
{
"name": "SAIA",
"total": 1087.00,
"serviceLevel": "Guaranteed",
"transitDays": "3",
"guaranteed": true,
"vendorId": 502885125,
"quoteNumber": "75190675"
}
]
}
}
}
Data Classes (Simplified)
| Class | Description |
| ResponseWrapper | Root wrapper for JSON data |
| Data | Contains results |
| Results | Contains list of Rate objects |
| Rate | Core object holding rate info (name, total, service level, etc.) |
Rate Fields
| Field | Type | Description |
| name | String | Carrier name |
| total | Decimal | Total rate charge |
| serviceLevel | String | Service level name |
| transitDays | String | Transit duration |
| guaranteed | Boolean | Indicates guaranteed service |
| vendorId | Integer | Carrier/vendor ID |
| quoteNumber | String | Quote identifier |
| rateRemarks | List | Remarks (HTML cleaned before display) |
Booking Request
Once a rate is selected:
- The system sends vendorId and quoteNumber to the booking endpoint.
Example
GET https://restapi.shipprimus.com/api/v1/book?vendorId=502885124"eNumber=75190672
Response
{
"status": "success",
"message": "Shipment booked successfully",
"bookingId": "PRM123456"
}
Error Handling
| Condition | Behavior |
| Missing Freight Info | Skipped; debug logs indicate missing parameters |
| Invalid Token | Returns 401; re-authenticate |
| Non-200 Response | Sets static variable error = ‘Missing required parameter!’ |
| HTML in rateRemarks | Cleaned via regex replaceAll(‘<[^>]+>’, ”) |
| Empty rates array | No response displayed; system.debug message only |
Security Recommendations
⚠️ Do NOT hard-code credentials.
Move username and password into a Protected Custom Metadata/Setting such as Primus_Config__mdt with fields:
- Username__c
- Password__c
Example reference in Apex:
Primus_Config__mdt cfg = Primus_Config__mdt.getInstance('Default');
String username = cfg.Username__c;
String password = cfg.Password__c;
Testing
You can trigger calls manually via Anonymous Apex:
PrimusOnLaneQuote.CalloutToPrimus('a0HXXXXXXXXXXXX');
PrimusOnLaneQuote.CalloutToBook();
Or for standalone booking:
PrimusBooking.CalloutToBook();
Deployment Checklist
✅ Add Remote Site Setting for https://restapi.shipprimus.com
✅ Move credentials to protected metadata or Named Credential
✅ Ensure Apex access to:
- PrimusOnLaneQuote
- PrimusBooking
✅ Grant access to Visualforce page (if used)
✅ Verify Lane Quote field mappings and Quote Cargo child records
Support
📧 FTM Integration Support: [email protected]