DAT Integration Guide:
Streamline your load posting, updating, deleting, and load discovery workflow with DAT, directly inside FTM, with secure token handling and minimal re-entry.
Overview
This DAT integration supports two primary workflows inside FTM:
A) Post / Update / Delete an FTM Load to DAT
Dispatchers can open a Load record and:
- Post the load to DAT (creates a DAT posting).
- Update the existing DAT posting when the load changes.
- Delete the DAT posting when the load is cancelled or no longer needed.
- Automatically store DAT identifiers back on the FTM Load record (DAT_Post_Id__c, DAT_Shipment_Id__c).
- Automatically create a completed Salesforce Task logging the result.
B) Search DAT Loads for a Driver/Carrier/Truck + Create an FTM Load
Dispatchers can open a Driver/Carrier/Truck (Employee) record and:
- Search DAT loads using Driver/Carrier/Truck preferences (equipment, max deadhead, minimum RPM, pickup window).
- Apply filters:
- Rate-per-mile minimum
- Equipment match
- Distance validation via Google Distance Matrix API
- Show:
- Accepted loads and rejected loads with rejection reasons
- Create a new FTM Load in Salesforce from a selected DAT result.
1⃣ User Information: What This Integration Does
Purpose
The integration allows users to work with DAT inside FTM:
- Load Posting Management: post/update/delete DAT postings directly from an FTM Load.
- Load Discovery for Driver/Carrier/Trucks: search and filter DAT loads for a Driver/Carrier/Truck, then create an FTM Load from a selected DAT record.
This reduces manual work, improves speed, and ensures key data (DAT IDs) is tracked inside FTM.
User Workflow
Workflow A (Shippers & Brokers): Post / Update / Delete Load to DAT

- Dispatcher opens an FTM Load record.
- Dispatcher clicks Post Load.
- System:
- retrieves Organization token
- retrieves User token
- posts the load to DAT via Posting API
- If successful:
- DAT returns
idandshipmentId - system saves them to:
FreightTM__Load__c.DAT_Post_Id__cFreightTM__Load__c.DAT_Shipment_Id__c
- system creates a Completed Task with the response summary
- DAT returns
- Dispatcher can later click:
- Update Load (only shown if
DAT_Post_Id__cexists) - Delete Load (only shown if
DAT_Post_Id__cexists)
- Update Load (only shown if
Workflow B (Carriers): Search DAT Loads for Driver/Carrier/Truck → Create FTM Load

- Dispatcher opens an FTM Driver/Carrier/Truck (Employee) record.
- Dispatcher clicks Search Loads.
- System validates Driver/Carrier/Truck profile (city/zip, equipment preference, max deadhead, min RPM, active status)
- System retrieves DAT tokens and calls DAT Posting API (GET loads).
- System filters results:
- Reject if rate per mile too low
- Reject if equipment mismatch
- Reject if deadhead distance too far (Google Distance Matrix)
- Dispatcher selects a load and clicks Create Selected Load in Salesforce.
- System creates an FTM Load record and pre-fills key fields.
Key Features
Posting Management (Load → DAT)
- OAuth-style token flow via DAT Identity APIs:
- Organization token
- User token
- Token caching using Salesforce Platform Cache (Org partition)
- Post load to DAT with structured payload (freight, lane, exposure, poster info)
- Stores DAT_Post_Id__c and DAT_Shipment_Id__c on the Load
- Creates Task logs automatically for audit trail
- UI supports Post / Update / Delete from a Visualforce page
Driver/Carrier/Truck Load Search (Driver/Carrier/Truck → DAT Search → Create Load)
- Search loads from DAT using Driver/Carrier/Truck constraints:
- origin radius (max deadhead)
- origin zip
- equipment type
- pickup date range (today → +7 days)
- Filters:
- Rate-per-mile
- Equipment match
- Distance check using Google API
- Shows both:
- Accepted loads
- Rejected loads + reason
- Creates a Load record in Salesforce from the selected result
2⃣ Developer Information: How It Works in Salesforce
Apex Components
| Component | Purpose |
PostLoadDat2 | Posts an existing FTM Load to DAT (and saves DAT IDs back to the load) |
PostLoadDat2Controller | Visualforce controller that executes Post/Update/Delete and renders result + writes Task logs |
UpdateLoadDat2 | Updates an existing DAT posting (called by controller) |
DeleteLoadDat2 | Deletes an existing DAT posting (called by controller) |
PostDriver/Carrier/TruckLoadDat | Searches DAT loads for a Driver/Carrier/Truck, filters results, and creates a new FTM Load from selection |
| Visualforce: Post/Update/Delete page | UI for posting management from the Load record |
| Visualforce: Driver/Carrier/Truck Load Management page | UI for searching and creating loads from a Driver/Carrier/Truck record |
3⃣ Authentication & Token Handling (Important)
Identity Endpoints (Staging shown in code)
- Organization token:
https://identity.api.staging.dat.com/access/v1/token/organization - User token:
https://identity.api.staging.dat.com/access/v1/token/user
Required Header
All DAT requests include:
- x-dat-partner-id: 001f400001M2BglAAF
Credentials Storage
Organization credentials come from a Hierarchy Custom Setting:
- DAT_Org_Credential__c.DAT_Login_Id__c
- DAT_Org_Credential__c.DAT_Login_Password__c
(User credentials are currently hardcoded in the provided code as asuccini_test / asuccini_test, but the code shows where user-based credentials could be pulled from the User record.)
Platform Cache Strategy
Tokens are cached using an Org Partition:
- Partition: local.DATCacheToken
- Keys:
- Org token key: DATORGTokenV1
- User token key: DATUSERTOKENV1<USER_ID>
- TTL: 28 minutes
This prevents unnecessary token calls and improves performance.
4⃣ Posting a Load to DAT (PostLoadDat2)
DAT Posting Endpoint
- POST: https://freight.api.staging.dat.com/posting/v2/loads
Payload Structure
The integration builds a JSON body with:
freight
- equipmentType (mapped from FreightTM__Required_Trailer__c)
- comments (from FreightTM__Remarks__c)
- lengthFeet (uses FreightTM__Total_Cargo_Volume__c, defaults to 1 if null/0)
- weightPounds (from FreightTM__Weight__c)
- fullPartial (mapped from Service__c):
- STL → PARTIAL
- FTL or Expedited → FULL
lane
- origin: city/state/zip
- destination: city/state/zip
exposure
- audience: loadBoard = true
- method: Public
- availability window dates:
- earliestAvailabilityWhen
- latestAvailabilityWhen (uses EOD rule)
- endWhen
- startWhen = now
Availability window logic used in code
- Earliest defaults to pickup datetime, else now.
- Latest defaults to delivery EOD if present, else pickup EOD, else today EOD.
- If delivery < pickup → normalize latest to pickup EOD.
- Clamp latest to within ~6 months.
posterInfo
- contactMethods includes PRIMARY_PHONE and EMAIL (values are expected to be set by DAT or filled depending on implementation, controller parses response fields).
Tracking
- isTrackingRequired = true
Saving DAT IDs Back to the Load
If DAT returns:
- id
- shipmentId
The integration updates:
- FreightTM__Load__c.DAT_Post_Id__c
- FreightTM__Load__c.DAT_Shipment_Id__c
5⃣ Visualforce UI: Post / Update / Delete Load
Visualforce Page (Load context)
- Buttons:
- Post Load (always)
- Update Load (only when datPostId exists)
- Delete Load (only when datPostId exists, includes confirm dialog)
Controller Behavior (PostLoadDat2Controller)
- executePostLoad():
- calls PostLoadDat2.execute()
- parses DAT response
- renders a human-readable HTML summary
- creates a Completed Task containing a plain-text summary
- executeUpdateLoad():
- requires DAT_Post_Id__c
- calls UpdateLoadDat2.execute(pageId, datPostId)
- uses shared parser to render + log Task
- executeDeleteLoad():
- requires DAT_Post_Id__c
- calls DeleteLoadDat2.execute(pageId, datPostId)
- renders status and clears datPostId so Update/Delete buttons disappear after successful delete


6⃣ Driver/Carrier/Truck Load Search & Create Load (PostDriver/Carrier/TruckLoadDat)
DAT Search Endpoint Used
GET request is sent to:
- https://freight.api.staging.dat.com/posting/v2/loads?…
Parameters built from the Driver/Carrier/Truck:
- originRadius = Driver/Carrier/Truck.Max_Deadhead_mile__c
- originZip = Driver/Carrier/Truck.FreightTM__Zip_Code__c
- equipmentType = mapEquipmentToDat(Driver/Carrier/Truck.Equipment_Preference__c)
- pickupStartDate = today
- pickupEndDate = today + 7
Driver/Carrier/Truck Validation (before searching)
Search is blocked unless these are present/valid:
- City OR Zip
- Preferred Equipment
- Max Deadhead Miles
- Min Rate Per Mile
- Driver/Carrier/Truck must be Active
Filtering Logic
Loads are evaluated and either:
- added to datLoads (accepted)
- or added to rejectedLoads with a reason
Rate-per-mile filter
If rate and miles exist:
- rpm = rate / miles
- reject if rpm < Driver/Carrier/Truck.Min_Rate_Per_Mile__c
Equipment filter
Reject if load equipment doesn’t match Driver/Carrier/Truck preference.
Distance filter (Google Distance Matrix)
If Driver/Carrier/Truck + origin have enough location fields:
- calls Google Distance Matrix API
- calculates distance in miles
- reject if distance > Driver/Carrier/Truck.Max_Deadhead_mile__c
Rejected loads display:
- load id
- reason
- full detail string built by buildLoadDisplayText()
Creating an FTM Load from a Selected DAT Load
createLoadInSalesforce() creates FreightTM__Load__c:
- Assigns driver:
- FreightTM__Driver__c = Driver/Carrier/Truck.Id (note: field semantics should match your org’s model, this is what code does)
- DAT IDs:
- DAT_Post_Id__c = selectedLoad.id
- DAT_Shipment_Id__c = selectedLoad.shipmentId
- Status:
- FreightTM__Status__c = ‘Assigned’
- Maps lane origin/destination:
- pickup city/state/zip
- delivery city/state/zip
- Maps pickup start date into FreightTM__Pickup_Date__c
- Maps freight:
- weight
- trailer/equipment name into FreightTM__Required_Trailer__c
7⃣ Field Mapping
A) Post Load (FTM → DAT)
| FTM Field | DAT Field | Notes |
FreightTM__Pickup_City__c | lane.origin.city | Required |
FreightTM__Pickup_State__c | lane.origin.stateProv | Required |
FreightTM__Pickup_Zip_Code__c | lane.origin.postalCode | Required |
FreightTM__Delivery_City__c | lane.destination.city | Required |
FreightTM__Delivery_State__c | lane.destination.stateProv | Required |
FreightTM__Delivery_Zip_Code__c | lane.destination.postalCode | Required |
FreightTM__Required_Trailer__c | freight.equipmentType | Mapped to DAT equipment codes (V, R, F, PO, etc.) |
Service__c | freight.fullPartial | STL→PARTIAL, FTL/Expedited→FULL |
FreightTM__Remarks__c | freight.comments[].comment | Optional |
FreightTM__Weight__c | freight.weightPounds | Optional but recommended |
FreightTM__Pickup_Date__c / FreightTM__Delivery_Date__c | exposure.*When | Availability logic + EOD rule + 6-month clamp |
| (system) | DAT_Post_Id__c | Saved from DAT response id |
| (system) | DAT_Shipment_Id__c | Saved from DAT response shipmentId |
B) Driver/Carrier/Truck Search / Create Load (DAT → FTM)
| DAT Field | FTM Field | Notes |
id | DAT_Post_Id__c | Stored on new load |
shipmentId | DAT_Shipment_Id__c | Stored on new load |
lane.origin.city/stateProv/postalCode | Pickup City/State/Zip | |
lane.destination.city/stateProv/postalCode | Delivery City/State/Zip | |
lane.pickupDates.start | FreightTM__Pickup_Date__c | Code uses Date.valueOf |
freight.weightPounds | FreightTM__Weight__c | |
freight.equipmentName | FreightTM__Required_Trailer__c |


8⃣ Error Handling
Token failures
- If org token fails → “Organization token error”
- If user token fails → “User token error”
- Debug logs include request/response details.
Post failures
- If response is null → user-facing message:
- “Failed to post load. Please check all the required fields.”
Update/Delete failures
- Blocks action if DAT_Post_Id__c is missing
- Shows friendly ApexPages error messages
- Delete treats 200/202/204/404 as “deleted” success (including already-missing posts)
Driver/Carrier/Truck search rejections
- Each rejected load gets a reason:
- RPM too low
- Equipment mismatch
- Distance too far
- Distance API exception / origin incomplete
9⃣ Testing & Deployment
A) Token Tests
- Ensure Custom Setting exists:
- DAT_Org_Credential__c
- Verify Platform Cache partition exists:
- local.DATCacheToken
B) Post Load Tests
- Open a test Load record and confirm required lane fields are populated.
- Use Visualforce page:
- Click Post Load
- Confirm:
- DAT_Post_Id__c and DAT_Shipment_Id__c saved
- Task created with subject “DAT Load Posted: <id>”
C) Update/Delete Tests
- After posting:
- Update fields on the Load
- Click Update Load
- Click Delete Load
- Confirm:
- Result panel shows expected output
- Update/Delete buttons disappear after successful delete
D) Driver/Carrier/Truck Search Tests
- Ensure Driver/Carrier/Truck has:
- Active = true
- City/Zip
- Equipment preference
- Max deadhead
- Min RPM
- Click Search Loads
- Verify:
- accepted loads display
- rejected loads show reasons
- Select a load and click Create Selected Load in Salesforce
- Confirm Load created and mapped fields populated
FAQs
Q: Do we still use Named Credentials?
Not in the provided code. Calls use direct endpoints + headers, and org credentials come from DAT_Org_Credential__c. (You can refactor to Named Credentials later for security/maintainability.)
Q: Are tokens cached?
Yes. Org and user tokens are cached in Platform Cache for 28 minutes.
Q: Can users post, update, and delete loads?
Yes. The Load Visualforce UI supports all three actions.
Q: Does Driver/Carrier/Truck search use distance validation?
Yes. Google Distance Matrix is used to enforce max deadhead miles.
Q: Does the integration sync DAT status back to FTM automatically?
Not in these classes. This implementation focuses on posting management, searching, and load creation.
Support
For setup help or troubleshooting, email: [email protected]
