Webhooks

Webhooks deliver real-time notifications about events in your TRMS workspace — directly to a URL you control. Use them to integrate TRMS with your CRM, your Slack channel, or any internal workflow tool.

Overview

Webhooks let you receive HTTP POST notifications from TRMS the moment something happens in your workspace — a new tender is discovered, a review is approved, a response is submitted. Configure them from Settings → Webhooks.

Event types

The following events are emitted:

  • tender.discovered
  • tender.deadline_approaching
  • response.created
  • response.section_approved
  • response.submitted
  • compliance.check_failed

Payload format

Every webhook payload has the same envelope. The data field contains the resource that triggered the event.

{
  "id": "evt_2k9d8f",
  "type": "tender.discovered",
  "created": "2026-04-07T08:32:00Z",
  "data": {
    "id": "tnd_8s7d6f",
    "title": "ZESA grid modernisation",
    "value_usd": 24000000
  }
}

Signing & verification

Every request includes an X-TRMS-Signature header — an HMAC-SHA256 of the request body using your webhook secret. Verify it before processing the payload.

const sig = req.headers["x-trms-signature"];
const expected = crypto
  .createHmac("sha256", process.env.TRMS_WEBHOOK_SECRET)
  .update(rawBody)
  .digest("hex");

if (sig !== expected) return res.status(401).end();

Retries

If your endpoint returns a non-2xx response, TRMS will retry with exponential backoff for up to 24 hours. Make your handler idempotent — the same event id may arrive more than once.

Best practices

  • Always respond with 2xx within 5 seconds, then process async
  • Use the event id to deduplicate
  • Verify the signature on every request
  • Whitelist TRMS's outbound IPs from your firewall