Inbound Messaging

Prev Next

Architecture

When a user submits a message or form, the system will transmit these messages from the user directly to your Messaging web service.

To eliminate delays caused by periodic polling, our system delivers inbound messages via a webhook-style architecture. The system calls your Messaging web service, appending the unique message handle to your configured URL. Both free-form messages and form messages are delivered to this same endpoint, though their payload structures differ slightly.

Delivery Order

The sequence in which your web service receives messages depends on their context within the app. Messages tied to a specific workflow are strictly queued and delivered in a First-In, First-Out (FIFO) order. If a workflow message fails and requires delivery retries, all subsequent workflow messages are held in the queue until the first one succeeds.

Conversely, messages not associated with a workflow, such as standalone free-form chats, are processed independently. These non-workflow messages are not queued or delivered in any particular order.

Delivery Formats

You can choose whether to receive message data encoded as a form or as JSON within App Manager.

NOTE: If you are transitioning from one format to another and wish to avoid downtime, use the value of the Content-Type header in the request to dynamically adjust how your system extracts the data.

Delivery Guarantees & Retries

Your web service must return an HTTP 200 to indicate a message has been successfully processed. If any other HTTP response code is returned, or if a network or DNS error occurs, our system will retry the request.

By default, the system retries up to 10 times utilizing exponential backoff with 50% jitter (e.g., waiting 0-10 seconds, then 0-20 seconds, then 0-40 seconds, and so on).

Handling Duplicates

Because of the retry logic and the nature of network connections, you may occasionally receive a call to your endpoint more than once for the same message.

IMPORTANT: Your system should stores the message handle (extracted from the URL) so that subsequent requests do not create duplicate messages in your backend.

Payload Structure and Key Behaviors

When your endpoint receives a request, the payload will contain the following:

  • Routing information: direction, username

  • Timestamps:composed_at, read_at, deleted_at

  • Core content: body for standard text, or form_data for structured forms

Depending on how the user initiates the communication, inbound messages may also contain additional context flags that dictate how your backend should handle the data:

  • workflow_action: When true, your web service must apply load data changes before responding with HTTP 200, as the app will automatically refresh load information upon completion.

  • in_reply_to_handle: Indicates the handle of the parent message a user replied to for maintaining conversation threads.

  • telematics: If enabled, attaches tractor, trailer, odometer, and location data corresponding to the time the message was composed.

  • server_validation_request: Indicates the payload is strictly for input validation and should not be permanently saved yet.

Payload Examples

Receiving Free-Form Messages

Users can send free-form messages using a standard chat-like interface. Your system will receive standard text data.

{
    "direction": "inbound",
    "username": "JDOE",
    "composed_at": "2026-01-16T16:34:12+00:00",
    "read_at": "2026-01-16T16:34:24+00:00",
    "message_type": "text",
    "body": "Hello World!"
}

Receiving Form Messages

Users generally send form messages by performing an action from a load, a stop, or a button in an activity screen. Launching a form directly from these contexts allows the application to pre-populate associated data fields (such as order numbers) using existing session data.

Rather than a textual body, your web service receives a map of form field codes and their corresponding values.

{
    "direction": "inbound",
    "username": "JDOE",
    "composed_at": "2026-01-16T16:49:56+00:00",
    "read_at": "2026-01-16T16:49:55+00:00",
    "message_type": "form",
    "form_code": "ARRIVED",
    "form_data": {
        "LOAD-NUMBER": "89458122",
        "STOP-NUMBER": "2",
        "PICK-UP-NUMBER": "100-674441"
    }
}

IMPORTANT: Form fields are not delivered in any particular order. Make sure your integration logic does not depend on the sequence of the parameters in the request body.

Read and Delete Events

In addition to new inbound messages, your webhook endpoint will also receive status updates for existing messages. This applies to both inbound and outbound communications.

When a user reads a message, the system sends a payload containing a read_at timestamp. You can use this request as a signal to mark the message as read within your backend systems.

{
    "direction": "inbound",
    "username": "JDOE",
    "composed_at": "2026-01-16T16:34:12+00:00",
    "read_at": "2026-01-16T16:34:24+00:00",
    "message_type": "text",
    "body": "Hello World!"
}

Similarly, if a user deletes a message, the payload will include a deleted_at timestamp. If your integration does not require tracking these read or delete events, you can simply acknowledge the notification and take no action by returning an empty HTTP 200 response.

Resources

API

App Manager