Provider · September 30, 2026
Posting carrier milestones with the Provider tracking API
A carrier system writes milestones into Cargobase for shipments it is responsible for, using the carrier tracking webhook and a status tag the shipper can see.
A provider already moves the freight. Cargobase and the shipper only see a milestone when someone types it in. This write-up is how a carrier TMS pushes those events in: who the token belongs to, which endpoint receives the event, and how the shipper side catches up.
The problem
Milestones exist in the carrier system first: booked, in transit, delayed, delivered. Cargobase still shows the last event a person pasted in. The shipper’s own tools then go stale, because they read status from Cargobase, not from the carrier.
The integration should post an event only for shipments this provider is allowed to update, and it should use the carrier’s own tracking number plus the Cargobase shipment id so both sides can match the record.
What we use
A Provider token for that carrier company. Sandbox first, Production (https://pluto.cargobase.com) when the mapping is proven. See Get API access and Authentication.
Authorization: Token <access_token>
Register the tracking number on the awarded shipment if it is not already there:
POST https://sandbox.cargobase.com/api/1/shipments/{shipment_reference}/tracking/create/
Content-Type: application/json
{
"references": [
{
"tracking_type": "primary",
"tracking_number": "TG166222"
}
]
}
Post milestones (and optional documents) with the carrier tracking webhook in the Provider API reference:
POST https://sandbox.cargobase.com/api/1/carrier-tracking-webhook
A provider can post only for shipments associated with their account. A post for someone else’s shipment is rejected.
How it plugs into the carrier TMS
Keep two ids on the carrier job: the carrier tracking number, and the Cargobase shipment reference (S…) from the awarded shipment. When the carrier TMS changes state, translate that state into a Cargobase status tag and POST once.
Required fields on the update payload:
| Field | Role |
|---|---|
tracking_number | The carrier or third-party tracking number |
tracking_type | Which system or carrier the update comes from |
tracking_update_text | A short description of what happened |
tracking_status_tag | BOOKED, INTRANSIT, DELAYED, DELIVERED, or CANCELLED |
Send shipment_id as well so the event is tied to the Cargobase shipment, not only to a tracking number. event_time should be the time the milestone happened. Send created_time too: it is the event's timestamp on the shipment timeline, and Cargobase uses it to recognise a retried event, so the same milestone is not stored twice.
JSON (milestone only)
Content-Type: application/json
{
"tracking_number": "TG166222",
"shipment_id": "S12345678",
"tracking_type": "carrier-tms",
"mode_of_transport": "air_freight",
"tracking_update_text": "Departed origin",
"tracking_status_tag": "INTRANSIT",
"created_time": "2026-09-30T08:15:00.000Z",
"event_time": "2026-09-30T08:15:00.000Z",
"expected_arrival_time": "2026-10-02T16:00:00.000Z"
}
Form-data (milestone + documents)
To upload documents, send multipart/form-data with:
| Key | Type | Role |
|---|---|---|
data | text | The tracking payload as a JSON string (same fields as above) |
documents | file | The file to attach (repeat the key for multiple files) |
Put the document type in tracking_update_text (for example POD uploaded, ARN document uploaded, HBL document uploaded).
| Document | tracking_status_tag |
|---|---|
| Proof of delivery (POD) | DELIVERED (also send actual_arrival_time) |
| Other documents (ARN, HBL, …) | INTRANSIT or another non-delivered status |
The carrier job should treat a successful response as “this milestone is in Cargobase” and should not retry the same event on every TMS save. A later, different milestone is a new POST.
On the shipper side, the same event is what their status integration reads. Cargobase can also POST a shipment-update webhook to the shipper’s HTTPS endpoint, with tracking_number and tracking_status_tag, so the shipper TMS does not have to poll. That receiver is covered in Using the Shipper API to update shipment statuses in a TMS.
What this achieves
A carrier milestone is written to the shipment the provider is actually carrying. The shipper sees that status in Cargobase, and any shipper TMS reading shipment detail or the shipment-update webhook stays aligned with the carrier system without a second manual update.