Axsync API v2

Verifying signatures

Each delivery has an Axsync-Signature header: t=timestamp,v1=hmac.

Compute HMAC-SHA256 over timestamp + '.' + raw_body with your webhook secret and compare in constant time. Reject timestamps older than five minutes to prevent replay.

import crypto from 'node:crypto';

export function verify(raw, header, secret) {
  const [t, v1] = header.split(',').map(p => p.split('=')[1]);
  const mac = crypto.createHmac('sha256', secret).update(`${t}.${raw}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(v1)) && Date.now() / 1000 - t < 300;
}
import hmac, hashlib, time

def verify(raw: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split('=') for p in header.split(','))
    mac = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(mac, parts['v1']) and time.time() - int(parts['t']) < 300