Webhook URL validation failed in python

I’m getting the message “URL validation failed. Try again later.”

I selected the Authentication Header Option- Custom Header.

hash_for_validate = hmac.new(
    bytes(ZOOM_WEBHOOK_SECRET_TOKEN, 'utf-8'),
    bytes(request.data['payload']['plainToken'], 'utf-8'),

response = {'plainToken': request.data['payload']['plainToken'],
            'encryptedToken': hash_for_validate }
return Response(response, 200)

I checked my server logs. The request is coming to my server and responded with a 200 status code and the same response body.

Can you please solve this issue? I read all the topics of the same issue here and applied but doesn’t work!

@development8 ,

without handling the custom header at the moment, I’m using this to verify

import json
import hashlib
import hmac
from flask import Flask, request, jsonify
import os
from dotenv import load_dotenv

# Load environment variables from .env file, this will try to load these values from your .env file

# Your .env file should look something like this


secret_token = os.getenv("secret_token")

app = Flask(__name__)

def handle_request(request):

    if request.method == 'POST':
        # This block handles POST requests

        # Get the raw POST data from the request
        input_data = request.data

        # Decode the JSON data
            data = json.loads(input_data)
        except json.JSONDecodeError:
            return "Invalid JSON data", 400

        # Check if the event type is "endpoint.url_validation"
        if data.get('event') == 'endpoint.url_validation':
            # Check if the payload contains the "plainToken" property
            payload = data.get('payload', {})
            plain_token = payload.get('plainToken')
            if plain_token is not None:
                # Hash the plainToken using HMAC-SHA256
                encrypted_token = hmac.new(

                # Create the response JSON object
                response = {
                    "plainToken": plain_token,
                    "encryptedToken": encrypted_token

                # Set the response content type to JSON
                return response, 200
                # Payload is missing the "plainToken" property
                return "Payload is missing 'plainToken' property.", 400
            # Invalid event type
            return "Invalid event type.", 400

    elif request.method == 'GET':
        # This block handles GET requests

        # Handle your GET request logic here

        # For example, you can retrieve query parameters using request.args
        param1 = request.args.get('param1')
        if param1 is not None:
            return f"Received GET request with param1 = {param1}"
            return "Received GET request without param1"

        # Unsupported HTTP method
        return "Unsupported HTTP method.", 405