Have you ever needed to combine dropdown options in a HubSpot property — especially a multi-select...
How to Track Property Changes in HubSpot
Overview
This guide shows how to track property changes in HubSpot—specifically how to store and view both the current and previous email address on a contact record. It covers three approaches depending on your HubSpot subscription and tools.
Option 1: Native HubSpot Property Change Tracking (Pro+)
If you have HubSpot Pro or Enterprise, you can track property changes using custom events.
Steps
- Go to Data Management → Events.
- Create a Custom Event.
- Select Track Object Changes.
- Choose the object (e.g., Contact).
- Select the property (e.g., Email).
- Set the trigger (e.g., when Email is known).
Limitation
- Only works if the property is visible to all users.
- If property visibility is restricted, it will not appear as an option.
Option 2: HubSpot Workflow + Custom Code (Recommended for Pro+)
This method stores the previous value in a separate property.
Step 1: Create a “Previous Email” Property
- Type: Email
- Recommendation: Restrict editing or keep hidden to prevent overwrites
Step 2: Build a Workflow
- Go to Automation → Workflows.
- Trigger:
- Property value changed → Email
- Enable re-enrollment
Step 3: Add Custom Code Action
- Requires Operations Hub Pro
- Use Node.js
- Purpose: Retrieve property history via API and extract the previous value
- Here's the code I used:
const axios = require('axios');
exports.main = async (event, callback) => {
const contactId = event.object.objectId;
const token = process.env.accessToken;
try {
const response = await axios.get(
`https://api.hubapi.com/crm/v3/objects/contacts/${contactId}?propertiesWithHistory=email`,
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
}
);
const history =
response.data?.propertiesWithHistory?.email || [];
history.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
const previousValue =
history.length > 1 ? String(history[1].value ?? '') : '';
callback({
outputFields: {
previous_email: previousValue
}
});
} catch (err) {
console.error('Error fetching property history:', err?.message || err);
callback({
outputFields: {
previous_email: ''
}
});
}
};
Key requirements:
- Private access token (via HubSpot service key)
- Scope:
contacts.read - Pass contact ID into the script
- Output: previous email value
Step 4: Update Contact Record
- Action: Edit Record
- Set:
- Property: Previous Email
- Value: Output from custom code step
Result
- Current email = Email property
- Previous email = stored in custom property
- Can be used in lists, segments, and reporting
Option 3: Zapier (If You Don’t Have Ops Hub Pro)
This replicates the same logic using Zapier.
Zap Structure
Step 1: Trigger
- App: HubSpot
- Event: Contact Property Change
- Property: Email
Step 2: API Request
- Use HubSpot API via Zapier
- Endpoint: Contact with
propertiesWithHistory - Include internal property name (e.g.,
email)
Step 3: Extract Previous Value
- Use Formatter → Utilities → Pick from List
- Select index:
0= current value1= previous value
Step 4: Update Contact
- Action: Update Contact
- Set:
- Previous Email = extracted value
Result
- Same outcome as workflow method without custom code
Creating a Segment or List
To view changes:
- Create a list or segment
- Filters:
- Email has been updated in last X days
- Email is known
- (Optional) Previous Email is known to exclude first-time entries
This allows side-by-side comparison of current vs. previous values.
Option 4: Export Property History
If you only need periodic visibility:
- Go to Settings → Properties
- Find the property (e.g., Email)
- Click More → Export Property History
Output
- CSV or Excel file
- Includes all historical values across records
Key Takeaways
- Best native option: Custom events (Pro+)
- Most flexible: Workflow + custom code
- No Ops Hub Pro: Use Zapier
- Quick audit: Export property history
When to Use Each Method
| Scenario | Best Option |
|---|---|
| Simple tracking (no restrictions) | Custom Events |
| Need stored previous value | Workflow + Custom Code |
| No Ops Hub Pro | Zapier |
| One-time analysis | Export |
Final Notes
- Property visibility affects tracking capabilities
- Always store historical values in a separate property
- Use lists or segments to make data actionable
Bye for now.