Skip to content
Agentmart
Submit a tool

enrich-company-name

Populate missing contact company name fields from associated company records using a HubSpot workflow with optional API backfill.

Skill by tomgranot

IndexedMIT★ 77
Write a review

Chalk Labs

Need help deploying enrich-company-name?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/tomgranot-enrich-company-name

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Populate missing contact company name fields from associated company records using a HubSpot workflow with optional API backfill. Ensures contacts inherit their company name for segmentation, personalization, and ICP classification.

Use cases: backend, sales, productivity

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Python package

Network hosts it talks to 2

  • api.hubapi.com · found in code
  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/enrich-company-name

What's inside

Skill name
enrich-company-name
Description
Populate missing contact company name fields from associated company records using a HubSpot workflow with optional API backfill. Ensures contacts inherit their company name for segmentation, personalization, and ICP classification.
License
MIT
Metadata
author: tomgranot · version: 1.1 · category: data-enrichment
Instructions
140 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts
  • Instructions call the network

Files (3)

  • SKILL.md
  • after.py · scripts/
  • before.py · scripts/

SKILL.md (first lines)

# Enrich Contact Company Name from Associated Company

Populate missing contact-level company name fields by copying the value from the associated company record. Uses a HubSpot workflow for ongoing enrichment and optionally an API backfill script for immediate results.

## Why This Matters

Contacts missing a company name cannot be matched to ICP-classified companies, break email personalization tokens, and are invisible to company-based segmentation. In a typical neglected CRM, 40-60% of contacts may be missing this field even though the vast majority have a company association.

## Prerequisites

- HubSpot Marketing Hub Professional or Sales Hub Professional (for Workflows)
- A HubSpot service key (`HUBSPOT_ACCESS_TOKEN` in `.env`; an existing legacy private app token also works) with contact read/write scopes (for the scripted stages)
- Python 3.10+ with [`uv`](https://github.com/astral-sh/uv)
- Phase 1 hygiene processes completed (invalid/deleted contacts removed first)
- **HubSpot auto-association enabled:** Settings > Objects > Companies > "Create and associate companies with contacts" toggle must be ON. This lets HubSpot automatically create company records from email domains and associate them.

## Scripts

Script paths are relative to this skill's directory. Run them from your project directory so `.env`, `data/`, and `reports/` resolve there: prefix each path with wherever this skill is installed (`skills/enrich-company-name/` in a clone of the repo).

| Stage | Script | Run with |
|-------|--------|----------|
| Before | [`scripts/before.py`](./scripts/before.py) | `uv run scripts/before.py` |
| After | [`scripts/after.py`](./scripts/after.py) | `uv run scripts/after.py` |

There is no execute script: the enrichment itself runs as a HubSpot workflow (see Execute below), which handles both the backlog and future contacts.

## Plan

1. Enable auto-association if not already on
2. Audit how many contacts are missing company name (before state)
3. Build a workflow that copies company name from the associated company record
4. Optionally run an API backfill script for immediate results
5. Verify enrichment results (after state)

## Before

Run the before-state audit to capture the baseline: `uv run scripts/before.py`

The core query it runs:

```python
resp = requests.post(f"{BASE}/crm/v3/objects/contacts/search", headers=HEADERS, json={
    "filterGroups": [{"filters": [
        {"propertyName": "company", "operator": "NOT_HAS_PROPERTY"},
    ]}],
    "limit": 1,
})
print(f"Contacts missing company name: {resp.json()['total']}")
```

**Manual approach:** Go to Contacts > filter by Company name > is unknown. Record the count.

Save the count. This is your baseline for measuring success.

## Execute

### Method 1: HubSpot Workflow (Recommended — Handles Backlog + Future)

1. Go to **Automation > Workflows > Create workflow**
2. Select **Contact-based > Blank workflow**
3. Name: `AUTO-ENRICH: Copy Company Name from Association`

**Enrollment trigger:**
- Contact property > Company name > **is unknown**

**Re-enrollment:**
- Enable re-enrollment when **associated company** changes. This is the safety net: if an association forms after the workflow already ran, the contact gets re-enrolled.

**Action 1: Delay 10 minutes**
- This delay is critical. When a new contact enters HubSpot, the auto-association engine needs time to parse the email domain, find or create a matching company, and create the association. Without this delay, the workflow checks for an association before one exists.

**Action 2: If/then branch**
- Condition: Associated company > Company name (or Name) > **is known**
- **YES branch:** Add a **Copy property** action:
  - Copy FROM: Company > Name
  - Copy TO: Contact > Company name
- **NO branch:** Leave empty (contact exits). These are typically contacts with personal email addresses (gmail, yahoo, etc.) where no company can be determined.

**Activate:**
- Click Review > Turn on
- When prompted, select **Yes, enroll existing contacts**. This enrolls the entire backlog.

### Method 2: API Backfill Script (Optional — Immediate Results)

Use this if you need the data populated immediately rather than waiting for workflow processing.

```python
# Pattern: fetch contacts missing company name,
# look up their associated company, copy the name.
# 1. POST /crm/v3/objects/contacts/search  (company NOT_HAS_PROPERTY)
# 2. POST /crm/v4/associations/contacts/companies/batch/read  (get associations)
# 3. POST /crm/v3/objects/companies/batch/read  (fetch company names)
# 4. POST /crm/v3/objects/contacts/batch/update  (write the contact's company property)
```

**Key API notes:**
- Use the Search API to find contacts where `company` NOT_HAS_PROPERTY
- Search API caps at 10,000 results. Segment by `createdate` ranges if needed.
- Use Associations API v4 to get contact-to-company associations
- Batch update contacts via `POST /crm/v3/objects/contacts/batch/update` (100 per call)
- Respect rate limits: 100 requests per 10 seconds per app on Free/Starter, 190 on Professional/Enterprise; the Search API has its own cap of 5 requests per second

### Why Do Both?

- The **workflow** handles both backlog (enrolled on activation) AND future contacts automatically. It is the long-term solution.
- The **API backfill** provides immediate results if you cannot wait for workflow processing (which may take hours for large databases).
- If you only do the workflow, that is perfectly fine. It will process the backlog since existing contacts meeting the trigger criteria get enrolled on activation.

## After

Wait 1-2 hours after activating the workflow (longer for very large databases), then verify: `uv run scripts/after.py` (re-runs the before-state query and compares against the baseline).

**Verification checklist:**

1. The "missing company name" count should have dropped dramatically (typically from 40-60% to under 10%)
2. Remaining contacts without company names should primarily be those with personal email addresses (gmail.com, yahoo.com, etc.)
3. Spot-check 10-20 contacts to confirm the company name matches their associated company record
4. Check workflow history for errors:

From TomGranot/hubspot-admin-skills, MIT.

More from TomGranot/hubspot-admin-skills

Signals

Stars
77
Forks
18
Open issues
0
Last commit (this folder)
Oct 12, 2026 (18 days ago)

From GitHub (fetched Oct 24, 2026).

Details

Version
1.1
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from tomgranot

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get enrich-company-name running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying enrich-company-name?

CallGet help
Cite this page

enrich-company-name skill. Agent Mart. https://agentmart.dev/skills/tomgranot-enrich-company-name (last updated 2026-10-24)