hubspot-audit
Run a full, read-only HubSpot portal audit covering both the marketing and sales sides: database, deliverability, engagement, owners, pipelines, deal quality…
Skill by tomgranot
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/tomgranot-hubspot-audit
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend, security, marketing, sales
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 2
api.hubapi.com· found in codecodeload.github.com· found in install command
Files it touches
~/.claude/skills/hubspot-audit
What's inside
- Skill name
hubspot-audit- Description
- Run a full, read-only HubSpot portal audit covering both the marketing and sales sides: database, deliverability, engagement, owners, pipelines, deal quality, and follow-up. Grades each dimension and prescribes the skills that fix what it finds. Use when starting a CRM cleanup, onboarding a new portal, or running a quarterly health check.
- License
- MIT
- Metadata
- author: tomgranot · version: 2.0 · category: audit-planning
- Instructions
- 188 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Files (2)
- SKILL.md
- audit_portal.py · scripts/
SKILL.md (first lines)
# HubSpot Portal Audit
Run a full diagnostic audit of a HubSpot portal. One read-only script collects the metrics, grades each dimension, and writes a report that opens with a prioritized list of skills to run.
## One Engine, Three Lenses
The audit is a single engine (`scripts/audit_portal.py`) with a `--scope` flag. Every dimension is tagged **shared**, **marketing**, or **sales**:
| Scope | Runs | Report | Entry point |
|-------|------|--------|-------------|
| `full` (default) | shared + marketing + sales | `reports/hubspot-audit-{date}.md` | this skill |
| `marketing` | shared + marketing | `reports/hubspot-marketing-audit-{date}.md` | `/hubspot-marketing-audit` |
| `sales` | shared + sales | `reports/hubspot-sales-audit-{date}.md` | `/hubspot-sales-audit` |
The shared dimensions run under every scope, so a marketing audit and a sales audit of the same portal agree on the numbers they have in common. Use this skill when you own the whole portal; hand a team the scoped audit when they only own one side.
## Setup
1. **Get the API token.** Check `.env` for `HUBSPOT_ACCESS_TOKEN`. If it is not set, ask the user for a read-scoped HubSpot access token and store it in `.env`:
```
HUBSPOT_ACCESS_TOKEN=pat-na1-xxxxxxxx
```
2. **Run the audit.** The script carries PEP 723 inline metadata and runs with [`uv`](https://github.com/astral-sh/uv), which resolves its dependencies automatically:
```bash
uv run scripts/audit_portal.py # full
uv run scripts/audit_portal.py --scope marketing
uv run scripts/audit_portal.py --scope sales
```
The script creates `reports/` if needed and writes a markdown report plus a JSON twin (same name, `.json`) for other skills to read.
## Audit Dimensions
### Shared (every scope)
| Dimension | What it measures | Graded on |
|-----------|------------------|-----------|
| Database Size | Total contacts, companies, deals | not graded |
| Owner Health | Unowned contacts and companies; records still owned by deactivated owners | unowned + orphaned contacts |
| Company Data Completeness | Companies missing domain, industry, country | missing domain |
| Duplicates | Flagged for `/merge-duplicate-companies` (exact scans need full pagination) | not graded |
### Marketing
| Dimension | What it measures | Graded on |
|-----------|------------------|-----------|
| Email Deliverability | Marketing contacts, hard bounces, global unsubscribes, 3+ bounces, never emailed | hard bounces + unsubscribes |
| Contact Data Completeness | Contacts missing email, lifecycle stage, company, industry, country, job title | missing lifecycle stage |
| Engagement Health | Opened in 90 days, never opened, last open over a year ago, current customers at the wrong lifecycle stage | never opened |
| List, Workflow & Form Health | Total lists, workflows (active vs inactive), forms | not graded |
### Sales
| Dimension | What it measures | Graded on |
|-----------|------------------|-----------|
| Pipeline Configuration | Pipelines, deals per pipeline, empty pipelines, pipelines with more than 10 open stages | empty + bloated pipelines |
| Deal Data Quality | Open deals missing amount, close date, owner, or an associated contact; closed-lost deals with no loss reason | missing amount + close date |
| Pipeline Hygiene & Velocity | Open deals with no activity in 60+ days, close dates in the past, no next activity; 90-day win rate | stale + past-due deals |
| Sales Ownership & Handoff | Open deals owned by deactivated owners; SQL/Opportunity contacts with no owner; Opportunity contacts with no deal | orphaned deals + unowned sales-stage contacts |
| Activity & Follow-up | Open and overdue tasks; leads and unowned leads | overdue tasks |
Thresholds (stale-deal window, win-rate window, stage limit) are in the `# --- Configuration ---` block at the top of the script.
## API Technical Notes
- **Null checks**: use the `NOT_HAS_PROPERTY` operator to find records where a property has never been set. HubSpot stores "never happened" as an absent property, not as 0 or an empty string.
- **Counting**: the script counts with the Search API's `total`, which is exact even past the 10,000-result paging cap. Paging through more than 10,000 *records* requires segmenting the query.
- **Search limits**: 5 requests per second, 5 filter groups per query, 6 filters per group. The script paces itself under the rate limit.
- **n/a is not zero**: when the token cannot read an object (missing scope, or the hub is not purchased), the row shows `n/a` and the dimension grades `?`. Fix the scope and re-run rather than reading it as clean.
- **Deactivated owners**: the Owners API only returns them with `archived=true`.
- **Open deals**: filtered with `hs_is_closed = false`, which works across every pipeline regardless of stage names.
- **Marketing contact status**: `hs_marketable_status` is readable and filterable but **read-only via API**.
- **Not available by API**: per-email open/click rates come from the marketing email statistics API or the UI; forecast accuracy and time-in-stage come from the UI's forecast and pipeline reports.
## Scripts
Script paths are relative to this skill's directory. Run them from your project directory so `.env`, `data/`, and `reports/` resolve there: prefix each path with wherever this skill is installed (`skills/hubspot-audit/` in a clone of the repo).
| Stage | Script | Run with |
|-------|--------|----------|
| Audit (read-only) | [`scripts/audit_portal.py`](./scripts/audit_portal.py) | `uv run scripts/audit_portal.py [--scope full\|marketing\|sales]` |
If a portal needs a check the script does not cover, add a dimension function with the right tag rather than writing a separate one-off script. The offline tests in `tests/test_audit_portal.py` run against a fake API and need no portal.
**MCP note:** if HubSpot's MCP server is connected (see `/connect-hubspot-mcp`), use it for spot-checks while auditing: opening sample records behind a suspicious count is faster than writing one-off queries. The counting queries themselves stay in the script for reproducibility.
## Grading Rubric
| Grade | Meaning | Criteria |
|-------|---------|----------|
| A | Healthy | < 5% of records affected |
| B | Minor issues | 5-15% of records affected |
| C | Needs attention | 15-30% of records affected |
| D | Significant problems | 30-50% of records affected |
| F | Critical | > 50% of records affected |
| ? | Unknown | The metric could not be read |
The script grades each dimension on the metric named in the tables above. Treat the grade as a starting point: a portal with 40 open deals and 3 stale ones is in a different place than one with 4,000 and 300, even though both grade B.
## Report Structure
```markdown
# HubSpot CRM Audit Report
**Date:** YYYY-MM-DD
**Scope:** full
## Executive Summary
| Dimension | Lens | Grade |
|---|---|---|
| Owner Health | shared | C |
| Email Deliverability | marketing | D |
| Deal Data Quality | sales | B |
## Prescription
| # | Skill | Why | Records | Priority |From TomGranot/hubspot-admin-skills, MIT.
More from TomGranot/hubspot-admin-skills
- 0.675score
sandbox-self-test
tomgranot
Verify the entire toolkit against a disposable HubSpot developer test account or sandbox that you bring: seed synthetic fixtures, run every scripted skill's…
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
create-icp-tiers
tomgranot
Classify companies into Ideal Customer Profile (ICP) tiers based on firmographic data (industry + employee count).
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
lifecycle-progression-workflow
tomgranot
Build workflows to automate contact progression through the sales funnel: Lead to MQL to SQL to Opportunity to Customer.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
suppress-global-unsubscribes
tomgranot
Identify and suppress globally unsubscribed contacts to ensure legal compliance and reduce billing.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
new-contact-hygiene-workflow
tomgranot
Build a HubSpot workflow that auto-enriches and stages new contacts upon creation.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
merge-duplicate-companies
tomgranot
Identify duplicate company records by domain and name, export audit CSVs for review, and guide merging.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
delete-no-email-contacts
tomgranot
Delete contacts with no email address from a HubSpot CRM instance.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
bounce-monitoring-workflow
tomgranot
Build a workflow to protect sender reputation through automated bounce monitoring.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
build-smart-lists
tomgranot
Create foundational segmented lists for marketing and sales operations via the Lists API, plus advanced UI-built segments: a master sendable list, ICP-based…
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
cleanup-deals
tomgranot
Find past-due, stale, incomplete, unexplained-loss, and likely test deals, then route each owner's flagged deals to them as one review task.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
assign-unowned-contacts
tomgranot
Assign an owner to marketing contacts that have no owner.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
engagement-suppression-workflow
tomgranot
Build a two-tier sunset workflow that re-engages dormant contacts before suppressing them.
SkillAFreshness: A★ 77Claude Code +9
Signals
- Stars
- 77
- Forks
- 18
- Open issues
- 0
- Last commit (this folder)
- Oct 12, 2026 (15 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- Version
- 2.0
- License
- MIT
- Website
- hubspot.granot.io
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from tomgranot
- 0.675score
sandbox-self-test
tomgranot
Verify the entire toolkit against a disposable HubSpot developer test account or sandbox that you bring: seed synthetic fixtures, run every scripted skill's…
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
merge-duplicate-companies
tomgranot
Identify duplicate company records by domain and name, export audit CSVs for review, and guide merging.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
lifecycle-progression-workflow
tomgranot
Build workflows to automate contact progression through the sales funnel: Lead to MQL to SQL to Opportunity to Customer.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
suppress-global-unsubscribes
tomgranot
Identify and suppress globally unsubscribed contacts to ensure legal compliance and reduce billing.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
assign-unowned-contacts
tomgranot
Assign an owner to marketing contacts that have no owner.
SkillAFreshness: A★ 77Claude Code +9 - 0.672score
new-contact-hygiene-workflow
tomgranot
Build a HubSpot workflow that auto-enriches and stages new contacts upon creation.
SkillAFreshness: A★ 77Claude Code +9
Cite this page
hubspot-audit skill. Agent Mart. https://agentmart.dev/skills/tomgranot-hubspot-audit (last updated 2026-10-24)