DocsEvents & Webhooks

Webhook Signature Verification

Verify HMAC-SHA256 signatures to ensure webhook payloads originate genuinely from PingStack.

4 min readAPI v1

Webhook Security Headers

Every webhook POST request dispatched by PingStack contains security headers: * `X-Pingstack-Event`: Event name (e.g. `message.received`). * `X-Pingstack-Event-Id`: Unique event UUID (`evt_...`). * `X-Pingstack-Timestamp`: Unix timestamp in milliseconds. * `X-Pingstack-Signature`: `v1=<hex>` HMAC-SHA256 signature calculated over `${timestamp}.${rawBody}` using your endpoint's `signing_secret`.

Verification Implementation in 5 Languages

Use timing-safe comparison over the raw UTF-8 request body:
import crypto from 'crypto';

export function verifyWebhook(rawBody, signatureHeader, timestampHeader, signingSecret) {
  const expected = crypto
    .createHmac('sha256', signingSecret)
    .update(`${timestampHeader}.${rawBody}`)
    .digest('hex');

  const received = (signatureHeader || '').replace('v1=', '');
  
  if (received.length !== expected.length) return false;
  return crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
}