HaulMatch
Documentation menu
Preview

Set up signed webhooks

Receive organization events, verify signatures, deduplicate deliveries and recover failures.

By HaulMatch · Updated

Integrations are in preview. Setup access depends on rollout and provider configuration. If your settings show integrations are not enabled, contact HaulMatch for availability. Contact us.

On this page

1. Register your receiver

  1. Deploy a public HTTPS receiver on port 443. Redirects and private network destinations are not accepted.
  2. As organization owner, open Connections, enter the receiver URL and select the events to subscribe to. Select a fleet team first when the subscription belongs to that team.
  3. Save the one-time webhook secret in the receiver’s server-side secret store. Use Delivery log to inspect delivery attempts.

Supported events

The envelope includes id, type, createdAt, organizationId, optional teamId and event-specific data. Use the event type and resource IDs to decide which records your system should update.

Event names (Text)
load.created
quote.received
quote.updated
quote.accepted
quote.withdrawn
job.assigned
driver.assigned
job.in_transit
job.completed
job.cancelled
job.relisted
payment.funded
payment.released
payment.refunded
payment.disputed
payout.updated

Event envelope

Example job event (JSON)
{
  "id": "REPLACE_WITH_EVENT_ID",
  "type": "job.in_transit",
  "createdAt": "2026-10-09T12:00:00.000Z",
  "organizationId": "REPLACE_WITH_ORGANIZATION_ID",
  "teamId": null,
  "data": {
    "jobId": "REPLACE_WITH_JOB_ID",
    "status": "IN_TRANSIT"
  }
}

2. Verify the signature

  1. Preserve the exact UTF-8 request body before JSON parsing. Read X-HaulMatch-Signature, which contains t=UNIX_SECONDS,v1=HEX_HMAC_SHA256.
  2. Compute HMAC-SHA256 over the timestamp, a full stop and the exact request body using the webhook secret. Compare digests in constant time.
  3. Reject stale timestamps older than five minutes and durably record the event ID before applying side effects.
Node.js signature verification example (JavaScript)
import { createHmac, timingSafeEqual } from 'node:crypto';
/** Call before JSON parsing, then deduplicate the event ID in your database. */
export function verifyWebhook(rawBody, signature, secret, now = Math.floor(Date.now() / 1000)) {
  const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(signature ?? '');
  if (!match || Math.abs(now - Number(match[1])) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${match[1]}.`).update(rawBody).digest();
  return timingSafeEqual(expected, Buffer.from(match[2], 'hex'));
}

3. Deduplicate and acknowledge

Webhook delivery is at least once. Deduplicate by event ID, including retries and manual replays. Acknowledge with a successful HTTP response only after you have durably accepted the event for processing.

Process time-consuming work asynchronously so the receiver responds within the 15-second attempt timeout. Use the API to read current job state when your system needs to reconcile events.

4. Recover failed deliveries

Automatic delivery uses eight attempts with exponential backoff and jitter, capped at six hours. Destination DNS is checked on each attempt and redirects are rejected. Removing or disabling a subscription stops its pending deliveries.

The delivery log shows event, channel, status, attempts and failure details. Authorized operations staff can replay finished or failed deliveries after fixing the receiver. Keep deduplication active during replay.