Project44 provides a direct pass-through to Carrier APIs for LTL quoting, tendering, tracking, and document retrieval. For Project44 tracking see the Project44 tracking API article. Project44 provides users the ability to complete the following actions.
Get LTL Carrier Quotes.
Tender to LTL Carriers.
Document Retrieval.
Support for Hazardous Materials quoting and tendering.
Project44 provides “push” status updates to the TMS via a sites-based web service. Inbound LTL load status packets are processed as Platform Events. Starting or stopping Project44 LTL load tracking sends outbound packets that are processed by the QueuedTransactionJob.
Setup
Enter Credentials
Enable the Project44 integration by completing the following steps.
Navigate to TMS Admin.
Select Credentials.
Select the Global Services tab.
Find Project44 in the list and open the card.
Check the Enabled and Receive Updates boxes.
Enter the User ID and Password 1 into the text fields.
Click the Save button when finished.
Valid credentials are required from a Project44 subscription. See examples in the table below.
User ID | Password 1 | Password 2 | Customer Number |
---|---|---|---|
Email address format | Required |
Inbound Packet IP Ranges: Any post-backs from Project44 that do not originate from this IP mask are rejected as a security feature. Any changes to this range are provided by Revenova.
Navigate to TMS Admin, Configuration and confirm the Use Platform Events For boxes are checked for Project44, Project44 Tracking, and Project44 Unified Tracking.
Remote Site Settings
Upgrading from previous versions of the TMS may have outdated information. Check that the Remote Site Settings for the Project44 integration URL are up to date.
There are TWO remote site settings required. One for the API and one for the BOL document URL.
Click the Setup gear icon in the top right corner.
From the drop-down, click Setup.
In the Quick Find Toolbar type Remote Site Settings and click the link.
From the list of remote sites find Project44 and click the Edit link.
Update the Remote Site URL to match the Service URL below:
Service URL: https://na12.api.project44.com
Test Service URL: https://na12.api.sandbox.p-44.com
Request from Project44 what customer-specific URL documents are available from and add it as a Remote Site Setting.
It is in a format such as: https://prod-44742-images.s3.amazonaws.com.
Partner Community Setup
Project44 relies on a “push” approach to event processing, and requires a webhook to send information to the TMS. Create an API Site to accept inbound API traffic.
Create a Salesforce Site for API Guest User Access.
Set the public access for the Site.
Activate and Publish the Site.
Enter the API URL into the field for Inbound API Community URL under TMS Admin, in the Configuration section.
Add the following extension to the end of the URL to match the example below: /services/apexrest/rtms/tmslistener?org=00D180000008oA9EAI&source=Project44&pwd=4wGFDgnT950Ovg1
Send the post-back URL, the customer company name and contact info to support.americas@project44.com.
Project44 LTL Tracking webhook:
{API Community URL} /services/apexrest/rtms/tmslistener?org= {18-character org id} &source=Project44&pwd= {credentials code field}
Example: https://revenova.my.site.com/api/services/apexrest/rtms/tmslistener?org=00D180000008oA9EAI&source=Project44&pwd=4wGFDgnT950Ovg1
The Salesforce-generated API Community URL is case sensitive.
Project44 Setup
Navigate to the Project44 website and log in.
Enter the Carrier credentials for each Carrier to quote/tender.
Warning:
To properly tender, track, and manage documents with Carriers, the following information must be configured correctly.
All Carrier credentials are present and correct. Billing information for the Carrier must also be correct.
Account login groups are configured correctly. Blank values are acceptable when not using login groups.
The SCAC fields in the Project44 portal should match the SCAC fields on the Carrier Transportation Profile.
When entering a Capacity Provider Account Code field, do NOT enter a dash (-) between the SCAC Code and Reference Number. Enter a an underscore (_) between the values so the TMS can parse the values.
The following error displays if a Carrier is not enabled correctly in the Project44 website:
For customer-specific pricing:
Create a Login Group for each customer.
Populate the customer-specific credentials for each Login Group.
Copy the Carrier API Login Group field from Project44 into the customer Transportation Profile (in the TMS, on the Rates tab) with the Login Group Key.
Project44 supports a login group cascade concept. This allows for defining two login groups and setting the Carrier API Login Group field at both the customer and default Transportation Profile levels. When quotes are retrieved from Project44, two queries are made - one with each login group. Any quotes received from the first query are masked out of the second query.
Configure Carrier Pickup Notes on the Project44 website to prevent tenders from failing. (Note could be too long).
Multiple contracts for a given capacity provider can be set up by providing unique names in the Project44 portal.
See the Project44 Tracking article for additional tracking setup in the Project44 website (Reference Data Keys).
Other Setup
A Bill of Lading Number is NOT generated by Project44. The BOL # is generated and passed from the TMS during the tender operation.
A Bill of Lading Number must be present to use the Truckload load tracking API.
Load status API calls may return signed BOL and POD images.
Notes:
The default Tracking Provider for a Carrier is selected on the Carrier's Transportation Profile on the Settings tab.
Only tracking integrations with credentials display as possible options in the Tracking Provider picklist.
Select Project44 as the default Tracking Provider for tracking LTL Mode loads.
The Project44 integration only supports 2 Stop Loads. If more than 2 Stop locations are included on a Load, no information returns.
Project44 LTL tracking does not support the same location for Pickup and Delivery Stops. If the same location is used as a Pickup and Delivery, users receive an error.
TMS Admin
Carrier Services
The following settings under TMS Admin → Carrier Services control when a PRO Number is generated.
Warning: Create 1 Carrier Service per SCAC/Transportation Profile, Mode, and API Provider (Project44). Rates do not return from Project44 If multiple Carrier Services are created for the same SCAC and Mode.
Pickup Only: Check the Pickup Only box on Project44 Carrier Services to not immediately generate a PRO Number. If the PRO Number changes later in the load lifecycle the tracking data will be invalid.
If requesting quotes with the TMS Web Service, it is possible to override the timeout period with the LTL API Timeout Override (Seconds) field in TMS Admin → Configuration. This field only applies when quoting through Project44 with the Revenova Web Service.
SMC3 Quoting + Project44 Tender/Track/Images
You may set up hybrid API carrier services that use SMC3 for quoting and Project44 for tendering, tracking, and image retrieval. These Carrier Services should be set up with the SMC3 RateWare Credentials Id.
Integration Calls
Troubleshoot mismatched Carrier Quotes and Rate Entries with the following components.
LTL Quotes Request
Carrier quotes returned from Project44 contain the laneType in the response that is stored in the Direct/Interline field. Filter out Carrier quotes returned from Project44 in the Customer Portal by setting the Portal Quote Direct/Interline Filter field on the Transportation Profile.
Request Quotes in a Specific Currency
Project44 supports quoting in the following currencies.
USD
CAD
MXN
EUR
Add the Carrier Quote Preferred Currency field to the Load TMS1 field set to select a preferred currency when creating Loads. If no currency is selected, the User default currency is included.
Single currency orgs do not include the Carrier Quote Preferred Currency field when requesting quotes from Project44.
Tender Load Request
The Create a Shipment Request sends the Load, Stop, and other relevant information to the Carrier in the Tender request.
TMS Operation | Project44 Endpoint | Request Type | Response |
---|---|---|---|
Tender Load through Project44 | dispatchedshipments | POST | 200: Success 400: Invalid Request |
Each Carrier Quote returned from the Rate Quote Query Response contains a unique ID that is stored in the Carrier Quote Reference field. This field is included in the request.
The following logic determines the information sent to Project44 for Pickup or Delivery Instructions in the request.
When First and Last Stop Instructions fields and Pickup/Delivery Number fields all contain values, the following is sent in the request.
“(Instructions) - PU#: (Pickup/Delivery Number)” is sent in the pickupNote element.
“(Instructions) - Dlvy#: (Pickup/Delivery Number)” is sent in the deliveryNote element.
When no Instructions field(s) contain values, the following is sent in the request.
“PU#: Pickup/Delivery Number”
“Dlvy#: Pickup/Delivery Number”
When both First and Last Stop location Instructions and Pickup/Delivery Number fields contain no values, the pickupNote and deliveryNote elements are not included in the request.
Hazmat Loads Tendered via Project44 require a value for the HazMat Packaging Group field. Add None as a picklist value to send no value.
TMS Fields Included in Create a Shipment Request
Object | Field | Type | Project44 Field |
---|---|---|---|
Carrier Quote | Carrier API Login Group | Text(40) | capacityProviderAccountGroup: code |
Carrier Quote | Pickup Only | Checkbox | apiConfiguration.pickupOnly |
Carrier Quote | Carrier Quote Reference | Text(100) | capacityProviderQuoteNumber |
Carrier Quote | Service Class Code | Text(20) | accessorialServices.code |
Line Item | Dimension Units | Picklist | lengthUnit |
Line Item | Handling Units | Picklist | lineItems.packageType |
Line Item | HazMat Class/Division | Picklist | lineItems.hasmatDetail.hazardClass |
Line Item | HazMat Contact | Lookup(Contact) | emergencyContact.companyName |
Line Item | HazMat Contact | Lookup(Contact) | emergencyContact.contactName |
Line Item | HazMat Contact | Lookup(Contact) | emergencyContact.email |
Line Item | HazMat Contact | Lookup(Contact) | emergencyContact.faxNumber |
Line Item | HazMat Contact | Lookup(Contact) | emergencyContact.phoneNumber |
Line Item | HazMat Number Type | Picklist | lineItems.hazmatDetail.identificationNumber |
Line Item | HazMat Packaging Group | Picklist | lineItems.hazmatDetail.packingGroup |
Line Item | Height | Number(16, 2) | lineItems.height |
Line Item | HU Count | Number(18, 0) | lineItems.totalPackages |
Line Item | Item Description | Text(255) | lineItems.description, lineItems.hazmatDetail.properShippingName |
Line Item | Length | Number(16, 2) | lineItems.length |
Line Item | NMFC Class | Picklist | freightClass |
Line Item | NMFC Number | Text(20) | lineItems.nmfcItemCode |
Line Item | Packaging Units | Picklist | lineItems.totalPieces |
Line Item | Stackable | Checkbox | lineItems.stackable |
Line Item | Weight | Number(18, 0) | lineItems.totalWeight |
Line Item | Width | Number(16, 2) | lineItems.width |
Load | Bill of Lading Number | Text(55) | ***shipmentIdentifiers.value |
Load | Expected Delivery Date | Formula (Date) | deliveryWindow.date |
Load | Expected Ship Date | Formula (Date) | pickupWindow.date |
Load | First Stop | Lookup(Stop) | destinationLocation.address.addressLines |
Load | First Stop | Lookup(Stop) | destinationLocation.address.city |
Load | First Stop | Lookup(Stop) | destinationLocation.address.country |
Load | First Stop | Lookup(Stop) | destinationLocation.address.postalCode |
Load | First Stop | Lookup(Stop) | destinationLocation.address.state |
Load | Order Number | Text(50) (External ID) | ***shipmentIdentifiers.value |
Load | Last Stop | Lookup(Stop) | originLocation.address.addressLines |
Load | Last Stop | Lookup(Stop) | originLocation.address.city |
Load | Last Stop | Lookup(Stop) | originLocation.address.country |
Load | Last Stop | Lookup(Stop) | originLocation.address.postalCode |
Load | Last Stop | Lookup(Stop) | originLocation.address.state |
Load | Linear Feet | Number(10, 2) | totalLinearFeet |
Load | PO Number | Text(100) | ***shipmentIdentifiers.value |
Load | Weight Units | Picklist | weightUnit |
Stop (First) | Appointment Time OR Shipping/Receiving Hours | Text(11) | pickupWindow.endTime |
Stop (First) | Appointment Time OR Shipping/Receiving Hours | Text(11) | pickupWindow.startTime |
Stop (Last) | Appointment Time OR Shipping/Receiving Hours | Text(11) | deliveryWindow.endTime |
Stop (Last) | Appointment Time OR Shipping/Receiving Hours | Text(11) | deliveryWindow.endTime |
Stop | Instructions | Long Text Area(2000) | deliveryNote, pickupNote |
Stop | Location Name | Formula (Text) | destinationLocation.contact.companyName |
Stop | Location Name | Formula (Text) | originLocation.contact.companyName |
Stop (First) | Pickup/Delivery Number | Text(20) | pickupNote, ***shipmentIdentifiers.value |
Stop | Shipping/Receiving Contact | Lookup(Contact) | destinationLocation.contact.contactName |
Stop | Shipping/Receiving Contact | Lookup(Contact) | destinationLocation.contact.phoneNumber |
Stop | Shipping/Receiving Contact | Lookup(Contact) | destinationLocation.contact.email |
Stop | Shipping/Receiving Contact | Lookup(Contact) | originLocation.contact.contactName |
Stop | Shipping/Receiving Contact | Lookup(Contact) | originLocation.contact.phoneNumber |
Stop | Shipping/Receiving Contact | Lookup(Contact) | originLocation.contact.email |
Transportation Profile | SCAC | Text(4) | capacityProviderAccountGroup: code, carrierCode |
User | Address | Address | *requestorLocation.address.addressLines |
User | Address | Address | *requestorLocation.address.city |
User | Address | Address | *requestorLocation.address.country |
User | Address | Address | *requestorLocation.address.postalCode |
User | Address | Address | *requestorLocation.address.state |
User | Company Name | Text(80) | **requestorLocation.contact.companyName |
User | Email Sender Address | **requestorLocation.contact.email | |
User | Name | Name | **requestorLocation.contact.contactName |
User | Phone | Phone | **requestorLocation.contact.phoneNumber |
TRUE | apiConfiguration.noteConfigruation.enableTruncation | ||
TRUE | apiConfiguration.enableUnitConversion | ||
Org. Currency (single) or Load currency (multicurrency) | currencyCode | ||
Hard-coded values from the TMS. Determines the shipIdentifier.value. | Hard-coded values from the TMS. Determines the shipIdentifier.value. | BILL_OF_LADING, PICKUP, EXTERNAL, CUSTOMER_REFERENCE | shipmentIdentifiers.type |
*Requestor Location Address fields are based on the user performing the actions that trigger the API call to Project44.
Internal requests performed by TMS users sends the User address fields.
Customer Portal requests send the Carrier Account owner address fields.
If no Carrier Account Owner fields are populated on the Load, the First Stop Account location address fields on the Load are sent.
**Requestor Contact fields are based on the user performing the actions that trigger the API call to Project44.
Internal requests performed by TMS users sends the internal user contact information.
Customer Portal requests send the Carrier Account owner Contact fields.
***Shipment Identifiers are sent if a Value exists for a Load in the TMS. The Type fields sent are hard-coded by the TMS based on the existing Values.
If there is no colon in the Carrier Quote Reference field, the SCAC is sent as the capacityProviderAccountGroup code.
HazMat Contact Information
The HazMat Contact Company Name is first sent from the Line Item HazMat Contact Account Name. If no value exists, the First Stop Location Account Contact Company Name with the HazMat role is sent.
The HazMat Contact Contact Name is first sent from the Line Item HazMat Contact Name. If no value exists, the First Stop Location Account Contact Name with the HazMat role is sent.
The HazMat Contact Phone Number is first sent from the Line Item HazMat Contact. If no value exists, the First Stop Location Account Contact with the HazMat role Phone Number is sent.
The HazMat Contact Email is first sent from the Line Item HazMat Contact. If no value exists, the First Stop Location Account Contact with the HazMat role Email is sent.
The HazMat Contact Fax is first sent from the Line Item HazMat Contact. If no value exists, the First Stop Location Account Contact with the HazMat role Fax Number is sent.
Sample Create a Shipment Request Payload
{
"accessorialServices": [
{}
],
"apiConfiguration": {
"allowUnsupportedAccessorials": true,
"enableUnitConversion": true,
"fallBackToDefaultAccountGroup": true,
"noteConfiguration": {},
"pickupOnly": true,
"preScheduledPickup": true
},
"capacityProviderAccountGroup": {
"code": "string",
"accounts": []
},
"capacityProviderQuoteNumber": "string",
"carrierCode": "string",
"currencyCode": "USD",
"customsInfo": {
"customsBrokerLocation": {}
},
"deliveryNote": "string",
"deliveryWindow": {
"date": "2019-08-24",
"startTime": "15:00",
"endTime": "17:00"
},
"destinationInvolvedParties": [
{}
],
"destinationLocation": {
"address": {},
"contact": {}
},
"directionOverride": "SHIPPER",
"emergencyContact": {
"companyName": "string",
"contactName": "string",
"phoneNumber": "string",
"phoneNumberCountryCode": "string",
"phoneNumber2": "string",
"phoneNumber2CountryCode": "string",
"email": "string",
"faxNumber": "string",
"faxNumberCountryCode": "string"
},
"enhancedHandlingUnits": [
{}
],
"handlingUnitTypeQuantities": [
{}
],
"lengthUnit": "IN",
"lineItems": [
{}
],
"originInvolvedParties": [
{}
],
"originLocation": {
"address": {},
"contact": {}
},
"paymentTermsOverride": "PREPAID",
"pickupNote": "string",
"pickupWindow": {
"date": "2019-08-24",
"startTime": "15:00",
"endTime": "17:00"
},
"requesterLocation": {
"address": {},
"contact": {}
},
"shipmentIdentifiers": [
{}
],
"totalHandlingUnits": 0,
"totalLinearFeet": 0,
"weightUnit": "LB"
}
Sample Create a Shipment Response Payload
{
"id": 674543219,
"infoMessages": [
{}
],
"shipmentIdentifiers": [
{}
]
}
TMS Field Updates
Object | Field | Type | Project44 Field |
---|---|---|---|
Load | API Load Id | Text(40) | id |
Load | PRO Number | Text(40) | shipmentIdentifiers.type, ipmentIdentifiers.value |
Load | Tracking Number | Text(40) | id |
Stop (First) | References | Text(255) | shipmentIdentifiers.type, ipmentIdentifiers.value |