Authenticating Webhooks
To ensure the security and integrity of webhooks sent by the Send platform, each request includes specific headers that can be used to verify its authenticity.
X-Send-Signature
This header contains a signature generated by signing the timestamp (X-Send-Request-Timestamp
header) and the message body using an asymmetric SHA256 private key. This signature can be used to ensure that the webhook originated from the Send platform and has not been altered.
Verifying the Signature
To verify the signature, follow these steps:
- Stringify the webhook body.
- Prefix the stringified body with the value from the
X-Send-Request-Timestamp
header. - Use the provided public key to verify the signature.
An example of this implemented in Node.js is as follows:
const fs = require('fs');
const crypto = require('crypto');
const calculateStringToVerify = (webhookBody, timestampHeader) => {
const bodyString = JSON.stringify(webhookBody);
return `${timestampHeader}${bodyString}`;
}
const verifySignature = async (webhookBody, timestampHeader, signatureHeader) => {
// Create the string to verify
const stringToVerify = calculateStringToVerify(webhookBody, timestampHeader);
// Retrieve the public key
const publicKey = fs.readFileSync('./public-key.pem', 'utf8');
// Set up the verifier
const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(stringToVerify);
verifier.end();
// Verify the signature
const isVerified = verifier.verify(publicKey, signatureHeader, 'base64');
return isVerified;
}
If you intend to implement signature verification for incoming webhooks, please contact the Send team to obtain the current public key.
X-Send-Request-Timestamp
This header contains an ISO 8601 timestamp (UTC), indicating when the webhook was sent. To mitigate the risk of replay attacks, we recommend rejecting any webhook messages older than a threshold of your choosing.
This timestamp is also used in the signature calculation process described above.
Updated 22 days ago