Step 3: Webhook Verification

The following steps will describe how to optionally verify that a webhook request originated from Yext (and not a potentially malicious third party).

Before You Start

Check for the “Configure Security” button on the Webhooks page in your Developer Console. If you don’t see this button, reach out to your Client Success Manager or Yext Support so we can make sure this feature is enabled in your account.

We will provide you with a Signing Secret that is unique to your app. We’ll also include an X-Yext-Signature header to all our webhook requests, which will be the hash of the request’s body using the Signing Secret. Upon receipt of the request, you’ll use your Signing Secret to hash the request body. If the result matches the X-Yext-Signature header, you’ll know the request came from Yext.

How to Verify a Request

For the purpose of this exercise, we’ll assume you’ve enabled a webhook that sends a request whenever an entity is created or modified.

  1. Obtain the ‘X-Yext-Signature’ header from the incoming webhook request yext_signature = request.headers[‘X-Yext-Signature’]>> 2eb9d011edb8063d3a2df8057ae772bca7cf6c9d761afcf39dbeea0d810e182b
  2. Extract the body from the incoming webhook request

     request_body = request.body():
     {
      "meta": {
         "eventType": "ENTITY_UPDATED",
         "uuid": "14dec63a-80f3-4aef-8dbc-d39830396fa7",
         "timestamp": 1555090463175,
         "accountId": "2369309",
         "actor": "YEXT SYSTEM",
         "appSpecificAccountId": "50d8bc38a506e9bdba9fcaf103d6811b8212e0d3"
       },
       "entityId": "5600633438974399303",
       "primaryProfile": {
         "address": {
           "line1": "1 Madison Ave",
           "city": "New York",
           "region": "NY",
           "postalCode": "10010",
            "countryCode": "US"
         },
         "addressHidden": false,
          "name": "A location",
         "isoRegionCode": "NY",
         "timezone": "America/New_York",
         "yextDisplayCoordinate": {
           "latitude": 40.7410895,
           "longitude": -73.98750919999999
         },
         "yextRoutableCoordinate": {
           "latitude": 40.7411640951893,
           "longitude": -73.987830606551
         },
         "meta": {
           "accountId": "2369309",
           "uid": "3x7Dmg",
           "id": "5600633438974399303",
           "timestamp": "2019-04-12T17:34:23",
           "folderId": "0",
           "language": "en",
           "countryCode": "US",
           "entityType": "location"
         },
         "categoryIds": [
           "1857"
         ],
         "reviewGenerationUrl": "https://locationrater.com/tp/2zAkB5",
         "firstPartyReviewPage": "https://www.locationrater.com/survey/YS1sb2NhdGlvbi1uZXcteW9yay1uZXcteW9yay11cy0wM2UzOTc=",
         "timeZoneUtcOffset": "-04:00"
       },
       "languageProfiles": [],
       "changedFields": {
         "language": "en",
         "fieldNames": [
           "timezone"
         ]
       }
     }
  3. Pull your Signing Secret from the Yext Platform by clicking the “Configure Security” on the top right while configuring Webhooks for an app, and copy the Signing Secret. This example assumes signing_secret = df81b78b32e34680a1c87302bfdefa1a.

configure webhook security 4. Using HMAC SHA256 implemented in your preferred programming language, obtain a signature by hashing the request body using your Signing Secret as the key. You should use the hex digest of the hash. my_signature = hmac_sha256_hash(signing_secret, request_body) >>2eb9d011edb8063d3a2df8057ae772bca7cf6c9d761afcf39dbeea0d810e182b 5. Compare your calculated signature with the signature in the ‘X-Yext-Signature’ header on the request. If they match, the request came from Yext. If they do not match, please block the request. Feel free to reach out to API Support so we can investigate the inauthentic attempt.

Feedback