Skip to documentation
Browse documentation topics
Documentation / Integrations and API

CONNECT YOUR SYSTEMS

Webhooks: being told when something happens

Have MegaHub post to your own system when a lead arrives, an order ships or a payment clears.

Public documentation6 min read
Explore Integrations and API
Requests in, signed events out: Your server → Posting endpoint → CRM record → Webhook event
Workflow illustration · Requests in, signed events out

A webhook is MegaHub calling you. You give it a URL, choose which events matter, and it posts JSON to that URL when they happen — so your accounting system, your own dashboard or a Zapier hook can react without polling.

Setting one up

  1. 1Settings → Integrations → Webhooks.
  2. 2Add an endpoint: a name you will recognise and an https URL that accepts POST.
  3. 3Tick the events you want. Start narrow; you can add more later.
  4. 4Copy the signing secret. You need it to verify deliveries are genuine.
  5. 5Use the Test button, which posts a sample payload so you can confirm your side receives it.

Events you can subscribe to

EventFires when
lead.createdAny lead arrives, from any source.
lead.status_changedAn agent moves a lead.
quote.sentA quote goes out to a customer.
order.createdA quote is converted to an order.
order.status_changedAn order moves through the pipeline.
order.deliveredA vehicle is marked delivered.
dispatch.offeredA load is offered to a carrier.
dispatch.acceptedA carrier accepts.
dispatch.declinedA carrier declines.
payment.succeededA payment clears.
payment.failedA payment is declined.
payment.refundedA refund is issued.
chargeback.openedA customer disputes a charge.

Verifying a delivery

Every delivery carries these headers. Check the signature before trusting the body — your URL is reachable by anyone who guesses it, and the signature is what proves the post came from MegaHub.

text
X-TransportCRM-Event:     order.delivered
X-TransportCRM-Delivery:  a unique id for this delivery
X-TransportCRM-Timestamp: unix seconds
X-TransportCRM-Signature: v1=<hex hmac>

The signature is an HMAC-SHA256 over the timestamp, a full stop, and the raw request body, keyed with your endpoint's secret.

Verifying in Node
javascript
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(req, rawBody, secret) {
  const timestamp = req.headers["x-transportcrm-timestamp"];
  const signature = req.headers["x-transportcrm-signature"];

  const expected =
    "v1=" +
    createHmac("sha256", secret)
      .update(`${timestamp}.${rawBody}`)
      .digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(String(signature));

  // Reject on a length mismatch first: timingSafeEqual throws rather than
  // returning false when the two differ in length.
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

Retries

A delivery that fails is retried with exponential backoff. Answer quickly with a 2xx and do your work afterwards: a receiver that takes thirty seconds to reply will be treated as failed and sent the same event again. Deliveries and their responses are listed under the endpoint, which is where to look when something did not arrive.

Read next

Need a hand with this step?

Tell us what you tried and the result you received.

Contact support