crm-data-quality
Find incomplete records, normalize field values in bulk, dedupe with `hubspot objects merge`, and audit custom properties. Builds on `bulk-operations` for JSONL piping and dry-run/digest/confirm.
By hubspot · 1,364 installs
npx skills add hubspot/agent-cli-skills --skill crm-data-quality
Source repository · Upstream listing
Read bulk operations/SKILL.md first — JSONL piping, batch read, pagination, and dry run/digest/confirm gating apply to every command below.
Property discovery
Don't guess property names. List them:
Same for type companies , deals , or any custom type ( hubspot objects types ).
1. Find incomplete records
!name = NOT HAS PROPERTY (missing or empty). Bare name = HAS PROPERTY. Within one filter , chain with AND ; multiple filter flags are OR'd.
For 100 results, use the pagination loop from bulk operations .
2. Normalize field values
Search → reshape with jq → pipe into update . objects update is irreversible, so dry run first — the dry run → digest → confirm flow is required at every row count, not just 100 ( bulk operations covers it end to end). Reshape patterns: bulk operations/resources/json patterns.md .
3. Dedupe with hubspot objects merge
Secondary is folded into primary and deleted. Irreversible. Dry run/digest/confirm gating applies.
Bulk: pipe JSONL {"primary":"...","secondary":"..."} on stdin (omit primary / secondary ).
Pagination required. objects search caps at 100 rows per call and jq s slurps a single stream into memory — running the snippet below against a raw search will silently miss every duplicate that crosses a page boundary. Collect the full set first with the pagination loop from bulk operations/SKILL.md (write to /tmp/contacts.jsonl ), then dedupe from the file:
Lift the digest/confirm from the preview line at any size — select(.digest != null) ; for a batch the confirm is the pair count ( .target.id ), and mutation kind is BulkData only above the 100 row threshold ( RecordMutation at or below it, but the digest is present either way). Re pipe the same producer with digest / confirm (see bulk operations ).
4. Audit properties
hubspot properties list (and get , batch read ) emits {name, label, type, fieldType, groupName, optionsDisplay} per row. Enum option values are exposed via properties options list — no need to read them off a live record or the UI.
Enum options — list and manage ( properties options , v0.11.0)
HubSpot defined properties with read only options reject options create / update / delete before the API is called.
Recovery
Merge is irreversible. After any merge, hubspot history since 1h captures the audit trail. If wrong direction, restore the secondary from the UI's recycle bin.