Webhook Signature Verification
This explains how to verify webhooks requests being sent from Luxury Presence.
Overview
This guide explains how to use the Luxury Presence Webhooks API. The Webhooks API can be used to subscribe to receive real-time Lead Activity events originating from actions taken on your Luxury Presence Websites.
Setup
See our documentation Webhooks API reference for listing, creating and deleting webhook subscriptions.
Receiving requests
All outbound webhook requests from webhook-lambda include HMAC-SHA256 signatures to ensure authenticity and integrity. Recipients should verify these signatures before processing webhook payloads.
The signature headers sent in the requests can be used to verify the origin of these requests as coming from Luxury Presence. See the section below for more information.
Signature Headers
Each webhook request includes the following headers:
x-lp-signature: The HMAC-SHA256 signature in hexadecimal formatx-lp-timestamp: Unix timestamp (in milliseconds) when the signature was generatedx-lp-signature-version: Signature algorithm version (currently "v1")
Signature Generation
The signature is generated using the following process:
- Create a string to sign by concatenating:
timestamp + url + JSON.stringify(payload) - Generate HMAC-SHA256 signature using your shared secret
- Convert the signature to hexadecimal format
Payload format
Currently, we only support Lead activity sync through webhooks. See Webhook Events for more information on what action triggers each activity type. Payload follows the example structure:
{
"eventName": "leads",
"companyId": "17g498eh-5b11-4d1c-8448-cb06ef213730",
"data": {
"leadId": "1d53e414-c8ad-49b8-9e23-2046f846d3d9",
"leadEmail": "[email protected]",
"leadFirstName": "Fluffy",
"leadLastName": "Trang",
"leadPhoneNumber": "(718) 555-5555",
"leadSource": "HOME_SEARCH",
"leadOrigin": "HOME_SEARCH",
"activityType": "ADD_FAVORITE",
"activityListingId": "b8fb82d6-03f4-42f3-ab57-526493b60949",
"activityAction": "ADD_FAVORITE",
"activityMessage": "",
"activityListingMlsId": "RLS30036941",
"activityListingAddress": "52 JANE Street 20",
"activityListingCity": "New York City",
"activityListingState": "NY",
"activityListingZip": "10014",
"activitySourceUrl": "p-110e844c-6254-4378-a176-f04ed117be61.staging.presencepreview.site/home-search/listings/b8fb82d6-03f4-42f3-ab57-526493b60949",
"assignedAgents": [
\{
"firstName": "",
"lastName": "",
"email": "[email protected]",
"mlsAgentId": ""
}
],
"assignedAgent": {
"firstName": "",
"lastName": "",
"email": "[email protected]",
"mlsAgentId": ""
},
"isNewLead": false,
"newPhoneNumber": false,
"companyName": "The Aster Group",
}
}Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(url, timestamp, signature, payload, secret) {
// Recreate the string that was signed
const stringToSign = timestamp + url + JSON.stringify(payload);
// Generate expected signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(stringToSign)
.digest('hex');
// Compare signatures using timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}Updated 6 months ago
