Verify the signature
Compute HMAC-SHA256 over the raw request body bytes with your webhook secret. Compare toX-Documate-Signature (sha256= + lowercase hex) using a constant-time compare.
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Outbound webhook headers, payload, and signature verification.
X-Documate-Signature (sha256= + lowercase hex) using a constant-time compare.
# BODY_FILE is the exact raw body bytes you received
SECRET='YOUR_WEBHOOK_SECRET'
SIG=$(openssl dgst -sha256 -hmac "$SECRET" "$BODY_FILE" | awk '{print $2}')
echo "sha256=$SIG"
import crypto from 'crypto';
function verify(secret, rawBody, header) {
const expected =
'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(String(header || '').trim());
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
import hashlib
import hmac
def verify(secret: str, raw_body: bytes, header: str | None) -> bool:
digest = hmac.new(secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
expected = f'sha256={digest}'
provided = (header or '').strip()
return hmac.compare_digest(expected, provided)
using System.Security.Cryptography;
using System.Text;
static bool Verify(string secret, byte[] rawBody, string? header)
{
var hash = HMACSHA256.HashData(Encoding.UTF8.GetBytes(secret), rawBody);
var expected = "sha256=" + Convert.ToHexString(hash).ToLowerInvariant();
var provided = (header ?? string.Empty).Trim();
var a = Encoding.UTF8.GetBytes(expected);
var b = Encoding.UTF8.GetBytes(provided);
return a.Length == b.Length && CryptographicOperations.FixedTimeEquals(a, b);
}
function verify(string $secret, string $rawBody, ?string $header): bool {
$digest = hash_hmac('sha256', $rawBody, $secret);
$expected = 'sha256=' . $digest;
$provided = trim($header ?? '');
return hash_equals($expected, $provided);
}