Signature Verification
Every webhook request includes an X-AudioSpliter-Signature header containing an HMAC-SHA256 signature. Verify this signature to ensure the webhook is authentic and was not tampered with.
How It Works
- AudioSpliter computes
HMAC-SHA256(webhook_secret, raw_request_body) - The hex-encoded result is sent in the
X-AudioSpliter-Signatureheader - Your server recomputes the signature and compares
Your Webhook Secret
Find your webhook signing secret in the Dashboard under Settings > Webhooks. It starts with whsec_.
Verification Examples
Node.js
const crypto = require('crypto');
function verifyWebhookSignature(req, secret) {
const signature = req.headers['x-audiospliter-signature'];
const body = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(body, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
}
// Express middleware
app.post('/webhooks/audiospliter', express.json(), (req, res) => {
const isValid = verifyWebhookSignature(req, process.env.WEBHOOK_SECRET);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook
const { event, jobId, data } = req.body;
console.log(`Received ${event} for job ${jobId}`);
res.status(200).json({ received: true });
});
Python
import hmac
import hashlib
def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature)
# Flask example
@app.route('/webhooks/audiospliter', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-AudioSpliter-Signature')
is_valid = verify_webhook_signature(
request.get_data(),
signature,
os.environ['WEBHOOK_SECRET'],
)
if not is_valid:
return jsonify({'error': 'Invalid signature'}), 401
data = request.get_json()
print(f"Received {data['event']} for job {data['jobId']}")
return jsonify({'received': True}), 200
PHP
function verifyWebhookSignature(string $payload, string $signature, string $secret): bool {
$expected = hash_hmac('sha256', $payload, $secret);
return hash_equals($expected, $signature);
}
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_AUDIOSPLITER_SIGNATURE'] ?? '';
$secret = getenv('WEBHOOK_SECRET');
if (!verifyWebhookSignature($payload, $signature, $secret)) {
http_response_code(401);
echo json_encode(['error' => 'Invalid signature']);
exit;
}
$data = json_decode($payload, true);
// Process webhook...
Security Best Practices
- Always verify signatures before processing webhooks
- Use timing-safe comparison functions to prevent timing attacks
- Store the webhook secret in environment variables, not in code
- Use HTTPS for your webhook endpoint
- Reject replays by checking the timestamp is within 5 minutes