Fix · HubSpot
Find which HubSpot custom properties are safe to retire
The problem
“Even if the team agrees they only use one, that doesn’t settle what still depends on the others.”
Short answer: Start from the data, not from asking people. For each custom property, count how many records have a value (search with HAS_PROPERTY), then read the property history on the most recently changed records to see when it was last written and by what: a person, a workflow, an import or an integration. Anything an integration still writes needs an owner before you touch it. Everything else gets renamed, hidden and archived after a reporting cycle, never deleted on day one.
HubSpot's Used in tab shows workflows, lists and forms, but it doesn't show an outside system writing through the API. Property history does, because every value carries a source. The script pulls that for a sample of records per property, scores each one RETIRE_CANDIDATE, REVIEW or KEEP, and lists look-alike fields (such as demo date and demo booked date) as merge pairs.
Download
- property_audit.py: the read-only audit script (CSV and Markdown report)
- README.md: setup, scoring rules and limits
- hubspot-property-retirement-audit.zip: everything, including sample data and the offline test
Step by step
1. Create a read-only private app
In HubSpot create a private app with read scopes for the object you are auditing and its property schemas. Save the token as HUBSPOT_TOKEN.
2. Try it offline
The sample has eight fake deal properties, including three overlapping date fields.
python3 property_audit.py --object deals --mock sample/ --out out --now 2026-11-053. Run it on your portal
It lists custom properties (GET /crm/v3/properties/deals), counts values with a HAS_PROPERTY search, and reads history with propertiesWithHistory on the 20 most recently modified records that have a value. 429s are retried.
python3 property_audit.py --object deals --sample-size 20 --out out4. Read the report
Open out/property_audit.md. RETIRE_CANDIDATE means very low fill or nothing written in a year, with no integration or API writes in the sample. REVIEW means an integration or the API still writes it, or low fill but recent writes. Look at those first.
5. Trace any integration
For REVIEW rows, the source id in property history usually names the app. Match it to Connected apps and Private apps in settings. Ask whoever pays for the Zapier or middleware account if nobody knows who built it.
6. Retire safely
Check the Used in tab and the archive panel by hand. Export the values with record IDs. Rename the property with DEPRECATED_ at the front and hide it from forms. Wait one reporting cycle, then archive (HubSpot lets you restore archived properties for 90 days).
What this does not cover
- It cannot see workflows, lists, forms or reports that use a property. The Used in tab is still a manual step.
- Last written date and sources come from a sample of records, so an integration that writes rarely may not show up.
- Tested offline against sample data only, not against a live portal. The verdict is a ranking, not permission to delete.
Want this done for you?
Kingdom of Kumar runs it for $500/month, first automation live in 48 hours. Claude + Grok Bot + $500/month (my fee). Email me the task you hate doing every week.