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.
- Obtain the ‘X-Yext-Signature’ header from the incoming webhook request
yext_signature = request.headers[‘X-Yext-Signature’]>> 2eb9d011edb8063d3a2df8057ae772bca7cf6c9d761afcf39dbeea0d810e182b
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" ] } }
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
.
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.