TAI Trigger
The TAI Trigger starts a workflow when TAI — a transportation management system (TMS) for freight brokerages — reports an event. When a shipment is created or updated, or an invoice is created in TAI, TAI posts the event to Splice, and this trigger turns it into a workflow execution. Use it to react to TAI activity in real time: sync shipments into another system, generate and transmit EDI, automate billing, validate data, or raise exceptions as they happen.
Overview
Use the TAI Trigger when you need to:
- React to shipment lifecycle events - Start a workflow the moment a TAI shipment is created or updated
- Automate billing - Act on invoice creation (e.g. push invoices into an accounting system or send an 810)
- Keep systems in sync - Push shipment and invoice changes from TAI into a WMS, ERP, billing system, or data warehouse
- Drive EDI from TAI activity - Generate and send EDI (e.g. 204/214/990/810) in response to TAI events
- Act on full shipment data - Shipment events carry the complete shipment object, so the workflow can branch and transform without an extra lookup
Endpoint & Setup
The TAI Trigger is delivered over the same HTTP ingress as the Webhook trigger. TAI posts events to the workflow's public endpoint:
POST https://<your-splice-api-domain>/hook/{workflowId}
Configure TAI to send events to this URL (copy it from the workflow), then choose which event should start the workflow with the Resource and Action settings below.
The trigger node itself takes no credential — it only receives the inbound event. If a workflow needs to call back into TAI (to fetch related records or push updates), use an HTTP Request or a TAI service node with a separate Tai Client credential. That credential holds the Api Key and URL used for outbound TAI API calls.
Configuration
Resource (required)
The kind of TAI record whose events should start the workflow. The available Action options depend on this selection.
| Resource | Value |
|---|---|
| Shipment | shipment |
| Invoice | invoice |
Action (required)
The TAI event that starts the workflow. Select one; only the chosen event type triggers a run.
Shipment resource:
| Event | Value | Fires when |
|---|---|---|
| Create | shipment-create | A new shipment is created in TAI |
| Update | shipment-update | An existing shipment is updated in TAI |
Invoice resource:
| Event | Value | Fires when |
|---|---|---|
| Create | invoice-create | An invoice is created in TAI |
Output
The trigger emits a single output keyed by the node's name. The payload shape depends on the resource: shipment events deliver the shipment object directly, while invoice events nest the invoice alongside the shipment it belongs to.
Because the payloads are large and nested, inspect the captured sample for the events you actually receive before mapping fields downstream.
Shipment events
shipment-create and shipment-update deliver the shipment object at the top level (the two share the same shape):
{
"TAI Trigger": {
"shipmentId": 0,
"status": "Quote",
"totalBuy": 0,
"totalSell": 0,
"latitude": 0,
"longitude": 0,
"lastLocationUpdate": "2023-12-20T13:40:48.516Z",
"mileage": 0,
"shipmentType": "Small Package",
"serviceLevel": "Normal",
"importExport": "Import",
"customer": {
"name": "string",
"referenceNumber": "string",
"salesRepNames": "string",
"billToOrganizationId": 0,
"officeName": "string"
},
"carrierList": [
{ "carrierMasterId": 0, "name": "string", "scac": "string", "status": "Quote", "buy": 0, "sell": 0 }
],
"stops": [
{ "companyName": "string", "city": "string", "state": "string", "zipCode": "string", "stopType": "First Pickup", "appointmentReadyDateTime": "2023-12-20T13:40:48.516Z" }
],
"commodities": [
{ "description": "string", "weightTotal": 0, "piecesTotal": 0, "freightClass": "No Class", "hazardousMaterial": true }
],
"shipmentReferenceNumbers": [ { "referenceType": "Reference Number", "value": "string" } ],
"accessorialCodes": [ { "code": "string", "name": "string" } ],
"attachments": [ { "attachmentUrl": "string", "attachmentType": "Document", "filename": "string" } ],
"shipmentAlerts": [ { "type": "OnHandOrigin", "createdDate": "2023-12-20T13:40:48.516Z", "resolved": true } ]
}
}
The most commonly used fields are:
shipmentId- The TAI shipment ID.status- The shipment status (e.g.Quote).totalBuy/totalSell- The cost and revenue totals on the shipment.customer- The customer withname,referenceNumber, sales rep, and billing/office organization details.carrierList[]- The assigned carriers, withscac, DOT/MC numbers, tracking URL,transitType,status,buy, andsell.stops[]- The stops, with address, contact,stopType, and estimated/appointment/actual date-time windows.commodities[]- The freight (dimensions,weightTotal,piecesTotal,freightClass, hazmat/unNumber/hazardClasses).shipmentReferenceNumbers[]/accessorialCodes[]/attachments[]/shipmentAlerts[]- Reference numbers, accessorials, documents, and alerts.
A shipment event contains many fields across nested customer, carrier, stop, and commodity sections. Use a Set or Code node early in the workflow to pull out just the fields you need, and reference them by path (e.g. {{$json.status}}) downstream.
Before the event reaches the workflow, Splice fetches each entry's attachmentUrl and stores the file. The delivered attachments[] entries gain a file (the stored path) and filename so downstream nodes can use the document directly rather than re-fetching the original URL.
Invoice events
invoice-create wraps the invoice in an invoice object and includes the full shipment under shipmentDetails:
{
"TAI Trigger": {
"invoice": {
"invoiceId": 0,
"shipmentId": 0,
"invoiceNumber": "string",
"invoiceDate": "2024-08-16T13:32:04.058Z",
"invoiceDueDate": "2024-08-16T13:32:04.058Z",
"totalAmount": 0,
"totalAmountApplied": 0,
"paymentStatus": "Unpaid",
"isRevision": true,
"billingOrganization": { "organizationId": 0, "name": "string", "organizationType": "LSP", "address": { "city": "string", "state": "string", "zipCode": "string" } },
"payerOrganization": { "organizationId": 0, "name": "string", "organizationType": "LSP" },
"invoiceAccountingProfile": { "paymentPreference": "Cash", "paymentTerms": 0, "preferredInvoicingMethod": "Email" },
"lineItems": [
{ "invoiceLineItemId": 0, "quantity": 0, "description": "string", "accessorialCode": "string", "amount": 0, "account": { "accountName": "string", "accountType": "Accounts Receivable" } }
],
"paymentLineItems": [ { "invoicePaymentLineItemId": 0, "invoiceNumber": "string", "shipmentId": 0, "amountApplied": 0 } ],
"invoiceRecipients": [ "string" ]
},
"shipmentDetails": {
"shipmentId": 0,
"status": "Quote",
"customer": { "name": "string", "referenceNumber": "string" },
"carrierList": [ { "name": "string", "scac": "string" } ],
"stops": [ { "companyName": "string", "city": "string", "state": "string", "stopType": "First Pickup" } ],
"commodities": [ { "description": "string", "weightTotal": 0, "piecesTotal": 0 } ]
}
}
}
Key fields:
invoice.invoiceId/invoice.invoiceNumber- The invoice identifiers.invoice.shipmentId- The shipment the invoice belongs to.invoice.invoiceDate/invoice.invoiceDueDate- When the invoice was raised and when it is due.invoice.totalAmount/invoice.totalAmountApplied/invoice.paymentStatus- The amount, the amount paid, and payment state (e.g.Unpaid).invoice.billingOrganization/invoice.payerOrganization- The billing and paying organizations, with addresses and contact details.invoice.lineItems[]- The charge lines, each withquantity,description,accessorialCode,amount, and the GLaccountit posts to.invoice.invoiceRecipients[]- Email recipients for the invoice.shipmentDetails- The full shipment context (same shape as a shipment event), so the workflow can act on the invoice without a separate lookup.
Example Usage & Common Use Cases
Sync a Shipment into Another System
Resource: Shipment Action: Create / Update
[TAI Trigger] → [Set: map shipmentId / status / stops]
→ [HTTP Request: upsert into WMS]
Generate EDI on Shipment Creation
Resource: Shipment Action: Create
[TAI Trigger] → [Set: extract shipment fields] → [EDI: build 204] → [AS2 / FTP: send to carrier]
Branch on Status
Resource: Shipment Action: Update
[TAI Trigger] → [If: status == "Delivered"] → [Send 214 / notify customer]
Automate Invoicing
Resource: Invoice Action: Create
[TAI Trigger] → [Set: map invoice.invoiceNumber / customer / totalAmount]
→ [EDI: build 810] → [AS2: send to customer]
How It Works
- TAI posts an event - TAI sends a
POSTto the workflow's/hook/{workflowId}URL when a subscribed event occurs, including the shipment or invoice payload. - Match the trigger - The webhook ingress resolves the workflow and selects its trigger node.
- Filter by resource and action - Only events matching the configured Resource and Action start the workflow.
- Enqueue - The event body becomes the trigger output and a workflow execution is started.
Best Practices
- Select only the event you handle - Configuring the resource and action the workflow is built for avoids unnecessary runs.
- Extract early - The payload is deep and verbose; map the handful of fields you need up front so downstream nodes stay readable.
- Make downstream actions idempotent -
shipment-updatecan fire repeatedly for the same shipment; key downstream updates onshipmentIdso repeats are safe. - Handle create/update distinctly - Build separate workflows (or branch) when create and update should do different things (insert vs. upsert).
- Guard against missing fields - Optional sections (carriers, stops, commodities, attachments, alerts) may be absent or empty depending on the shipment; don't assume a fixed shape.
Troubleshooting
Common Issues
- No workflow runs on a TAI event - Confirm TAI is posting to the correct
/hook/{workflowId}URL, the workflow is active, and the configured Resource / Action match the event TAI sends. - A field is missing from the payload - TAI omits sections that don't apply to a given shipment or invoice. Inspect the captured sample for the actual shape and code defensively.
- Outbound TAI API call fails - The trigger and the TAI API are separate concerns. Verify the Tai Client credential (Api Key and URL) used by the downstream HTTP/service node, not the trigger.
Debugging Tips
- Inspect the captured sample - The trigger output is stored as node sample data on each run; use it to navigate the nested payload and build downstream field paths.
- Test with a manual POST - Send a sample shipment or invoice body to the URL with
curlto confirm the endpoint and downstream logic before relying on live TAI events.
Related
- Webhook - The general-purpose HTTP trigger this node is built on
- TAI - Call into the TAI API when the workflow needs more than the event payload
- Trigger Nodes - Overview of all available workflow trigger types