Webhook Event Payload & Verification

Learn how to receive webhook events from HiTide and verify their authenticity using HMAC signature validation.

Example Webhook Payload

When a user subscribes through your HiTide campaign, we'll send a POST request to your webhook endpoint with the following JSON payload:

{
  "email": "joe@example.com",
  "collectedAt": "2025-11-11T07:46:35+00:00",
  "tags": ["HiTide", "HiTide - Campaign Name"]
}

Field descriptions:

  • email - The email address collected from the subscriber

  • collectedAt - ISO 8601 timestamp when the email was collected

  • tags - Array of tags associated with the campaign

Verifying Webhook Authenticity

To ensure the webhook request is genuinely from HiTide, you should verify the signature sent in the X-HiTide-Signature header using HMAC SHA256.

Node.js Example:

import crypto from 'node:crypto';
// Your webhook secret (found in HiTide settings)
const secret = process.env.HITIDE_WEBHOOK_SECRET;
// Get the raw request body as a string
const rawBody = JSON.stringify(req.body);
// Calculate the expected signature
const expectedSignature = crypto
  .createHmac('sha256', secret)
  .update(rawBody)
  .digest('hex');
// Get the signature from the request header
const receivedSignature = req.headers['x-hitide-signature'];
// Compare signatures using timing-safe comparison
const isValid = crypto.timingSafeEqual(
  Buffer.from(expectedSignature, 'utf8'),
  Buffer.from(receivedSignature, 'utf8')
);
if (!isValid) {
  throw new Error('Invalid webhook signature');
}

Important Notes:

  • Always use the raw request body (before JSON parsing) for signature verification

  • Use crypto.timingSafeEqual() to prevent timing attacks when comparing signatures

  • Store your webhook secret securely in environment variables

  • You will setup your webhook secret when you configure your webhook endpoint in How to Setup Webhook Endpoint