assign-unowned-contacts
关于
This skill automatically assigns owners to marketing contacts that currently have none, ensuring proper lead routing and accountability. It addresses reporting gaps by making all contacts visible in owner-based dashboards and integrates with routing systems like round-robin. Use it after basic data hygiene to maintain complete pipeline visibility and follow-up processes.
快速安装
Claude Code
推荐npx skills add TomGranot/hubspot-admin-skills -a claude-code/plugin add https://github.com/TomGranot/hubspot-admin-skillsgit clone https://github.com/TomGranot/hubspot-admin-skills.git ~/.claude/skills/assign-unowned-contacts在 Claude Code 中复制并粘贴此命令以安装该技能
技能文档
Assign Unowned Marketing Contacts
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.
Why This Matters
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.
Prerequisites
- Phase 1 hygiene and earlier Phase 3 enrichment processes completed
- Access to Contacts with permission to bulk edit owner assignments
- Approval from team leads before bulk assignment. This is a business decision, not just a technical one. Get sign-off on the assignment strategy before proceeding.
Interview: Gather Requirements
Before executing, collect the following information from the user:
Q1: Who should unowned contacts be assigned to?
- Examples: "Assign all to our Integration User", "Distribute across the sales team", "Assign to the Marketing Team user", "Assign to specific reps by territory"
- Default: No default -- this is a business decision that requires team lead approval
Q2: Should we use territory-based routing, round-robin, or a single catch-all owner?
- Examples: Territory-based (assign by geography or industry), round-robin (distribute evenly across active reps), catch-all (assign all to one user)
- Default: Catch-all to a single integration/service user as a temporary measure, with plans to implement proper routing later
Plan
- Identify all marketing contacts with no owner (before state)
- Decide on the assignment strategy (catch-all user vs. territory rules)
- Execute the bulk assignment
- Verify all marketing contacts have owners (after state)
Before State
Create the Unowned Marketing Contacts List
- Go to Contacts > Lists > Create list
- Select Active list
- Name:
CLEANUP: Unowned Marketing Contacts - Add filters:
- Marketing contact status > is any of > Marketing contact
- AND Contact owner > is unknown
- Save the list and note the count
Script Approach
import 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}")
Execute
Assignment Strategy Decision
Choose one of these approaches (requires team lead approval):
Option A: Catch-All User (Simplest)
- Assign all unowned contacts to a single integration/service user
- Pro: Fast, ensures 100% coverage immediately
- Con: One "owner" accumulates a large number of contacts; not meaningful for routing
- Best when: You plan to implement proper routing later and just need coverage now
Option B: Territory/Region Rules
- Assign based on contact geography, industry, or company size
- Pro: More meaningful ownership, better for sales follow-up
- Con: Requires a defined routing matrix and more complex execution
- Best when: You have established sales territories
Option C: Round-Robin
- Distribute evenly across active sales reps
- Pro: Fair distribution, immediate accountability
- Con: May assign contacts to reps who do not cover that segment
- Best when: Small team, all reps handle all segments
Bulk Assignment via UI
- Open the unowned marketing contacts list
- Click the checkbox in the table header to select all contacts on the page
- Click Select all X contacts to select across all pages
- Click Edit in the toolbar
- In the property dropdown, select Contact owner
- Search for and select the chosen owner
- Click Update
- Confirm the bulk edit
- For large numbers (5,000+), HubSpot processes in batches. This may take several minutes.
Bulk Assignment via API
# 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:
- Get owner IDs from the Owners API:
api_client.crm.owners.owners_api.get_page() - To find a specific owner by email: iterate through owners and match on
email - Batch update accepts up to 100 records per call
- Rate limit: 100 requests per 10 seconds
After State
Wait 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:
- The unowned marketing contacts list shows 0 contacts
- Re-run the before-state script — count should be 0
- Spot-check 5-10 contacts that were previously unowned — confirm they show the assigned owner
- Check owner-based dashboards/reports to confirm the previously invisible contacts now appear
Key Technical Learnings
- This is a business decision, not just a technical one. Always get approval from sales/marketing leadership on the assignment strategy before executing. Bulk-assigning contacts to the wrong people creates confusion and erodes trust.
- A catch-all user is a temporary solution. If you assign to a single integration user, plan a follow-up process to redistribute contacts to actual sales reps when proper routing is established.
- Pair with lead owner cleanup. Once proper routing is in place, revisit contacts under the catch-all user and reassign them to real owners.
- HubSpot bulk edit limits. For very large batches (10,000+), the UI bulk edit may time out. Use the API approach instead, which handles pagination and batching gracefully.
- New contacts need routing too. After this one-time cleanup, implement a workflow or lead rotation rule to automatically assign owners to new marketing contacts going forward.
GitHub 仓库
相关推荐技能
railway-docs
文档Railway Docs Skill可实时获取最新的Railway官方文档,确保回答的准确性。当开发者询问Railway功能特性、工作原理或分享docs.railway.com链接时,应优先使用此技能。它通过专门的LLM优化文档源提供最新信息,避免依赖过时记忆来回答技术问题。
n8n-code-python
文档该Skill为在n8n平台的Python代码节点中编写代码提供专家指导,特别适用于需要使用_input/_json/_node语法、Python标准库或了解n8n中Python限制的场景。它强调JavaScript应作为首选方案,仅当需要特定Python功能或对Python语法更熟悉时才使用Python。Skill提供了快速入门模板和关键注意事项,帮助开发者在n8n中高效编写Python代码。
archon
文档Archon Skill为开发者提供了基于RAG的语义搜索和项目任务管理功能,可通过REST API访问知识库。它支持文档搜索、网站爬取、文件上传和版本控制,适用于技术文档查询和项目管理场景。首次使用时需要配置Archon主机地址,建议在处理外部文档时优先使用该Skill。
n8n-code-javascript
文档这个Skill为n8n工作流中的JavaScript代码节点提供专业指导,涵盖数据处理、HTTP请求和日期操作等核心场景。它详细解释了如何正确使用n8n特有的`$input`/`$json`语法、`$helpers`工具以及DateTime对象,并包含关键的错误排查和模式选择建议。开发者通过该Skill能快速掌握Code节点的正确返回格式、数据访问方法和常见陷阱解决方案。
