A single tracking event. Requires type and dateTime. At least one of shipmentEvent, readings or stops must be present.
readings
object
Conditional
Position and/or sensor readings, with its own dateTime. At least one of shipmentEvent, readings or stops must be present.
stops
array
Conditional
Updates to stops that already exist on the shipment, such as a carrier ETA or an appointment window. At least one of shipmentEvent, readings or stops must be present. See stops[].
extensions
object
No
Reserved for carrier-specific extension fields.
Objects
Field references for the nested objects under truckload. Timestamps are ISO 8601 date-times (for example 2026-06-01T08:30:00Z) and must not be more than 5 minutes in the future.
Each entry updates one stop that already exists on the shipment. project44 never creates, removes or reorders stops from this array. Identify the stop with stopNumber or stopReferenceId, and always send at least one value to set. An entry that identifies a stop but carries neither carrierEstimatedArrivalDateTime nor carrierAppointmentWindow is accepted and simply has no effect, so it will not tell you that something is missing.
Field
Type
Required
Description
stopNumber
integer
Conditional
1-based position of the stop on the shipment. The most reliable way to identify a stop.
stopReferenceId
string
Conditional
Carrier's reference id for the stop. Maximum 255 characters.
stopType
string
No
PICKUP or DELIVERY. Use only when the shipment has exactly one stop of that type.
stopId
string
No
project44 stop id. Accepted, but identify the stop with stopNumber or stopReferenceId.
carrierEstimatedArrivalDateTime
string
No
Your estimated arrival at the stop. Must include a UTC offset or Z — see the note below.
carrierAppointmentWindow
object
No
A dock appointment window for the stop.
carrierEstimatedArrivalDateTime and carrierAppointmentWindow use different time formats on purpose. An ETA is an instant, so carrierEstimatedArrivalDateTime must carry a UTC offset or the Z designator, for example 2026-06-01T14:30:00-05:00. An appointment window is a wall-clock commitment at the dock, so its times are local to the stop. An offset is optional there: send the plain wall-clock time, and if you do include an offset it is honoured.
stops[].carrierAppointmentWindow
Field
Type
Required
Description
startDateTime
string
Yes
When the window starts, as the wall-clock time at the stop, for example 2026-06-01T15:00:00. Do not convert to UTC.
endDateTime
string
Yes
When the window ends, in the same format. Must be later than startDateTime.
The carrier appointment window is displayed separately from the customer appointment window and does not override it. Both remain visible.
Identifier Reference
The identifiers object uses named keys, not a polymorphic typed array. At least one of billOfLadingNumber or orderNumber is required; each value is a string with a maximum length of 256 characters.
Category
Key
Description
Shipment
billOfLadingNumber
The shipment's bill of lading (BOL) number.
Shipment
orderNumber
The shipment's order number.
Carrier
scac
The SCAC of the carrier the data is about (for example XPPP).
Carrier
dotNumber
The US DOT number of the carrier the data is about.
Carrier
mcNumber
The MC number of the carrier the data is about.
The shipment is resolved from billOfLadingNumber and orderNumber only. The carrier keys scac, dotNumber, and mcNumber identify the carrier the data is about, and are only needed when you push for another carrier. Leading and trailing whitespace on identifier values is trimmed before matching.
Unrecognized identifier keys are silently ignored, not rejected.identifiers is not a closed set of keys: it accepts up to 250 keys, and any key other than the five listed above is accepted, counted towards that limit, and then dropped. A misspelled carrier key — for example carrierScac instead of scac — therefore returns 202 and looks successful, while carrier attribution is silently lost. Confirm the exact spelling of every key you send before you go live.
A misspelled shipment-resolving key behaves differently. Because at least one of billOfLadingNumber or orderNumber is required, sending only bolNumber leaves the request with no resolving identifier and it is rejected with 400 rather than accepted. The silent-202 case above applies to unrecognized keys sent alongside a valid resolving identifier.
Pushing for Another Carrier
Normally you push tracking data for your own shipments, and no carrier identifier is needed: project44 uses the credentials on the request to work out which carrier the data is about.
A carrier identifier is only needed when those two are different — for example when a telematics provider or fleet aggregator pushes for the carriers whose fleets it manages. Two roles are involved:
Reporting carrier — the party that holds the API credentials and makes the request.
Subject carrier — the carrier the data is about, that is, the carrier on the shipment. The subject carrier does nothing at request time.
When the reporting carrier and the subject carrier are different, name the subject carrier in the identifiers object using whichever of scac, dotNumber, or mcNumber that carrier has. A carrier without a SCAC, for example, is identified by dotNumber or mcNumber. All values are strings.
project44 must authorize you to report for each subject carrier before you start. This cannot be set up by yourself — contact your project44 integration representative. Use only the keys scac, dotNumber, and mcNumber; any other spelling is accepted with a 202 response and then ignored, and the carrier the data is about is lost.
Stop Coupling
Stop-coupled events reference a stop through the shipmentEvent object (not identifiers), using any of stopReferenceId, stopId, or stopNumber. All three are optional. When more than one is present, they are resolved in the priority order stopReferenceId > stopId > stopNumber.
Entries in stops[] identify their stop independently of shipmentEvent, using stopReferenceId, stopNumber or stopType, resolved in that order. A stop update that matches no stop on the shipment is discarded.
FTL Event Types
The endpoint accepts project44's standard shipment event types plus the truckload terminal events ARRIVED_AT_TERMINAL and DEPARTED_TERMINAL. The complete list is in the reference documentation. Other values are accepted and stored but do not change the shipment's status; only the events below produce a status milestone:
Event type
Description
ARRIVAL_AT_STOP
Vehicle has arrived at the stop.
DEPARTURE_FROM_STOP
Vehicle has departed from the stop.
LOAD_ONTO_VEHICLE
Freight is being loaded onto the vehicle.
UNLOAD_FROM_VEHICLE
Freight is being unloaded from the vehicle.
DELIVERY
Freight has been delivered.
GATE_IN
Unit has entered the gate/facility.
GATE_OUT
Unit has exited the gate/facility.
DISPATCH
Vehicle has been dispatched.
ARRIVED_AT_TERMINAL
Unit has arrived at a terminal.
DEPARTED_TERMINAL
Unit has departed a terminal.
Events that do not map to a milestone (for example PICKED_UP, OUT_FOR_DELIVERY) are accepted with 202 and stored, but do not change the shipment's status. A position update flows whenever readings.position is present, regardless of the event type.
Migrating from the Truckload Status-Update Endpoint
If you already send Truckload tracking data to /api/v4/capacityproviders/tl/shipments/statusUpdates (see Send Tracking Updates), the table below maps what you send today to its Universal PUSH equivalent. For complete payloads, see Send Tracking Updates.
Truckload status-update endpoint
Universal PUSH
Notes
Payload top level
FTL tracking data nested under truckload
The tracking data moves one level down, under the truckload key. customerAccountNumber is the exception and stays at the top level, alongside truckload.
customerId
customerAccountNumber
Identifies the customer the tracking data is for. It stays at the top level and does not move under truckload. customerAccountNumber is the customer's project44 tenant ID, so confirm the value to send with your project44 integration representative rather than reusing your existing customerId value unchanged.
shipmentIdentifiers[], an array of {type, value}
identifiers, an object with named keys
Type BILL_OF_LADING becomes identifiers.billOfLadingNumber; type ORDER becomes identifiers.orderNumber. At least one of the two is still required.
carrierIdentifier{type: SCAC, value}
identifiers.scac
Use identifiers.dotNumber or identifiers.mcNumber for a carrier that has no SCAC. Still only needed when you push for another carrier — see Pushing for Another Carrier.
eventStopNumber
shipmentEvent.stopNumber
shipmentEvent.stopReferenceId and shipmentEvent.stopId are also available — see Stop Coupling.
utcTimestamp
shipmentEvent.dateTime and/or readings.dateTime
The event and the readings each carry their own timestamp and are independent. When you send both objects and only have one time, send the same value in both. For a readings-only payload — the POSITION migration above — set readings.dateTime only. Universal PUSH timestamps are ISO 8601 date-times with the UTC designator, for example 2026-06-01T08:30:00Z.
Position now lives in the readings object rather than at the top level.
eventType: ARRIVED
shipmentEvent.type: ARRIVAL_AT_STOP
eventType: DEPARTED
shipmentEvent.type: DEPARTURE_FROM_STOP
eventType: LOADING
shipmentEvent.type: LOAD_ONTO_VEHICLE
eventType: UNLOADING
shipmentEvent.type: UNLOAD_FROM_VEHICLE
eventType: DELIVERED
shipmentEvent.type: DELIVERY
eventType: POSITION
No shipmentEvent
There is no POSITION event type. Send a readings-only payload instead: omit shipmentEvent and send readings with a position.
shipmentStops[].stopNumber
stops[].stopNumber
Still 1-based. stops[] updates stops that already exist on the shipment.
shipmentStops[].carrierSuppliedEta
stops[].carrierEstimatedArrivalDateTime
The legacy value is a UTC instant, written either bare (2025-01-05T10:30:00) or with an explicit zero offset (2025-01-05T10:30:00+0000). carrierEstimatedArrivalDateTime always requires an offset or the Z designator, so add Z to the bare form and rewrite +0000 as Z. Both become 2025-01-05T10:30:00Z.
shipmentStops[].appointmentWindow
stops[].carrierAppointmentWindow
Same wall-clock-at-the-stop semantics, same startDateTime / endDateTime.
Universal PUSH has no time-zone field. Times are interpreted in the stop's own time zone, which is what omitting localTimeZoneIdentifier did on the legacy endpoint.
Any field you send today that is not listed above has no direct one-to-one equivalent. Contact your project44 integration representative before you migrate it, rather than guessing at a mapping.
Payload Limits
Entity
Limit
Total payload
1 MB
identifiers keys
250
Identifier value length
256 characters
stops[] items
100
readings.sensor.zones[] items
5
readings.sensor.tirePressure[] items
22
Error Response Codes
If there was a problem with your request, you will receive one of the following HTTP status codes:
Status code
Meaning
400 Bad Request
Synchronous schema validation failed. The response body lists each violation. The event was not accepted.
401 Unauthorized
Authentication credentials are missing or invalid.
403 Forbidden
Your credentials are not authorized to push for this tenant.
404 Not Found
The requested resource does not exist.
413 Content Too Large
Payload exceeds the 1 MB size limit.
No 5xx status is surfaced externally.
Error Response Body
Validation errors return the standard project44 ApiError envelope. errors[] may carry more than one entry (for example, an empty identifiers object returns three). errorMessage and source are returned null; supportReferenceId is a reference id to quote when contacting project44 support.
JSON
{"httpStatusCode":400,"httpMessage":"Bad Request","errorMessage":null,"errors":[{"severity":"ERROR","message":"$.truckload.readings.position: required property 'latitude' not found","diagnostic":"MISSING_REQUIRED_FIELD at $.truckload.readings.position","source":null}],"supportReferenceId":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}
Error Response Field
Description
httpStatusCode
The value of the HTTP status code.
httpMessage
A brief description of the HTTP status code.
errorMessage
A detailed description of the error. Returned null for schema-validation errors.
errors
An array containing one entry per violation.
errors.severity
The severity of the message. Possible values: ERROR, WARNING, INFO.
errors.message
The JSON path of the offending field plus the reason.
errors.diagnostic
A machine-readable diagnostic code and the JSON path (for example MISSING_REQUIRED_FIELD at $.truckload.identifiers).
errors.source
The originator of the error. Returned null for schema-validation errors.
supportReferenceId
A reference identifier to quote when contacting project44 support.