Hubspot-admin-skills review-bounced-contacts
Weekly manual review of contacts with 3+ bounce events. Decide whether to delete or attempt recovery for each flagged contact. Prevents over-suppression while removing truly bad data.
install
source · Clone the upstream repo
git clone https://github.com/TomGranot/hubspot-admin-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TomGranot/hubspot-admin-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/review-bounced-contacts" ~/.claude/skills/tomgranot-hubspot-admin-skills-review-bounced-contacts && rm -rf "$T"
manifest:
skills/review-bounced-contacts/SKILL.mdsource content
Review Bounced Contacts
A weekly manual review process for contacts flagged with 3+ bounces. The bounce monitoring workflow auto-suppresses these contacts, but a human should decide whether to permanently delete or attempt recovery.
Prerequisites
- Bounce monitoring workflow active (run
first)/bounce-monitoring-workflow
custom property exists on contactsemail_health_flag- HubSpot API token in
(for scripted pre-filtering).env
Step-by-Step Instructions
Stage 1: Before — Pull the Review List
Use the HubSpot API to search for contacts where
email_health_flag is set:
from hubspot import HubSpot from hubspot.crm.contacts import PublicObjectSearchRequest api_client = HubSpot(access_token=os.getenv("HUBSPOT_API_TOKEN")) search = PublicObjectSearchRequest( filter_groups=[{ "filters": [{ "propertyName": "email_health_flag", "operator": "EQ", "value": "true" }] }], properties=["email", "firstname", "lastname", "company", "hs_email_bounce", "hs_email_hard_bounce_reason_enum", "lifecyclestage", "hubspot_owner_id"] ) results = api_client.crm.contacts.search_api.do_search(search)
Export results to a CSV for review.
Stage 2: Execute — Review Each Contact
For each flagged contact, check:
- Is the email domain active? Run a quick MX record lookup or visit the domain.
- Is this a known customer or high-value contact? Check lifecycle stage and deal history.
- What is the bounce reason? Hard bounce (invalid mailbox) vs. soft bounce (mailbox full, temporary error).
Decision matrix:
| Domain active? | High value? | Bounce type | Action |
|---|---|---|---|
| No | Any | Any | Delete |
| Yes | No | Hard | Delete |
| Yes | No | Soft | Keep suppressed, recheck next quarter |
| Yes | Yes | Hard | Attempt to find updated email |
| Yes | Yes | Soft | Keep suppressed, monitor |
Stage 3: After — Execute Decisions
- Delete contacts marked for deletion via the HubSpot UI or API batch delete.
- Clear the
on all reviewed contacts.email_health_flag - Log the review results (deleted count, kept count, recovery attempts) for the quarterly report.
Stage 4: Rollback
- Deleted contacts can be restored from HubSpot's recycling bin within 90 days.
- Contacts kept as suppressed can be restored to marketing status via a workflow or manual update in the UI.
Frequency
Run weekly, ideally Monday morning. Should take 5-15 minutes depending on volume. If volume exceeds 50 contacts per week, investigate the root cause (bad list source, form spam, etc.).