Docs
Node SDK

verifyWebhookRequest

Verify the original body and signed headers before processing a webhook.

Import

TypeScript
import { verifyWebhookRequest } from '@relayrtc/node'

Signature

TypeScript
declare function verifyWebhookRequest(
  secret: string,
  rawBody: string | Uint8Array,
  headers: WebhookHeaders,
  options?: WebhookVerificationOptions,
): boolean

Parameters

OptionTypeDefault / requirementPurpose
secretstringRequiredFull whsec_ signing secret returned by endpoint creation or rotation.
rawBodystring or Uint8ArrayRequiredUnmodified body bytes. A Node Buffer is accepted.
headersHeaders or readonly header recordRequiredIncoming request headers.
options.nowDateCurrent timeClock override, useful for controlled verification.
options.toleranceSecondsinteger300Allowed clock difference, 1–300 seconds.

Example

TypeScript
const valid = verifyWebhookRequest(
  process.env.RELAYRTC_WEBHOOK_SECRET!,
  rawRequestBody,
  request.headers,
)
 
if (!valid) {
  throw new Error('Invalid webhook signature')
}

rawRequestBody must be captured before a JSON parser rewrites the body. See the Express receiver.

Returns

A boolean. Invalid secret format, missing/duplicate headers, malformed signature, stale timestamp or mismatched digest returns false.

Headers

HeaderPurpose
x-relayrtc-signatureSignature string with timestamp.
x-relayrtc-delivery-idDelivery ID included in the signed content.
x-relayrtc-replay-countReplay count included in the signed content.
x-relayrtc-signing-key-versionInformational secret version; not part of the verifier’s signed input.

Signature format is t=TIMESTAMP,v1=HEX_DIGEST.

The HMAC-SHA256 input is the ASCII prefix TIMESTAMP.DELIVERY_ID.REPLAY_COUNT. followed by the original body bytes. The HMAC key is the complete signing secret string, including whsec_; do not decode its suffix as a separate key.

Processing events

Signature verification authenticates a delivery. It does not prevent duplicate processing. Store each event ID atomically with its side effects and processing result.

Verify the original bytes

Parsing and serializing JSON before verification can change the bytes and invalidate the signature. Register the raw-body receiver before general JSON middleware.