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

EventDescriptionPayload Fields
job.createdA new job was created.jobId, jobType, containerSize, siteId
job.assignedA job was assigned to a driver.jobId, driverId, dispatchId, assignmentSource
job.unassignedA job was removed from a driver's route.jobId, previousDriverId
job.status_changedA job's status changed.jobId, previousStatus, newStatus, jobType, driverId, timestamp
job.completedConvenience event fired when a job reaches COMPLETED status.jobId, jobType, driverId, completedAt
dispatch.optimizedAn 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.