I’m trying to set up a separate server-to-server app for production, distinct from my staging environment. Everything is working perfectly in staging, but in production, the webhook URL validation keeps failing—even though I’m following the exact same process.
When I attempt to validate the production URL:
https ://api-dev.mastersunion.in/api/v1/zoom/zoomReport
I receive the error: “URL validation failed. Try again later.”
To troubleshoot, I tried using ngrok to inspect incoming requests on localhost. Surprisingly, any ngrok URL I use gets validated instantly, without even hitting my backend. That suggests the validation process isn’t actually triggering on my server during this step.
So my questions are:
How exactly is the URL validation being done on your end?
Is there some kind of allowlist/denylist for domains during validation?
If so, how can I ensure my production domain (api-dev.mastersunion.in) is whitelisted?
If not, what else could be causing the validation to silently fail for this specific URL?
Any help or clarification would be much appreciated!
for (const hostDetail of hostDetails) {
const hashForVerify = crypto.createHmac('sha256', hostDetail.webhookSecretToken)
.update(message)
.digest('hex');
const signature = `v0=${hashForVerify}`;
console.log(req.body.event, "req.body.event");
if (req.headers['x-zm-signature'] === signature) {
if (req.body.event === 'endpoint.url_validation') {
const hashForValidate = crypto.createHmac('sha256', hostDetail.webhookSecretToken)
.update(req.body.payload.plainToken)
.digest('hex');
response = {
message: {
plainToken: req.body.payload.plainToken,
encryptedToken: hashForValidate
},
status: 200
};
console.log(response.message, hostDetail,"hosttttttt");
res.status(response.status);
res.json(response.message);
} else if (req.body.event === 'meeting.ended') {
const id = req.body.payload.object.id;
await zoomService.zoomAttendance(id, hostDetail);
response = { message: 'Meeting end event processed successfully.', status: 200 };
console.log(response.message);
res.status(response.status);
res.json(response);
} else {
response = { message: 'Authorized request to Zoom Webhook sample.', status: 200 };
console.log(response.message);
res.status(response.status);
res.json(response);
}
} else {
response = { message: 'Unauthorized request to Zoom Webhook sample.', status: 401 };
console.log(response.message);
res.status(response.status);
res.json(response);
}
}