Webhooks
Receive Chain events in your webhook endpoint
Listen to events in your Chain account on your webhook endpoint so your integration can automatically trigger reactions.
Chain's entire platform is event-based and generates many events on various workflows. Users configure webhooks from the dashboard which provides a user interface for registering and testing your webhook endpoints.
Transmission Methods
Chain supports multiple ways to receive events:
HTTP/HTTPS Webhooks
- Send events directly to your endpoint via HTTP POST
- Supports JSON, XML, or custom formats
- Configurable headers and authentication
- Can specify HTTP method (GET, POST, PUT)
- Supports query parameters or request body
- Configurable timeout settings
SFTP/FTP
- Receive events as files on your SFTP/FTP server
- Supports various file formats (CSV, JSON, XML, EDI, TXT)
- Configurable file naming templates
- Supports file encryption
- Can handle file attachments
Salesforce Integration
- Direct integration with Salesforce
- Supports CREATE and UPDATE operations
- Configurable object mapping
Custom App Integration
- Direct integration with custom applications
- Supports specific app actions like createShipment
Configuration Options
Data Format
- JSON
- XML
- CSV
- EDI
- TXT
- File (for attachments)
- QueryParams
Conditions
- Configure when events should be sent
- Supports AND/OR conditions
- Can filter based on event data
Throttling
- Control event frequency
- Set minimum interval between events
- Prevents overwhelming your systems
Enterprise Settings - only relevant for Chain Enterprise customers who have split PODs or offices into different workspaces
- Enable for entire enterprise or specific workspace
- Configure enterprise-wide defaults
- Manage workspace-specific settings
Setup a webhook endpoint
Prerequisites:
- Chain Enterprise
- Chain Admin or Owner role
NOTE: The below is coming soon. In the meantime, please ask your Chain representative to help you setup a webhook endpoint.
- Go to the Chain dashboard
- Click your Avatar at the top-right and select Settings
- Click integrations
- Select the event you want to listen to
- Enter the webhook endpoint details or select SFTP if you want to receive a file instead
Once you create an integration, it will automatically be opt-ed in for Developer Logs which you can view under Settings > Logs. If you want to disable these logs, simple click the "Stop publishing to logs" toggle next to the integration.
We recommend to turn off logs for high-volume events like shipmentLocationReceived.
Consumable Events
This list is always changing and we are always adding new events. If you don't see one on here, simply ask your Chain representative and we'll support the new event in a matter of days.
NOTE: With any of the events, if you have a third-party or custom TMS integrated, you can add the unique shipment id (and/or stop id for the stop events) to the payload to ensure you are only consuming the events you need.
- shipmentCreated: this event can pass back two properties that may be relevant to you:
- chainChatEmbedURL: a URL to the chat widget for the shipment. This is a great way to provide a chat interface for your users to interact with drivers and dispatchers.
- chainMapEmbedURL: a URL to the map widget for the shipment. This is a great way to provide a map interface for your users to view the shipment's tracking history. The map will also have additional functionality like App Download Status and exposes a button to resend tracking requests to drivers.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"chainChatEmbedURL": "https://chaineapp.com/chat/embed/550e8400-e29b-41d4-a716-446655440000",
"chainMapEmbedURL": "https://chaineapp.com/map/embed/550e8400-e29b-41d4-a716-446655440000"
}
- driverAppDownloadSMSStatusReceived - this event will have the status of sending an app download message to the driver. This will also include information about the driver's cell phone number such as the cell carrier (i.e. AT&T, Verizon, etc.), the phone type ('mobile', 'landline', 'voip') and the status of the message (i.e. sent, failed, etc.). Note, for non-mobile numbers, you will get a failed status as we do not allow non-mobile numbers to be used in our app for security reasons.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"driver": {
"name": "John Doe",
"phoneNumber": "+1234567890"
},
"overallStatusMessage": "Message sent successfully",
"smsStatus": {
"isValidMobileNumber": true,
"lookupSuccessful": true,
"phoneLookupMessage": "Valid mobile number",
"sendSMSMessage": "Message queued",
"sendSMSSuccessful": true
}
}
- mobileAppLocationSettingsChanged - Triggered when mobile app location settings are changed. This will include if the driver has location sharing enabled or disabled.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"gpsGeolocationProviderAvailable": true,
"hasCorrectPermissions": true,
"locationServicesEnabled": true,
"networkGeolocationProviderAvailable": true,
"userID": "550e8400-e29b-41d4-a716-446655440001",
"userPhone": "+1234567890"
}
- shipmentLocationReceived - this will be sent when a location is received from tracking devices. This will include the latitude, longitude, timestamp, and reverse geocoded address (city, state, zip, country).
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"address": {
"city": "New York",
"stateCode": "NY",
"zipCode": "10001",
"country": "USA"
},
"dateTime": {
"date": "2024-03-13",
"time": "15:00",
"isoDateTime": "2024-03-13T15:00:00.000Z",
"timezone": "America/New_York",
"timezoneOffset": "-04:00"
},
"sourceDisplayName": "Mobile App",
"sourceID": "device123",
"sourceType": "MobileApp"
}
- stopArrived - will have the arrival date and time.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"chaineCustomerStopID": "STOP123",
"arrivalDateTime": {
"date": "2024-03-13",
"time": "15:00",
"isoDateTime": "2024-03-13T15:00:00.000Z",
"timezone": "America/New_York",
"timezoneOffset": "-04:00"
},
"isDestination": false,
"isOrigin": true,
"stopID": "550e8400-e29b-41d4-a716-446655440002",
"stopSequence": 1,
"stopType": "Pick",
"source": "DriverApp"
}
- stopDeparted - will have the departure date and time.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"chaineCustomerStopID": "STOP123",
"departureDateTime": {
"date": "2024-03-13",
"time": "16:00",
"isoDateTime": "2024-03-13T16:00:00.000Z",
"timezone": "America/New_York",
"timezoneOffset": "-04:00"
},
"isDestination": false,
"isOrigin": true,
"stopID": "550e8400-e29b-41d4-a716-446655440002",
"stopSequence": 1,
"stopType": "Pick",
"source": "DriverApp"
}
- shipmentFileReceived - triggered whenever a file or document is received from a driver or dispatcher. This can include pictures of breakdowns, lumper receipts, PODs, etc.
{
"chaineCustomerShipmentID": "CUST123",
"id": "550e8400-e29b-41d4-a716-446655440003",
"fileURL": "https://chaineapp.com/files/550e8400-e29b-41d4-a716-446655440003"
}
- postOfferMade - for customer's using our booking product, you can consume any carrier offer that is made for an available shipment. This can include the carrier details (name, mcNumber, dotNumber), your unique shipment id, and offer details (amount)
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"amount": {
"amount": 1000.00,
"currency": "USD"
},
"dotNumber": "1234567",
"mcNumber": "MC123456",
"message": "Available for immediate pickup",
"offeredBy": "550e8400-e29b-41d4-a716-446655440004",
"offeredByUserEmail": "carrier@example.com",
"offeredByUserName": "Carrier Name",
"offeredByUserPhone": "+1234567890",
"offerStatus": "Pending"
}
- postOfferAccepted - for customer's using our booking product, when an offer is accepted, you can consume data related to the carrier making the offer, the carrier sales rep that accepted the offer, and the shipment details. This should kick off a workflow in your TMS to assign the carrier, rate and carrier sales rep to the shipment.
{
"chaineShipmentID": "550e8400-e29b-41d4-a716-446655440000",
"chaineCustomerShipmentID": "CUST123",
"amount": {
"amount": 1000.00,
"currency": "USD"
},
"dotNumber": "1234567",
"mcNumber": "MC123456",
"offerStatus": "Accepted",
"offerStatusChangedBy": "550e8400-e29b-41d4-a716-446655440005",
"offeredBy": "550e8400-e29b-41d4-a716-446655440004",
"offeredByUserEmail": "carrier@example.com",
"offeredByWorkspaceID": "550e8400-e29b-41d4-a716-446655440006"
}
- shipmentChatMessageReceived - any of the chat messages that come from a shipment can be consumed using this event. This can be used if you are designing your own chat interface. We highly recommend to use the chainChatEmbedURL for your chat interface as our chat widget is built to be a great experience and has many built-in features like reactions, GIFs, emojis, document previews and more. And we are constantly adding new features.
{
"channelID": "550e8400-e29b-41d4-a716-446655440007",
"channelType": "Shipment",
"copilotMetadata": {
"ruleDescription": "Notify when shipment is delayed",
"ruleName": "DelayNotification"
},
"id": "550e8400-e29b-41d4-a716-446655440008",
"isUserInChannelOwnerWorkspace": true,
"members": [
{
"channelRole": "Dispatcher",
"email": "dispatcher@example.com",
"isUserInChannelOwnerWorkspace": true,
"name": "John Smith",
"phone": "+1234567890",
"userID": "550e8400-e29b-41d4-a716-446655440009",
"userRoleInShipmentChannel": "Dispatcher",
"workspaceID": "550e8400-e29b-41d4-a716-446655440010"
},
{
"channelRole": "Driver",
"email": "driver@example.com",
"isUserInChannelOwnerWorkspace": false,
"name": "Mike Johnson",
"phone": "+1987654321",
"userID": "550e8400-e29b-41d4-a716-446655440011",
"userRoleInShipmentChannel": "Driver",
"workspaceID": "550e8400-e29b-41d4-a716-446655440012"
}
],
"mentionedUsers": [
{
"email": "dispatcher@example.com",
"name": "John Smith",
"phone": "+1234567890",
"userID": "550e8400-e29b-41d4-a716-446655440009",
"workspaceID": "550e8400-e29b-41d4-a716-446655440010"
}
],
"message": {
"actionType": null,
"attachments": [
{
"assetURL": "https://chaineapp.com/files/550e8400-e29b-41d4-a716-446655440013",
"fileSize": 1024,
"filename": "delivery_proof.jpg",
"mimeType": "image/jpeg",
"thumbURL": "https://chaineapp.com/files/550e8400-e29b-41d4-a716-446655440013/thumb",
"type": "image"
}
],
"createdAt": "2024-03-13T15:00:00.000Z",
"html": "<p>Delivery proof attached</p>",
"text": "Delivery proof attached",
"type": "default",
"updatedAt": "2024-03-13T15:00:00.000Z"
},
"messageGeneratedBy": "Human",
"sentByUser": {
"email": "driver@example.com",
"name": "Mike Johnson",
"phone": "+1987654321",
"userID": "550e8400-e29b-41d4-a716-446655440011",
"workspaceID": "550e8400-e29b-41d4-a716-446655440012"
},
"shipmentMetadata": {
"chaineChannelType": "Shipment",
"destinationCity": "Los Angeles",
"destinationState": "CA",
"originCity": "New York",
"originState": "NY",
"shipmentID": "550e8400-e29b-41d4-a716-446655440000",
"shipmentNumber": "SH123456",
"shipmentOwnerEnterpriseWorkspaceID": "550e8400-e29b-41d4-a716-446655440014",
"shipmentOwnerWorkspaceID": "550e8400-e29b-41d4-a716-446655440010",
"shipmentStatus": "InTransit",
"shipmentStatusTime": "2024-03-13T15:00:00.000Z",
"updatedBy": {
"userID": "550e8400-e29b-41d4-a716-446655440011",
"userName": "Mike Johnson"
}
},
"source": "DriverApp",
"userRoleInShipmentChannel": "Driver"
}
This sample demonstrates a chat message received in a shipment channel, including:
- Message details with attachments
- Channel and member information
- User roles and workspace context
- Shipment metadata
- Message source and generation details
The message in this example is a delivery proof sent by a driver, with an attached image. The message includes both plain text and HTML versions, and it's sent through the Driver App.
Event Types and Enums
StopTypeEnum
- Pick
- Drop
StopSourceEnum
- AIGenerated
- ChaineWebApp
- DriverApp
- Geofence
ShipmentTrackingSourceEnum
- API
- CSVFile
- Convoy
- EDIFile
- ELD
- ExternalTrackingLink
- ThirdPartyCarrierTrackingAPI
- MobileApp
- TiveDevice
- TrailerNumber
- TruckNumber
TOfferStatus
- Accepted
- Bookmarked
- Declined
- Expired
- Pending
ChatMessageEventSourceEnum
- AIGenerated
- ChaineWebApp
- Copilot
- DriverApp
- SMS
- TMS
- Unknown
ChatMessageGeneratedByEnum
- Copilot
- GenAI
- Human
ChaineChannelTypeEnum
- Default
- Driver
- Offer
- Shipment
AttachmentTypeEnum
- Audio
- File
- Image
- Text
- Video
SendChatMessageMessageTypeEnum
- Default
- Event
- Template
SendChatMessageEventEnum
- AppDownloadMessageCancelled
- AppDownloadMessageCompleted
- AppDownloadMessageScheduled
- DemoEvent
- MemberAdded
- MemberRemoved
- PostOfferCreated
- ShipmentCreated
- ShipmentExceptionDetected
- ShipmentRuleScheduled
- ShipmentUpdated
- StopArrived
- StopDeparted
- StopETAUpdated
Best Practices
Error Handling
- Implement proper error handling for failed webhook deliveries
- Set up monitoring for webhook failures
- Implement retry logic for failed deliveries
Security
- Use HTTPS for all webhook endpoints
- Implement authentication for webhook endpoints
- Validate webhook signatures
- Use IP whitelisting when possible
Performance
- Process webhooks asynchronously
- Implement proper queuing for high-volume events
- Use throttling to prevent overwhelming your systems
Testing
- Test webhook endpoints thoroughly
- Use the Chain dashboard to test webhook configurations
- Monitor webhook delivery logs
- Set up alerts for webhook failures