From hubspot-admin
Convert inconsistent country and state/region formats to standardized values across contacts and companies. Ensures geographic segmentation works reliably.
npx claudepluginhub tomgranot/hubspot-admin-skillsThis skill uses the workspace's default tool permissions.
Convert inconsistent geographic formats (e.g., "US", "USA", "U.S." vs "United States"; "NY" vs "New York") to a single standard format across all contact and company records.
Enrich missing geographic data (country, state, city) on contacts and companies using HubSpot workflows, external data providers, or IP-based geolocation.
Syncs contacts, deals, and campaigns to/from Salesforce, HubSpot, Zoho, or Pipedrive with deduplication, field mapping, compliance checks, and bi-directional support. Use for automated CRM data transfers avoiding manual imports.
Implements HubSpot GDPR/CCPA contact deletion, data export for DSAR, and privacy ops using CRM APIs. For compliance in integrations.
Share bugs, ideas, or general feedback.
Convert inconsistent geographic formats (e.g., "US", "USA", "U.S." vs "United States"; "NY" vs "New York") to a single standard format across all contact and company records.
Inconsistent geo values break geographic segmentation. A list filtering for "United States" will miss contacts labeled "US" or "USA". For B2B companies running region-specific campaigns or reporting by geography, this means inaccurate audience sizes and missed contacts.
Before executing, collect the following information from the user:
Q1: What format do you prefer for country values -- full names (United States) or ISO codes (US)?
Q2: Do you have a Salesforce or other CRM integration that requires a specific format?
import os
from hubspot import HubSpot
from dotenv import load_dotenv
load_dotenv()
api_client = HubSpot(access_token=os.getenv("HUBSPOT_API_TOKEN"))
# Check for common country variants
variants = ["US", "USA", "U.S.", "U.S.A.", "America"]
for variant in variants:
result = api_client.crm.contacts.search_api.do_search(
public_object_search_request={
"filterGroups": [{
"filters": [{
"propertyName": "country",
"operator": "EQ",
"value": variant
}]
}],
"limit": 0
}
)
if result.total > 0:
print(f"Contacts with country = '{variant}': {result.total}")
# Repeat for companies
for variant in variants:
result = api_client.crm.companies.search_api.do_search(
public_object_search_request={
"filterGroups": [{
"filters": [{
"propertyName": "country",
"operator": "EQ",
"value": variant
}]
}],
"limit": 0
}
)
if result.total > 0:
print(f"Companies with country = '{variant}': {result.total}")
Record all variant counts as your baseline.
# Pattern: Build mapping table, search for each variant, batch update
COUNTRY_MAPPING = {
"US": "United States",
"USA": "United States",
"U.S.": "United States",
"U.S.A.": "United States",
"America": "United States",
"UK": "United Kingdom",
"GB": "United Kingdom",
"Great Britain": "United Kingdom",
# Add other mappings as discovered in your audit
}
STATE_MAPPING = {
"NY": "New York",
"CA": "California",
"TX": "Texas",
"FL": "Florida",
"IL": "Illinois",
"PA": "Pennsylvania",
"OH": "Ohio",
"GA": "Georgia",
"NC": "North Carolina",
"NJ": "New Jersey",
"VA": "Virginia",
"WA": "Washington",
"MA": "Massachusetts",
"AZ": "Arizona",
"CO": "Colorado",
"MD": "Maryland",
"MN": "Minnesota",
"MO": "Missouri",
"WI": "Wisconsin",
"CT": "Connecticut",
"OR": "Oregon",
"SC": "South Carolina",
"LA": "Louisiana",
# Add all 50 US states + territories as needed
}
# For each mapping:
# 1. Search for contacts with the variant value
# 2. Collect all matching contact IDs (paginate if > 100)
# 3. Batch update using crm.contacts.batch_api.update
# 4. Repeat for companies using crm.companies
API notes:
For each variant:
For companies, do the same from the Companies view using filters and bulk edit.
After standardizing existing data:
# Re-run the same variant checks from before state
variants = ["US", "USA", "U.S.", "U.S.A.", "America"]
for variant in variants:
result = api_client.crm.contacts.search_api.do_search(
public_object_search_request={
"filterGroups": [{
"filters": [{
"propertyName": "country",
"operator": "EQ",
"value": variant
}]
}],
"limit": 0
}
)
assert result.total == 0, f"Still have {result.total} contacts with '{variant}'"
print(f"Contacts with country = '{variant}': {result.total} (should be 0)")
Verification checklist: