AP Records: Third Party → Tai

Four ways to push AP data from your accounting system into Tai — approve pending bills, post variances for human review, correct carrier-charge pricing before accounting locks, or fall back to activity logs when a Tai user needs to step in.

What this is for

Your AP department is the one that opens the envelope, reads the carrier's actual invoice, and decides whether it matches what was quoted. Tai has a "pending bill" waiting; your AP process is what turns it into an approved bill (or flags it for a manager review). This flow is how your ERP or in-house AP tool tells Tai the outcome: approve the pending bill with the vendor's real numbers, flag it for variance when the numbers don't match, or correct the pricing if you catch it before the bill goes out.

Four endpoints handle four situations. Pick the one that matches what your AP process just decided.

1. Approve a pending Bill

The standard "the carrier's invoice matches, close it out" flow. Your AP department received the vendor's actual invoice and the numbers reconcile — this endpoint approves the matching pending bill in Tai with the vendor's real bill number, dates, and amount.

POST  /PublicApi/Accounting/v2/Bills/Approve

View in API Reference →

Request payload

{
  "shipmentId": 131382699,
  "vendorId": 903421,
  "vendorType": "Carrier",
  "transitLegType": "Linehaul",
  "billNumber": "B-2026-091043",
  "billAmount": 1847.50,
  "billDate": "2026-09-04T00:00:00Z",
  "billDueDate": "2026-10-04T00:00:00Z"
}
FieldRequiredNotes
shipmentId + vendorId + vendorType + transitLegTypeYesThe 4-tuple that uniquely identifies the pending bill on the shipment. vendorType: Carrier or Organization. transitLegType: PickupLocal, Linehaul, DeliveryLocal, Ocean, Air, Insurance, Customs, Lumper, Warehouse, Other, Consolidation, TONU.
billNumberYesVendor's invoice number.
billAmountYesTotal the vendor billed. Must be within the broker's Over Payment Tolerance vs. the expected pending amount, or Tai will reject with: "Cannot create bill as it does not meet Over Payment Tolerance. Expected bill amount: X, which led to a difference of Y and this was not within tolerances."
billDate, billDueDateNoVendor's invoice date and due date.

Response (200) — returns the full PublicAPIBill in the shape shown on AP Records: Tai → Third Party, including the newly-assigned billId. Save this for the sync status update.

Common errors

Bill amount exceeds the remaining chargeable amount by more than the broker's AP Overpay Tolerance:

["Cannot create bill as it does not meet Over Payment Tolerance. Expected bill amount: 1200.00, which led to a difference of 647.50 and this was not within tolerances."]

Expected bill amount is the sum of the still-chargeable lines on that leg for the vendor (billing status Ready, NotReady, or HasVariance). If your billAmount is higher than that by more than the broker's configured Overpay Tolerance, this fires. There's a matching "Under Payment Tolerance" error for the opposite case.

No chargeable lines left on that leg for the vendor — usually because a bill has already been approved for that shipment/vendor/leg combination:

["Cannot create bill, no charges found for this vendor."]

This is the actual "already approved" signal — once a bill exists against the 4-tuple (shipmentId + vendorId + vendorType + transitLegType), the underlying charge lines transition out of chargeable status and there's nothing left to approve against. Post a variance or use activity logs to flag it for a Tai user.

Carrier not on file (when vendorType is Carrier and the vendorId doesn't match a CarrierMasterId):

{"exceptionType":"ObjectNotFoundException","exceptionMessage":"Carrier not found: 999999"}

2. Post a variance (route for review)

The "the numbers don't match, don't auto-approve — flag it for a human" flow. Use when your AP department caught a discrepancy they can't resolve programmatically: bill amount higher than expected, detention hours in dispute, wrong vendor billed. This routes the bill into Tai's variance queue for a Tai user to reconcile in the UI.

POST  /PublicApi/Accounting/v2/Bills/Variance

View in API Reference →

Request payload

{
  "shipmentId": 131382699,
  "vendorId": 903421,
  "vendorType": "Carrier",
  "transitType": "Linehaul"
}

Lightweight — just identifies the shipment leg + vendor. The Tai user handles the reconciliation once the variance appears on their queue.

Common error — attempting variance on a bill that's already been through accounting:

["Cannot variance bill, accounting has already started."]

3. Update Carrier Charges (buy-side pricing)

The "the rate itself was wrong, fix it before the bill goes out" flow. Use when your integration or your AP department discovers the original quoted rate needs adjustment — bad tariff match, missed accessorial, updated fuel surcharge — and there's still time to correct the pricing before Tai generates the bill.

PUT  /PublicApi/Shipping/v2/CarrierCharges

View in API Reference →

Request payload

{
  "referenceNumbers": [
    { "referenceType": "ShipmentId", "value": "131382699" }
  ],
  "transitType": "Linehaul",
  "carrierMasterId": 1122,
  "charges": [
    {
      "chargeType": "Linehaul",
      "price": 1650.00,
      "calculationType": "Flat"
    },
    {
      "chargeType": "Fuel",
      "price": 197.50,
      "calculationType": "PercentageOfLinehaul"
    }
  ],
  "accessorialCharges": [
    {
      "accessorialCode": "DETENTION",
      "price": 75.00,
      "calculationType": "Flat"
    }
  ]
}
FieldRequiredNotes
referenceNumbers[].referenceType + valueYesIdentifies the shipment. referenceType values: ShipmentId, BrokerReference, CustomerReference, CarrierReference, PurchaseOrder, BillOfLading, etc.
transitTypeYesWhich leg of the shipment: Linehaul, PickupLocal, DeliveryLocal, etc.
carrierMasterIdNoWhich carrier the charges apply to.
charges[].chargeTypeYesEnum: Linehaul, Fuel, Pickup, Delivery, Insurance, Handling, Detention, Lumper, Warehouse, AirFreight, OceanFreight, CustomsEntry, MiscCharges, OtherCharges, and many more (see full enum in the API DTO reference).
charges[].priceYesDollar amount for this line.
charges[].calculationTypeYesHow the price is computed: Flat, CWT, CubicFoot, Density, DimensionalWeight, External, Mileage, MinCharge, Pallet, PercentageOfLinehaul, Pieces, Pound, Ton, PerQuantity, Call.
accessorialCharges[].accessorialCodeYesBroker-defined accessorial code (e.g. DETENTION, LFTD, APTD).
🚧

Accounting Lock

This endpoint is not available once accounting has occurred for the leg. Once a Bill has been created or approved against the specified transit leg, its charges are locked and this call will be rejected. Use Post a variance (above) instead to flag a Tai user for manual reconciliation.

Common error — request-shape validation error:

[
  { "key": "shipmentCharges.ReferenceNumbers[0].ReferenceType", "value": "The ReferenceType field is required." },
  { "key": "shipmentCharges.Charges[0].ChargeType", "value": "The field ChargeType is invalid." }
]

4. When nothing above fits — Activity Log fallback

The escape hatch. Vendor not on file, ambiguous carrier match, amount requiring management approval, accessorial the customer has to authorize — post the situation as an activity log on the shipment so a Tai user picks it up inside the shipment view. Don't block your pipeline waiting for a human.

POST  /PublicApi/Shipping/v2/ShipmentActivityLogs

View in API Reference →

See Shipment Activity Logs for the full payload shape and how to write actionable error messages.

Close the loop

After you've approved (or variance-flagged) the bill in Tai, close the loop with a sync status update so Tai knows the bill also exists in your target system, with your target's transactionId on the Tai record for future cross-referencing.

PUT  /PublicApi/Accounting/v2/Bills/Sync

View in API Reference →

Full details: Sync Status Updates.


Did this page help you?