Workflow External Action

Fires an outbound HTTPS POST to any URL from an in-app workflow, with the current shipment's full data plus a configurable auth model. Used to hand shipments off to external systems (AI agents, third-party dispatchers, customer-side automations, etc.) without a custom integration.

Overview

Workflow External Action is a one-way outbound trigger from Tai to your
system.
Tai does not read or accept a response body as part of the
workflow — the payload is essentially a rich webhook that hands your
system a fully-hydrated shipment and any context parameters you've
configured. It's meant to start work on your side, not to exchange
data in a single call.

The end-to-end flow:

  1. A dispatcher (or an automation) triggers the workflow against one or
    more shipments in TMS.
  2. Tai POSTs a JSON payload — full shipment details plus any configured
    auth/context parameters — to the URL configured on the Integration Source.
  3. Tai logs the request and (optionally) the response against the shipment
    and always drops an AI Agent Call alert on it.
  4. Your system reacts to the payload — spin up an AI agent, dispatch to
    a driver, create a ticket in your own platform, etc.
  5. When your system needs to update Tai (append a note, change a
    status, upload a document, submit a quote, etc.), it calls Tai's
    Public API.

Prerequisites

  • LSP-level access to configure Integration Sources.
  • Your endpoint publicly reachable over HTTPS.
  • Contact your Tai account team to enable the Workflow External Action
    Integration Source type.
  • A BrokerTMS Public API key if you plan to push updates back to Tai
    from your system (see the [Public API Documentation]).

Create the Integration Source

In BrokerTMS, go to LSP → Integration Sources → Add New Integration Source and choose type
Workflow External Action. The SourceName you enter shows up on the
shipment activity log as AI Agent Call executed via <SourceName>. and on
the shipment alert as AI Agent Call via <SourceName>.

Configuration Parameters

Every knob is either a field on the Integration Source itself or a row on
its IntegrationSourceParameters table. Parameter names are matched
case-insensitively.

Required

ParameterPurpose
urlDestination URL for the outbound POST. Must be present and non-empty — omitting it causes Tai to return 400 Integration source does not have a url parameter.

Reserved (behavior-controlling, not sent to your endpoint)

ParameterValueEffect
EnableLoggingtrue / falseWhen true: Tai awaits the response body, stores it in the ApiActivityLog, and writes a private ShipmentActivityLog on the shipment. When false (or omitted): the request is fired without awaiting a response body. ApiActivityLog is written either way.
DefaultStaffIdinteger StaffIdFallback carrier rep — used if the shipment has no CarrierRep.

Custom Headers

Any parameter whose name starts with Header_ is sent as an HTTP header on
the outbound call. The prefix is stripped to form the header name.

Parameter NameHeader Sent
Header_AuthorizationAuthorization: <value>
Header_x-api-keyx-api-key: <value>
Header_X-Vendor-AccountX-Vendor-Account: <value>

Multiple Header_* parameters are supported and all are sent on every call.
Values are added with TryAddWithoutValidation, so any header format is
accepted (no strict RFC 7230 checks). This is the recommended path for
Bearer tokens, API keys, or any other auth scheme your endpoint requires.

Custom Body Parameters

Any Integration Source parameter that is not url, EnableLogging,
DefaultStaffId, or a Header_* entry is added as a top-level key inside
the integrationSourceParameters object on the outbound payload, keeping
the exact parameter name as the JSON key.

Use these to pass anything your endpoint needs to identify the connection
(vendor account ID, workflow ID, environment tag, etc.).

Integration Source Field Handling

Two fields on the Integration Source itself are automatically injected into
integrationSourceParameters on every call — only when non-empty:

Field on IntegrationSourceInjected asCondition
LicenseKeyintegrationSourceParameters.licenseKeyOnly if non-empty.
AccountNumberintegrationSourceParameters.accountNumberOnly if non-empty.

UserName and Password fields on the Integration Source are NOT sent
by this integration.
If you need to send credentials to your endpoint,
either:

  • Add them as custom parameters (e.g. an IntegrationSourceParameter named
    UserName will surface as integrationSourceParameters.UserName), or
  • Send them as HTTP headers via the Header_* convention (recommended for
    Bearer tokens and API keys).

The Outbound Request

  • Method: POST
  • URL: the url parameter value, unchanged
  • Content-Type: application/json; charset=utf-8
  • Headers: any Header_* parameter values, plus Content-Type
  • Body: JSON object with two top-level keys — shipment and
    integrationSourceParameters. See the full example below.

Triggers

The Workflow External Action can be fired from three places in the TMS UI:

  • Check Call — On an individual shipment's Check Call screen, any
    configured Workflow External Action integration source appears as a
    callable action. Runs synchronously for that single shipment.
  • Shipment Search / Company Loadboard — Bulk Operations — Select multiple shipments on
    the Shipment Search page and choose the Workflow External Action from
    the bulk operations menu. Runs in the background as a Hangfire job.
  • Workflow Automations — Configure a workflow rule to fire the
    action automatically when its trigger conditions are met (status
    change, alert added, etc.).

Response Handling

  • Any HTTP status from your endpoint is tolerated. Non-2xx responses do
    not halt the workflow. Network errors and exceptions are swallowed —
    Tai still writes the activity log and the shipment alert.
  • Response bodies are only captured when EnableLogging is true.
  • Regardless of outcome, every call:
    • Adds an AI Agent Call shipment alert.
  • When EnableLogging = true, additionally: a private ShipmentActivityLog
    entry visible in the shipment's activity feed.

Sending Updates Back to Tai

The Workflow External Action is one-way. There is no reserved "return"
endpoint or expected response format — Tai does not read the response body
into the shipment record, and any state change on Tai's side after the
webhook fires must come from a Public API call your system makes.

That's the intended design: your system uses the payload as its trigger and
then uses Tai's Public API for any updates it needs to push back —
comments, status changes, attachments, quotes, tracking updates, and so on.
See the [Public API Documentation] for the full endpoint catalog. Common
patterns include:

  • Posting shipment activity notes / comments
  • Updating shipment status
  • Uploading attachments (documents, BOLs, PODs)
  • Submitting a truckload quote (POST /PublicApi/Shipping/v2/TruckloadQuote)
  • Updating tracking, appointments, or stop actuals

Your system uses its own Public API key for these calls — the credentials
configured on the Workflow External Action Integration Source are for
authenticating inbound to your system, not for calling back to Tai.

Carrier Rep Resolution

shipment.carrierRep in the outbound payload is resolved in this order:

  1. Whatever CarrierRep is already set on the shipment.
  2. Otherwise, if DefaultStaffId is configured on the Integration Source,
    the Staff record with that ID — but only if that Staff belongs to the
    same accounting organization as the Integration Source owner.
  3. Otherwise (or if the Staff is in a different accounting org), the
    DefaultStaff configured on the Integration Source's owner
    organization.

This guarantees the outbound payload always carries a CarrierRep, even for
shipments that don't have one assigned yet.

Example

For an integration that hits https://agent.example.com/v1/dispatch with a
Bearer token and a vendor workflow tag:

WhereField / ParameterValue
IntegrationSourceSourceNameAcme Dispatcher Agent
IntegrationSourceLicenseKeyLK-9F2A
IntegrationSourceAccountNumberACME-001
IntegrationSourceParametersurlhttps://agent.example.com/v1/dispatch
IntegrationSourceParametersEnableLoggingtrue
IntegrationSourceParametersHeader_AuthorizationBearer eyJhbGciOi…
IntegrationSourceParametersWorkflowIddispatch-standard
IntegrationSourceParametersEnvironmentproduction

Outbound request headers:

Authorization: Bearer eyJhbGciOi…
Content-Type: application/json; charset=utf-8

Outbound request body:

{
  "shipment": {
    "latitude": 42.61458,
    "longitude": -89.62367,
    "locationString": "06/30 08:04 ET : North 29th Avenue, Monroe, WI, 53566",
    "lastLocationUpdate": "2026-06-30T12:04:00Z",
    "mileage": 4093.64,
    "customer": {
      "name": "Acme Manufacturing",
      "referenceNumber": null,
      "staffID": 896203,
      "staffName": "Shipping",
      "staffReferenceNumber": null,
      "salesRepNames": "Sales Rep",
      "billToOrganizationId": 217393,
      "officeOrganizationId": 798833,
      "officeName": "Field Sales"
    },
    "carrierRep": {
      "staffId": 1040914,
      "contactName": "Acme Automation",
      "email": null,
      "phone": null
    },
    "payerOrganization": {
      "organizationId": 217393,
      "name": "Acme Manufacturing",
      "address": {
        "streetAddress": "8950 Seward Road",
        "streetAddressTwo": null,
        "city": "Fairfield",
        "state": "OH",
        "zipCode": "45014",
        "country": "USA",
        "contactName": null
      }
    },
    "totalBuy": 1500.00,
    "totalSell": 1600.00,
    "status": "Delivered",
    "carrierList": [
      {
        "carrierMasterId": 516202,
        "transitLegId": 29837094,
        "shipmentStopIds": [54235677, 54659984, 54235678],
        "name": "Sample Carrier Corp",
        "scac": "",
        "dotNumber": "3305176",
        "mcNumber": "1048914",
        "trackingURL": "",
        "city": "Murfreesboro",
        "state": "TN",
        "zipCode": "37129",
        "phoneNumber": "+15551234567",
        "tariffName": null,
        "transitType": "Linehaul",
        "status": "Delivered",
        "buy": 1500.00,
        "sell": 1600.00,
        "parentShipmentId": null,
        "childShipmentIds": []
      }
    ],
    "attachments": [
      {
        "attachmentName": "CarrierConfirmationTruckload_130037578_signed.pdf",
        "attachmentUrl": "https://<tenant>.taicloud.net/Files/SecureDownload?token=<token>",
        "attachmentType": "Carrier Confirmation",
        "documentId": 63309845
      },
      {
        "attachmentName": "RateQuoteSheet_130037578.pdf",
        "attachmentUrl": "https://<tenant>.taicloud.net/Files/SecureDownload?token=<token>",
        "attachmentType": "Document",
        "documentId": 63309861
      }
    ],
    "shipmentType": "Truckload",
    "stackable": false,
    "trailerType": "53 ft Van | Dry",
    "trailerSize": "Full",
    "weightUnits": "lbs",
    "dimensionUnits": "in",
    "serviceLevel": "Normal",
    "importExport": null,
    "shipmentReferenceNumbers": [
      { "referenceType": "Shipper Reference Number",         "value": "63746" },
      { "referenceType": "Customer PO Number",               "value": "QSTP000019138" },
      { "referenceType": "Trailer Number",                   "value": "012" },
      { "referenceType": "Tracking Reference Number",        "value": "Stop 1 Arrived 06/29 12:38 - Chain (Geofence)" },
      { "referenceType": "Driver Cell Phone Number",         "value": "+15551234567" },
      { "referenceType": "Linehaul Carrier Pro Number",      "value": "63746" },
      { "referenceType": "Driver Name",                      "value": "Sample Driver" },
      { "referenceType": "Truck Number",                     "value": "104" },
      { "referenceType": "Carrier Dispatcher Name",          "value": "Alex" },
      { "referenceType": "Carrier Dispatcher Phone Number",  "value": "+15551234567" },
      { "referenceType": "Carrier Rep",                      "value": "Sample Rep" },
      { "referenceType": "Customer Confirmation",            "value": "False" },
      { "referenceType": "Carrier Confirmation",             "value": "False" },
      { "referenceType": "Carrier Dispatcher Email",         "value": "[email protected]" },
      { "referenceType": "Offer Rate",                       "value": "1450" },
      { "referenceType": "Min Buy Rate",                     "value": "1350" },
      { "referenceType": "Max Buy Rate",                     "value": "1550" },
      { "referenceType": "External Carrier Confirmation Id", "value": "10107785|20242312" },
      { "referenceType": "Shipment Id",                      "value": "130037578" },
      { "referenceType": "Linehaul Carrier Pro Number Clean","value": "63746" },
      { "referenceType": "Built by",                         "value": "Sample User" },
      { "referenceType": "Tracking Check Call Notes",        "value": "Empty in Walton, KY" },
      { "referenceType": "Tracking Miles to Next Stop",      "value": "0.1 miles to Stop 2 : 06/30 08:04 ET" },
      { "referenceType": "Est ETA",                          "value": "06/30 08:00 CT" },
      { "referenceType": "VIN",                              "value": "1XKYD00X0XX000000" },
      { "referenceType": "Customer Tracking Link",           "value": "https://example.com/tracking/307e91da" }
    ],
    "stops": [
      {
        "shipmentStopId": 54235677,
        "companyName": "Acme Manufacturing",
        "streetAddress": "8950 Seward Rd.",
        "streetAddressTwo": null,
        "city": "Fairfield",
        "state": "OH",
        "zipCode": "45011",
        "country": "USA",
        "contactName": "Shipping/Receiving",
        "phone": "+15551234567",
        "fax": null,
        "email": null,
        "instructions": "MUST HAVE LOCKS OR STRAPS TO SECURE",
        "notes": "SET RATE -- 4PM",
        "referenceNumber": null,
        "estimatedReadyDateTime": "2026-06-29T12:00:00+00:00",
        "estimatedCloseDateTime": "2026-06-29T18:00:00+00:00",
        "appointmentReadyDateTime": null,
        "appointmentCloseDateTime": null,
        "actualArrivalDateTime": "2026-06-29T16:38:00+00:00",
        "actualDepartureDateTime": null,
        "stopType": "First Pickup",
        "shipmentStopReferenceNumbers": [],
        "shipmentStopPickupCommodities": [
          {
            "shipmentCommodityId": 36866679,
            "pickupStopId": null,
            "deliveryStopId": null
          }
        ],
        "shipmentStopDeliveryCommodities": []
      },
      {
        "shipmentStopId": 54659984,
        "companyName": "Intermediate Stop",
        "streetAddress": "555 Main Street",
        "streetAddressTwo": "Suite 1",
        "city": "Anaheim",
        "state": "CA",
        "zipCode": "92807",
        "country": "USA",
        "contactName": null,
        "phone": null,
        "fax": null,
        "email": null,
        "instructions": null,
        "notes": null,
        "referenceNumber": null,
        "estimatedReadyDateTime": "2026-06-29T21:00:00+00:00",
        "estimatedCloseDateTime": "2026-06-29T22:00:00+00:00",
        "appointmentReadyDateTime": null,
        "appointmentCloseDateTime": null,
        "actualArrivalDateTime": "2026-06-29T20:00:00+00:00",
        "actualDepartureDateTime": null,
        "stopType": "Both",
        "shipmentStopReferenceNumbers": [],
        "shipmentStopPickupCommodities": [],
        "shipmentStopDeliveryCommodities": []
      },
      {
        "shipmentStopId": 54235678,
        "companyName": "Sample Consignee",
        "streetAddress": "303 North 29th Ave",
        "streetAddressTwo": null,
        "city": "Monroe",
        "state": "WI",
        "zipCode": "53566",
        "country": "USA",
        "contactName": null,
        "phone": null,
        "fax": null,
        "email": null,
        "instructions": null,
        "notes": null,
        "referenceNumber": null,
        "estimatedReadyDateTime": "2026-06-30T13:00:00+00:00",
        "estimatedCloseDateTime": "2026-06-30T16:00:00+00:00",
        "appointmentReadyDateTime": null,
        "appointmentCloseDateTime": null,
        "actualArrivalDateTime": null,
        "actualDepartureDateTime": null,
        "stopType": "Last Drop",
        "shipmentStopReferenceNumbers": [],
        "shipmentStopPickupCommodities": [],
        "shipmentStopDeliveryCommodities": [
          {
            "shipmentCommodityId": 36866679,
            "pickupStopId": null,
            "deliveryStopId": null
          }
        ]
      }
    ],
    "commodities": [
      {
        "shipmentCommodityId": 36866679,
        "handlingQuantity": 1,
        "packagingType": "Skid",
        "length": null,
        "width": null,
        "height": null,
        "weightTotal": 15000.0,
        "hazardousMaterial": false,
        "piecesTotal": 1,
        "freightClass": "70",
        "nmfc": "120700-19",
        "description": "Conveyors, Elevators or Lifts",
        "additionalMarkings": null,
        "unNumber": null,
        "packingGroup": null,
        "referenceNumber": null,
        "hazmatCustomClassDescription": null,
        "hazmatPieceDescription": null,
        "harmonizedCode": null,
        "hazardClasses": [],
        "shipmentCommodityReferenceNumbers": []
      }
    ],
    "accessorialCodes": [],
    "shipmentAlerts": [
      {
        "type": "On Hand Origin",
        "alertId": 2,
        "createdDate": "2026-06-29T16:38:59+00:00",
        "resolved": true,
        "shipmentStopId": null
      },
      {
        "type": "AI Agent Call",
        "alertId": 271,
        "createdDate": "2026-07-22T15:36:28+00:00",
        "resolved": false,
        "shipmentStopId": null
      },
      {
        "type": "Team: Purple Team",
        "alertId": 477,
        "createdDate": "2026-06-29T14:15:27+00:00",
        "resolved": false,
        "shipmentStopId": null
      },
      {
        "type": "Customer Approved Quote",
        "alertId": 1005,
        "createdDate": "2026-06-29T14:16:25+00:00",
        "resolved": false,
        "shipmentStopId": null
      }
    ],
    "driverCellPhoneNumber": "+15551234567",
    "hazmatEmergencyContactNumber": null,
    "transitTime": null,
    "shipmentId": 130037578
  },
  "integrationSourceParameters": {
    "WorkflowId": "dispatch-standard",
    "Environment": "production",
    "licenseKey": "LK-9F2A",
    "accountNumber": "ACME-001"
  }
}

Related Articles

  • Webhook Integration Guide
  • Shipment Events
  • Public API Documentation
  • External Load Board Integration Guide

Did this page help you?