Install any skill in seconds. Free to start, no credit card required.
Get Started Free →jeremylongshore/hubspot-contact-dedup
Deduplicate HubSpot contacts at production scale — surviving import storms, wrong-winner merges, fuzzy-match blind spots, association orphans, rate-limit exhaustion, and silent merge failures on conflicting lifecycle or opt-out status.
Passed 20 of 23 test cases with the skill, and 11 of 23 without it.
and 11 more in the full report
10 fixed11 passed either way3 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 10 test cases the skill fixed. Same model, same prompt, with and without the skill.
We are setting up a HubSpot private app token for an automated pipeline that reads contact details, merges duplicates, and fixes deal associations. Which four specific OAuth scopes must be assigned to this token?
| Checked | Without skill | With skill |
|---|---|---|
| Includes read and write scopes for contacts. | Passed | Passed |
| Includes read and write scopes for associations. | Missed | Passed |
The instructions your model reads when the skill loads.
Merge duplicate contacts in HubSpot and operate that process in production, at scale, without data loss. This is not a one-click cleanup guide — it is the logic your pipeline runs when a sales ops team imports 80,000 leads from a tradeshow CSV that already exist in the CRM, when a merge destroys the "winner" contact's email history, when a fuzzy match on "Jon" vs "John" leaves a six-figure deal associated to a ghost record, and when on-call discovers that 40,000 contacts were merged without checking opt-out flags.
The six production failures this skill prevents:
POST /crm/v3/objects/contacts/merge requires a primaryObjectId. Picking the wrong one demotes the older contact's full activity timeline — calls, emails, form submissions — to the discarded record's history.hs_email_optout=true overriding the primary's opted-in status. HubSpot's "most recently updated value wins" rule is wrong for compliance flags.Authenticate with a private app token (pat-na1-*) or OAuth access token. Pass it on every request:
Authorization: Bearer {your-token}
Required scopes: crm.objects.contacts.read, crm.objects.contacts.write, crm.associations.read, crm.associations.write. See the hubspot-auth skill for token caching, OAuth refresh, and scope-drift detection.
requests, phonenumbers, rapidfuzz) for the full pipelinejq for shell examplesFind exact duplicates by email using the search API. Never pull all contacts into memory for comparison — use the search endpoint with specific filter values.
test cases passed, vs 11 / 23 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.