Avnology ID
API ReferenceWebhooks

Signature Verification

How to verify webhook delivery signatures using HMAC-SHA256 with code examples in 5 languages.

Webhook Signature Verification

Every webhook delivery is signed with your webhook's signing secret using HMAC-SHA256. Always verify signatures before processing webhook payloads to ensure they originated from Avnology ID and were not tampered with.

Signature Format

Each delivery includes two headers:

HeaderDescription
X-Avnology-SignatureHMAC-SHA256 hex digest of {timestamp}.{body}
X-Avnology-TimestampUnix timestamp when the delivery was sent

Verification Algorithm

  1. Extract the X-Avnology-Timestamp and X-Avnology-Signature headers
  2. Concatenate {timestamp}.{raw_request_body} (with a literal dot separator)
  3. Compute HMAC-SHA256 of that string using your webhook secret
  4. Compare your computed signature with the header value (use constant-time comparison)
  5. Optionally verify the timestamp is within 5 minutes to prevent replay attacks

Code Examples

JavaScript (Node.js)

import crypto from 'crypto';

function verifyWebhookSignature(secret, signature, timestamp, body) {
  // Prevent replay attacks (5 minute tolerance)
  const now = Math.floor(Date.now() / 1000);
  if































Python (Flask)

import hmac
import hashlib
import time
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

def






















Go (net/http)

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"

































Ruby

require 'openssl'
require 'json'

def verify_webhook(secret, signature, timestamp, body)
  return false if (Time.now.to_i - timestamp.to_i).abs > 300

  payload = "#{timestamp}.#{body}"
  expected = OpenSSL::HMAC

PHP

function verifyWebhook(string $secret, string $signature, string $timestamp, string $body): bool {
    if (abs(time() - intval($timestamp)) > 300) {
        return false






Testing Verification

Use the Test Webhook endpoint to send a test event to your endpoint and verify your signature implementation works correctly.