Guides
Webhooks
Get an HMAC-signed callback the moment an ETA moves or a box is discharged, instead of polling.
Polling is fine for a first integration, but it wastes calls and adds lag. TrackingMCP fires a webhook the instant something changes, so your systems hear about a delay when we do.
What fires
A webhook is sent when a tracked container changes in a way worth acting on:
- an ETA moves,
- a box is discharged,
- a hold or exception appears,
- a demurrage free-time clock crosses a threshold.
The payload
Each delivery is a JSON body with the event and the container it belongs to.
{
"event": "eta.changed",
"container": {
"id": "ctr_9Fk2mQ",
"reference": "MEDU1234562",
"eta": "2026-07-05",
"eta_basis": "predicted",
"previous_eta": "2026-07-03"
},
"sent_at": "2026-08-04T09:12:00Z"
}
Verifying the signature
Every delivery is signed with HMAC so you can trust it came from us and was not altered. The signature rides in a header. Recompute it over the raw request body with your signing secret and compare.
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, signature, secret) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signature);
return a.length === b.length && timingSafeEqual(a, b);
}
Verify against the raw bytes, before any JSON parsing reserialises them. A mismatch means you reject the delivery.
Responding
Return 2xx quickly. Do the real work asynchronously, so a slow handler never blocks or times out a delivery. If you return an error or time out, we retry with backoff.