Verify a Callback
The vcr object on the SDK allows you to verify whether a callback that your application receives is from the Cloud Runtime platform. All requests made to your instance from the Cloud Runtime platform will include a JWT signed with your Vonage Application's private key in the Authorization header.
Important: If your application uses the VCR Subscription providers (Messages, Voice, or Conversation), webhooks are routed via the VCR callback router. In this case, the Authorization header only authenticates the callback router itself — it does not guarantee that the original event came from Vonage, or that the payload has not been tampered with in transit. To fully verify the origin of these webhooks, you must also validate the X-Vonage-Webhook-Auth-Token header as described below.
You can confirm whether this applies to your app by checking your webhook URL. If it begins with any of the following URLs, your app is receiving webhooks via the VCR callback router and you should follow the additional verification steps in this guide:
https://callback-router.euw1.runtime.vonage.cloud/https://callback-router.use1.runtime.vonage.cloud/https://callback-router.apse1.runtime.vonage.cloud/https://callback-router.apse2.runtime.vonage.cloud/
If you manually applied your webhook URLs to point directly to your public instance URL, then this does not apply.
Retrieve Your Vonage Webhook Secret
To validate the X-Vonage-Webhook-Auth-Token header, you will need your Vonage webhook secret.
- Log in to the Vonage API Dashboard.
- Navigate to your application settings.
- Locate the Webhook Secret (also referred to as the Signature Secret) under the security settings.
- Store this value securely in your application's environment variables (e.g. as
VONAGE_WEBHOOK_SECRET). Do not hardcode it in your source code.
Verify the Callback Router JWT (Authorization header)
Use vcr.verifyAuth() to confirm that the request was sent by the VCR callback router. This step remains valid and should be kept as a first layer of verification.
Method Signature:
vcr.verifyAuth(token: string)
Use verifyAuth in a middleware function. It will throw an error if the token is not valid.
// Express Example
const authMiddleware = (req, res, next) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ error: 'Missing Authorization header' });
}
try {
vcr.verifyAuth(token);
next();
} catch (error) {
return res.status(401).json({ error: error.message });
}
};
Verify the Vonage Origin Token (X-Vonage-Webhook-Auth-Token header)
For applications using the VCR callback router, you must additionally validate the X-Vonage-Webhook-Auth-Token header. This token is signed by Vonage and allows you to cryptographically confirm that the event genuinely originated from Vonage and has not been tampered with.
const jwt = require('jsonwebtoken');
const verifyVonageOrigin = (req, res, next) => {
const vonageToken = req.headers['x-vonage-webhook-auth-token'];
if (!vonageToken) {
return res.status(401).json({ error: 'Missing X-Vonage-Webhook-Auth-Token header' });
}
try {
// Verify the token using your Vonage Webhook Secret
jwt.verify(vonageToken, process.env.VONAGE_WEBHOOK_SECRET, { algorithms: ['HS256'] });
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid Vonage origin token: ' + error.message });
}
};
Not Using the VCR Callback Router?
If your application receives webhooks directly (i.e. your webhook URL does not begin with https://callback-router.euw1.runtime.vonage.cloud/), the Authorization header carries the original Vonage-signed JWT — issued by the Vonage platform, not by VCR.
In this case, you must validate the token using your Vonage Webhook Secret.