From hubspot-admin
Assign an owner to marketing contacts that have no owner. Ensures every marketable contact has accountability for follow-up, proper lead routing, and accurate owner-based reporting.
npx claudepluginhub tomgranot/hubspot-admin-skillsThis skill uses the workspace's default tool permissions.
Assign an owner to all marketing contacts that currently have no owner. Unowned contacts create gaps in reporting, prevent proper lead routing, and mean no one is accountable for follow-up on marketing-generated responses.
Reassign contacts and companies from deactivated team members to active owners. Fully automated via the HubSpot Owners API and Batch Update API. Includes territory analysis for informed reassignment decisions.
Imports leads into CRMs like Salesforce, HubSpot, Zoho, Pipedrive from CSV, JSON, or manual entry with deduplication, lead scoring, validation, and consent tracking. Use for form submissions or bulk loads.
Automates Lemlist multichannel outreach: list/manage campaigns, enroll leads at scale with enrichment, add personalization variables, export data, handle unsubscribes via Composio MCP tools.
Share bugs, ideas, or general feedback.
Assign an owner to all marketing contacts that currently have no owner. Unowned contacts create gaps in reporting, prevent proper lead routing, and mean no one is accountable for follow-up on marketing-generated responses.
Marketing contacts without an owner are a blind spot. They receive campaigns but no one sees their responses. They appear in aggregate metrics but not in individual pipeline views. In owner-based dashboards and reports, they simply do not exist. For teams using round-robin or territory-based routing, unowned contacts bypass the entire system.
Before executing, collect the following information from the user:
Q1: Who should unowned contacts be assigned to?
Q2: Should we use territory-based routing, round-robin, or a single catch-all owner?
CLEANUP: Unowned Marketing Contactsimport os
from hubspot import HubSpot
from dotenv import load_dotenv
load_dotenv()
api_client = HubSpot(access_token=os.getenv("HUBSPOT_API_TOKEN"))
# Count unowned marketing contacts
result = api_client.crm.contacts.search_api.do_search(
public_object_search_request={
"filterGroups": [{
"filters": [
{
"propertyName": "hs_marketable_status",
"operator": "EQ",
"value": "true"
},
{
"propertyName": "hubspot_owner_id",
"operator": "NOT_HAS_PROPERTY"
}
]
}],
"limit": 0
}
)
print(f"Unowned marketing contacts: {result.total}")
Choose one of these approaches (requires team lead approval):
Option A: Catch-All User (Simplest)
Option B: Territory/Region Rules
Option C: Round-Robin
# Pattern for API-based assignment
# Useful for territory-based rules or when UI bulk edit times out
OWNER_ID = "your-owner-id" # Get from Owners API
# 1. Search for unowned marketing contacts (paginate through all)
# 2. Build batch update payload with hubspot_owner_id = OWNER_ID
# 3. Submit in batches of 100 via crm.contacts.batch_api.update
# For territory-based routing:
# 1. Search for unowned marketing contacts
# 2. For each contact, determine territory based on country/state/industry
# 3. Map territory to owner ID
# 4. Batch update with the appropriate owner per contact
API notes:
api_client.crm.owners.owners_api.get_page()emailWait 5-10 minutes for HubSpot to finish processing, then verify.
# Re-run the same search
result = api_client.crm.contacts.search_api.do_search(
public_object_search_request={
"filterGroups": [{
"filters": [
{
"propertyName": "hs_marketable_status",
"operator": "EQ",
"value": "true"
},
{
"propertyName": "hubspot_owner_id",
"operator": "NOT_HAS_PROPERTY"
}
]
}],
"limit": 0
}
)
print(f"Unowned marketing contacts: {result.total} (should be 0)")
Verification checklist: