Webhook verification
Import from the dedicated entry point — no client or credentials required:
import {
constructEvent,
verifyWebhookSignature,
SignatureVerificationError,
} from '@minetech/node/webhooks';
constructEvent
Verifies, then parses:
const event = await constructEvent({
payload: req.body, // RAW bytes
signatureHeader: req.header('x-mt-signature'),
secret: process.env.MINETECH_WEBHOOK_SECRET!,
});
verifyWebhookSignature
When you want to parse yourself:
await verifyWebhookSignature({
payload: rawBody,
signatureHeader: header,
secret,
toleranceSeconds: 300, // default
algorithms: ['sha256', 'sha512'],
});
Returns true or throws. Both algorithms are accepted by default, so an endpoint
configured for sha512 verifies with no caller change.
Failure reasons
SignatureVerificationError.reason is one of:
| Reason | Meaning |
|---|---|
no_signatures | Header absent |
malformed_header | Not t=…,v1=… |
timestamp_out_of_tolerance | Outside the window — check your clock |
no_match | Digest mismatch — wrong secret, or not the raw body |
These are distinguished deliberately: a clock problem and a wrong secret need different fixes.
Raw body
The digest covers the exact bytes sent. Use express.raw({ type: 'application/json' })
on the webhook route, or request.get_data() in Flask. A parsed-and-re-serialised
body will never verify.
Typed events
switch (event.type) {
case 'safety.incident.reported':
console.log(event.data);
break;
default:
// Unknown types parse fine — new events never break a deployed receiver.
break;
}