Browse help topics

Add a webhook endpoint

In this article: Send contractor events to your own systems, and pick which of the five events you want.

A webhook is TrackMyVendor calling your system when something happens, instead of your system asking us. It's how everything else here — Zapier, Make, Slack, Teams — actually works underneath.

  1. Open Settings → Integrations

    Settings → the Integrations tab → Webhook Endpoints.

  2. Add the endpoint

    Label — for you, so a list of three endpoints is legible in a year. "Make scenario", "Slack #compliance".

    URL — where we POST. Must be HTTPS.

  3. Choose events

    Tick the Events you want. Subscribe to what you'll act on, not everything — an endpoint firing on events nobody handles is noise you'll eventually stop reading.

  4. Save and copy the secret

    Save. The signing secret is shown once. Copy it now — you need it to verify deliveries, and it can't be shown again.

The five events

EventFires when
contractor.createdA contractor is added.
contractor.compliance_changedTheir status badge changes. The one most people want.
contractor.license_expiringA licence is approaching expiry.
contractor.coi_expiringA certificate is approaching expiry.
contractor.w9_missingNo W-9 on file.
contractor.approvedA prospect is approved, outright or with conditions.
contractor.declinedA prospect is declined.

What we send

A POST with a JSON body:

{
  "id": "evt_4f1c9a2b7d3e8f0a1b2c3d4e",
  "event": "contractor.compliance_changed",
  "created_at": "2026-09-03T14:05:11Z",
  "data": {
    "contractor": {
      "id": 412,
      "name": "Ridgeline Electric",
      "email": "office@ridgeline.example",
      "compliance_status": "not_compliant",
      "compliance_reasons": ["The certificate from Travelers expired Sep 1, 2026"],
      "url": "https://trackmyvendor.com/app/vendors/412",
      ...
    },
    "from": "compliant",
    "to": "not_compliant"
  }
}

Every event carries the full contractor, so you don't have to look them up. The rest of data depends on the event: from and to for a status change; expiration_date, days_left and window for anything expiring, with the license or certificate it's about.

A status is one of compliant, not_compliant or no_documents — the same as the badge on the contractor's page.

And four headers:

  • X-TMV-Event — the event type
  • X-TMV-Event-Id — the event's id, the same on every attempt
  • X-TMV-Delivery — this attempt, for matching it to the delivery log
  • X-TMV-Signature — proof it came from us

Careful

Respond quickly with a 2xx and do the real work afterwards. A failed delivery is retried, so your endpoint may see the same event twice — use its id to recognise a repeat rather than acting on it again. X-TMV-Delivery is different on every attempt, so it can't tell you that.

When a delivery fails

  • Anything other than a 2xx is retried, three attempts in all. Each one appears in the endpoint's delivery log.
  • A 410 Gone is taken to mean the URL is finished with: the endpoint is switched off instead of retried. Switch it back on from the same list.
  • An address on a private network — localhost, 10.x, 192.168.x and the like — is refused when you save it, and never sent to.

What happens next

Anything reachable by URL can receive one, but you don't have to write the receiver yourself: connect Zapier or Make.

Related articles

Didn't find what you were looking for?

Send us the question — a person answers, usually the same working day.

Contact support