Webhooks
Register webhook endpoints to receive real-time notifications when events occur in your haulers' operations. Klau pushes events to your server instead of requiring you to poll.
Registering a Webhook
Create a webhook endpoint via the Developer Settings page or the API. Specify the URL to receive events and the event types you want to subscribe to.
POST /api/v1/webhooks
Authorization: Bearer <token>
Content-Type: application/json
{
"url": "https://your-server.com/webhooks/klau",
"eventTypes": ["job.completed", "dispatch.optimized"]
}Verifying Signatures
Every webhook request includes a Klau-Signature header so you can verify it came from Klau.
Klau-Signature: t=1709654400,v1=a3f2b1c8d4e5...To verify: compute HMAC-SHA256 of timestamp.payload using your webhook secret. Compare the result to the v1 value in the header. Reject the request if they don't match.
// Node.js verification example
const crypto = require('crypto');
function verifySignature(payload, header, secret) {
const [tPart, v1Part] = header.split(',');
const timestamp = tPart.replace('t=', '');
const signature = v1Part.replace('v1=', '');
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Event Types
| Event | Description | Payload Fields |
|---|---|---|
| job.created | A new job was created. | jobId, jobType, containerSize, siteId |
| job.assigned | A job was assigned to a driver. | jobId, driverId, dispatchId, assignmentSource |
| job.unassigned | A job was removed from a driver's route. | jobId, previousDriverId |
| job.status_changed | A job's status changed. | jobId, previousStatus, newStatus, jobType, driverId, timestamp |
| job.completed | Convenience event fired when a job reaches COMPLETED status. | jobId, jobType, driverId, completedAt |
| dispatch.optimized | An optimization run completed. | dispatchId, date, mode, metrics |
Delivery Guarantees
- Transactional outbox: Events are saved to the database in the same transaction as the change that produced them. No events are lost even if the webhook relay is temporarily down.
- At-least-once delivery: If your server returns a non-2xx response, Klau retries with exponential backoff for up to 24 hours.
- 10-second timeout: Your endpoint must respond within 10 seconds or the delivery is marked as failed and retried.
Handling Duplicates
Because delivery is at-least-once, your server may receive the same event more than once. Use the event id field to deduplicate on your end.