Polling asks the same question over and over; webhooks answer it once, the moment it matters. Instead of your integration fetching the review list every few minutes to notice changes, TrustRating sends an HTTP POST to your endpoint whenever something you care about happens — a review is published, your score moves, an invited customer converts. Your systems react in seconds, and your API quota stays untouched.
This guide covers the available events, configuring an endpoint in the business panel, verifying that deliveries are genuine, and the operational habits that keep a webhook integration reliable.
The events you can subscribe to
Each webhook subscription picks from the same event catalog. The names below are exactly what arrives in the payload's event field:
REVIEW_CREATED— a customer submits a new review (before moderation).REVIEW_PUBLISHED— a review passes checks and goes live on your profile.REVIEW_RESPONDED— your company posts a reply to a review.REVIEW_FLAGGED— a review is flagged for moderation review.REVIEW_HIDDEN— a review is hidden or removed from your profile.SCORE_CHANGED— your TrustScore moves up or down.INVITATION_SENT— a review invitation goes out to a customer.INVITATION_REVIEWED— an invited customer leaves a review.COMPANY_VERIFIED— your company profile receives verification.ISSUE_DETECTED— TrustGuard detects a problem that needs your attention.
A few pairings cover most real integrations: REVIEW_PUBLISHED for a Slack channel or CRM sync, REVIEW_CREATED plus REVIEW_RESPONDED for support-team workflows, SCORE_CHANGED for monitoring dashboards, and INVITATION_REVIEWED to close the loop in your order system.
Configuring an endpoint
Webhooks are a capability of higher plans — see plan options if the page shows an upgrade notice. With access in place:
- Open the business panel and go to Webhooks.
- Enter your endpoint URL — an HTTPS address on your infrastructure that accepts POST requests.
- Add a short description so future-you remembers what this endpoint feeds ("Slack alerts", "CRM sync").
- Tick the events this endpoint should receive. Subscribe to what you handle, nothing more.
- Leave active checked and save.
Each subscription gets its own signing secret, generated for you and visible on the webhooks page — you will need it in the next step. You can register several endpoints per company (there is a small cap to keep fan-out sane), and each one carries its own event selection and secret, so your Slack notifier and your data pipeline stay independent. Deactivating a webhook pauses deliveries without losing its configuration.
What a delivery looks like
Every delivery is a POST with a JSON body and two TrustRating headers:
POST /webhooks/trustrating HTTP/1.1
Content-Type: application/json
X-TrustRating-Signature: 3f1c2a…
X-TrustRating-Webhook-Id: whk_8s5k2
{
"event": "REVIEW_PUBLISHED",
"companyId": "cmp_9f2k1",
"ts": 1784102530000,
"data": { "reviewId": "rev_7d31x", "rating": 5 }
}
The envelope is always the same — event, companyId, a millisecond timestamp ts, and an event-specific data object. Treat the payload as a notification, not the full record: it carries identifiers, and you fetch anything more you need via the API.
Verify the signature — every time
Anyone who discovers your endpoint URL can POST fake JSON at it. The signature header is what separates genuine TrustRating deliveries from noise: X-TrustRating-Signature is an HMAC-SHA256 of the raw request body, computed with your webhook's secret. Recompute it on your side and compare:
import crypto from "node:crypto";
function isFromTrustRating(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}
Two classic pitfalls: verify against the raw bytes as received (parsing and re-serializing the JSON changes the string and breaks the HMAC), and use a constant-time comparison rather than ===. Reject anything that fails verification with a 401 and log it.
Respond fast, process async
TrustRating considers a delivery successful when your endpoint returns any 2xx status. The right pattern is to do almost nothing inline:
- Verify the signature.
- Persist the payload to a queue or table.
- Return
200immediately. - Process the event from the queue on your own time.
If your handler does its real work — database writes, third-party API calls, Slack posts — before responding, slow dependencies turn into timeouts, timeouts turn into retries, and retries turn into duplicate processing. Acknowledge first, work second. And because retries can happen legitimately, make your processing idempotent: keying on the event plus the identifiers in data means a redelivered event is a harmless no-op.
Retries: what happens when your endpoint fails
A non-2xx response or an unreachable endpoint does not lose the event. The delivery is retried automatically with exponential backoff — the gaps start around a minute and stretch to hours — before the platform eventually marks the delivery as failed after repeated attempts. The recent deliveries log on the webhooks page shows every attempt with its event, status, attempt count, and the HTTP response your endpoint returned, and failed rows have a Retry button to re-fire them immediately once you have fixed your side.
This buys you resilience against deploys and blips, but it is not a substitute for monitoring: an endpoint that has been down for a day will have a backlog arriving out of order.
Testing your integration
- Use the Test button. Every registered webhook has a Test action in the panel that sends a delivery to your endpoint — the fastest way to confirm reachability and signature handling end to end.
- Start with a request bin. Before writing any code, point a subscription at a disposable request-inspection URL and click Test. You will see the exact headers and body you need to handle.
- Keep a staging subscription. Register your staging endpoint as a second webhook with the same events. Since each subscription has its own secret, production and staging stay cleanly separated.
- Replay with Retry. After fixing a handler bug, use the delivery log's Retry to re-send the exact failed payload instead of manufacturing a new event.
Securing the receiving endpoint
Beyond signature verification: serve HTTPS only (the form requires it), keep the secret in your secrets manager rather than your code, prefer an unguessable path for the endpoint, and rate-limit or alert on repeated signature failures — that pattern means someone is probing. If your endpoint sits behind a firewall or WAF, make sure it does not silently block unfamiliar POST traffic.
Troubleshooting missed deliveries
"Nothing arrives at all." Check the delivery log first. No rows means the events are not firing for your subscription — confirm the webhook is active and the right events are ticked. Rows with failures mean TrustRating is sending and your side is not accepting: check the logged HTTP status, your TLS certificate, and any firewall between the internet and your handler.
"Signature verification always fails." Almost always a raw-body problem: a framework middleware parsed the JSON before your code saw it. Configure the route to expose raw bytes for the HMAC check.
"I get duplicates." Your endpoint responded slowly or non-2xx, so the delivery retried. Speed up the acknowledgment and rely on idempotent processing.
"Deliveries show FAILED." The retries were exhausted while your endpoint was down. Fix the endpoint, then press Retry on the failed rows to recover them.
For pulling data on demand rather than receiving pushes, pair webhooks with the REST API — the companion guide is getting started with the API. And if the delivery log and your server logs disagree, contact support with the webhook ID and timestamps; we can trace individual deliveries.