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:
| Header | Description |
|---|---|
X-Avnology-Signature | HMAC-SHA256 hex digest of {timestamp}.{body} |
X-Avnology-Timestamp | Unix timestamp when the delivery was sent |
Verification Algorithm
- Extract the
X-Avnology-TimestampandX-Avnology-Signatureheaders - Concatenate
{timestamp}.{raw_request_body}(with a literal dot separator) - Compute HMAC-SHA256 of that string using your webhook secret
- Compare your computed signature with the header value (use constant-time comparison)
- 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.
Related
- Create Webhook -- get the signing secret
- Rotate Secret -- rotate the signing secret with a grace period
- Events Reference -- all event types and payloads