Webhooks
Receive real-time notifications when events occur in your fleet.
What are Webhooks?
Webhooks allow your application to receive automatic HTTP POST notifications when specific events happen in your EZToTrack fleet. Instead of polling the API for changes, webhooks push data to your server in real time.
Available Events
| Event | Description | Trigger |
|---|---|---|
vehicle.location.updated |
Vehicle location changed | Every location update from a tracking device |
vehicle.status.changed |
Vehicle status changed | Status transitions (driving, parked, idling, offline) |
driver.created |
New driver added | Driver created via API or dashboard |
hos.violation.detected |
HOS violation detected | Driver exceeds hours of service limits |
Payload Format
All webhook payloads follow a consistent envelope structure:
{
"id": "evt_abc123def456",
"type": "vehicle.location.updated",
"createdAt": "2026-02-01T14:30:00Z",
"data": {
"vehicleId": "veh_12345",
"name": "Truck 101",
"location": {
"latitude": 41.8781,
"longitude": -87.6298,
"heading": 245,
"speed": 55.2,
"time": "2026-02-01T14:30:00Z"
}
}
}
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID for deduplication |
type | string | Event type (see table above) |
createdAt | string | ISO 8601 timestamp (UTC) |
data | object | Event-specific payload data |
Setup
Setting up webhooks involves three steps:
-
Register your endpoint
Configure your webhook URL in the EZToTrack dashboard under Settings > Webhooks, or use the API to register programmatically.
-
Select events
Choose which events you want to receive. You can subscribe to individual events or use
*to receive all events. -
Verify signatures
Each webhook request includes a
X-EZToTrack-Signatureheader containing an HMAC-SHA256 signature. Verify this against your webhook secret to ensure authenticity.
Code Examples
import hmac
import hashlib
from flask import Flask, request, jsonify
app = Flask(__name__)
WEBHOOK_SECRET = "your_webhook_secret"
@app.route("/webhooks/eztotrack", methods=["POST"])
def handle_webhook():
# Verify signature
signature = request.headers.get("X-EZToTrack-Signature", "")
body = request.get_data()
expected = hmac.new(
WEBHOOK_SECRET.encode(),
body,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
return jsonify({"error": "Invalid signature"}), 401
# Process event
event = request.get_json()
event_type = event.get("type")
if event_type == "vehicle.location.updated":
vehicle = event["data"]
print(f"Vehicle {vehicle['name']} moved to "
f"{vehicle['location']['latitude']}, "
f"{vehicle['location']['longitude']}")
elif event_type == "hos.violation.detected":
print(f"HOS violation: {event['data']}")
return jsonify({"received": True}), 200
const express = require("express");
const crypto = require("crypto");
const app = express();
const WEBHOOK_SECRET = "your_webhook_secret";
app.post("/webhooks/eztotrack",
express.raw({ type: "application/json" }),
(req, res) => {
// Verify signature
const signature = req.headers["x-eztotrack-signature"] || "";
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)) {
return res.status(401).json({ error: "Invalid signature" });
}
// Process event
const event = JSON.parse(req.body);
switch (event.type) {
case "vehicle.location.updated":
const v = event.data;
console.log(`Vehicle ${v.name} at ` +
`${v.location.latitude}, ${v.location.longitude}`);
break;
case "hos.violation.detected":
console.log("HOS violation:", event.data);
break;
}
res.json({ received: true });
}
);
app.listen(3001, () => console.log("Webhook server on :3001"));
Best Practices
- Respond quickly — Return a 2xx response within 5 seconds. Process events asynchronously.
- Handle duplicates — Use the
idfield to deduplicate events. Webhooks may be delivered more than once. - Verify signatures — Always validate the
X-EZToTrack-Signatureheader to ensure requests are authentic. - Use HTTPS — Your webhook endpoint must use HTTPS in production.
- Monitor failures — Webhooks that fail consistently will be automatically disabled after 7 days of failures.
Retry Policy
If your endpoint returns a non-2xx status code or times out, we retry with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |