<< All versions
Skill v1.0.1
currentAutomated scan100/100tomgranot/hubspot-admin-skills/cleanup-deals
+2 new
──Details
PublishedAugust 1, 2026 at 08:11 AM
Content Hashsha256:a80b17a05a51782c...
Git SHAcb6a1e828482
Bump Typepatch
──Files
Files (1 file, 3.5 KB)
SKILL.md3.5 KBactive
SKILL.md · 91 lines · 3.5 KB
version: "1.0.1" name: cleanup-deals description: "Standardize deal pipelines, remove test deals, and address deals with missing amounts or close dates. Coordinates with Salesforce sync if applicable." license: MIT metadata: author: tomgranot version: "1.1" category: ongoing-maintenance
Cleanup Deals
Standardize deal data to make pipeline reporting accurate. Test deals, missing amounts, and stale opportunities distort forecasts and pipeline metrics.
Prerequisites
- A HubSpot private app access token (
HUBSPOT_ACCESS_TOKENin.env) withcrm.objects.deals.readandcrm.objects.deals.writescopes - Python 3.10+ with `uv`
- Knowledge of which deal pipelines are active and which are synced from Salesforce
Important: Salesforce Sync Considerations
If deals are synced from Salesforce:
- Do NOT delete or modify synced deals without coordinating with the Salesforce admin.
- Changes in HubSpot may sync back to Salesforce and cause data loss.
- Identify synced deals by checking for the
hs_salesforceopportunityidproperty.
Step-by-Step Instructions
Stage 1: Plan
Confirm with the user before starting:
- Which pipelines are in scope, and which are Salesforce-synced (hands off without coordination)?
- The staleness cutoff for closing abandoned deals (default: 90 days without activity).
Stage 2: Before
Pull deal metrics via the CRM Search API:
python
import os, requestsfrom dotenv import load_dotenvload_dotenv()TOKEN = os.environ["HUBSPOT_ACCESS_TOKEN"]BASE = "https://api.hubapi.com"HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}def deal_count(prop, operator):resp = requests.post(f"{BASE}/crm/v3/objects/deals/search", headers=HEADERS, json={"filterGroups": [{"filters": [{"propertyName": prop, "operator": operator}]}],"limit": 1,})resp.raise_for_status()return resp.json()["total"]no_amount = deal_count("amount", "NOT_HAS_PROPERTY")no_close = deal_count("closedate", "NOT_HAS_PROPERTY")
Record: total deals, deals per pipeline stage, deals missing amount, deals missing close date, stale deals (open with no activity in 60+ days).
Stage 3: Execute
- Delete test deals — search for deals with names containing "test", "demo", "sample", or with amount = $0 and no associated contacts.
- Address missing amounts — export deals without
amountand work with sales to fill in values or mark as lost. - Close stale deals — deals open with no activity in 90+ days should be reviewed with the deal owner. Set to "Closed Lost" if abandoned.
- Standardize pipeline stages — ensure all pipelines have consistent stage names and probability percentages.
- Remove unused pipelines — if a pipeline has zero active deals and is not in use, archive or delete it.
Stage 4: After
- Re-run the deal audit queries. Confirm:
- Test deals removed
- Missing amount count decreased
- Stale deal count decreased
- Check pipeline reports for accuracy.
Rollback
- Deleted deals can be restored from HubSpot's recycling bin within 90 days.
- Stage changes and property updates can be reverted manually but there is no bulk undo.
- For Salesforce-synced deals, check the Salesforce recycle bin as well.
Tips
- Establish a deal hygiene rule: deals without activity for 60 days get an automated reminder to the owner (build a simple workflow).
- Require
amountandclosedateas mandatory deal properties to prevent future gaps.