# Clean and Enrich a HubSpot Contacts Export — Ravn

Canonical: https://askravn.com/skills/hubspot-export-cleanup

Claude skill

# Clean and enrich a HubSpot contacts export

Take a contacts CSV exported from HubSpot, verify every email, find missing work emails, optionally fill job titles, and produce an import file that updates the existing records. Ravn has no native HubSpot app, so this is a file round-trip: export, enrich with the CLI, re-import.
[Download SKILL.md](https://askravn.com/skills/hubspot-export-cleanup/SKILL.md) [Start free](https://askravn.com/#start)

Install
## One command.
Installs into `~/.claude/skills` for Claude Code. In Claude, upload the downloaded file under Settings → Capabilities → Skills.
```
npx ravn skill install hubspot-export-cleanup
```

## When to use

- Bounces are climbing, or a big sequence is coming up.
- Contacts have names and companies but no email, or unchecked emails.
- The user says "clean up my HubSpot contacts" and can export a CSV.

## Before you start

- Check the connection: `npx ravn whoami` (free). Note lookups left this window.
- `reverse_email_lookup` needs your own provider key connected — run `ravn keys add pdl` first; this tool runs on your own provider account. If it returns 403 `provider_key_required`, stop and tell the human to add their key. Verifying emails and finding emails by name are ours and need no key. Every call is one lookup; misses are free.
- Ask the user to export with the Record ID column included. That ID is what lets HubSpot update existing contacts on re-import instead of creating new ones.
- Read the header row. Column names vary; common ones are `Record ID`, `First Name`, `Last Name`, `Email`, `Website URL` and `Job Title`. Use the real names.

## Steps

- Remove opted-out contacts first. Filter out anyone unsubscribed and keep them out of every later step.
- Verify existing emails. Quote `--map` values that contain spaces.

```
npx ravn enrich contacts.csv --tool validate_email --column Email --dry-run
npx ravn enrich contacts.csv --tool validate_email --column Email --limit 10 --out sample.csv
npx ravn enrich contacts.csv --tool validate_email --column Email --out step1.csv
```

- Split `step1.csv` locally into: rows with `rw_verdict` = `valid`, and rows that are blank, `invalid`, `risky` or `unknown` and have a name plus a company website. Write that second group to `needs-email.csv` with the step 1 `rw_*` columns renamed (for example `rw_verdict` to `old_verdict`) or dropped, so the next pass does not create clashing column names.
- For the second group, try to find a better work email:

```
npx ravn enrich needs-email.csv --tool search_business_email_by_name --map "first_name=First Name,last_name=Last Name,company=Website URL" --limit 10 --out sample2.csv
npx ravn enrich needs-email.csv --tool search_business_email_by_name --map "first_name=First Name,last_name=Last Name,company=Website URL" --out step2.csv
```

Accept a found address only when its `rw_verdict` is `valid`. Treat `risky` (catch-all) as a suggestion for the user to review. 5. Optional, needs your provider key: for valid rows with an empty job title, run `reverse_email_lookup --column Email` on a copy with the step 1 `rw_*` columns renamed, to fill `rw_title`, `rw_seniority` and `rw_company`. The dry run shows how many lookups the pass will use. 6. Build the import file. Keep `Record ID`. Write the best email into `Email`, copy `rw_title` into `Job Title` only where it was empty, and add a column such as `Email Verdict` with the verdict. Never overwrite hand-entered data without asking. 7. Tell the user how to import: Contacts, Import, file from computer, and map `Record ID` so existing records are updated. Any custom property (like `Email Verdict`) must exist in HubSpot before it can be mapped.

## Output

- `hubspot-import.csv`: Record ID plus the updated columns, one row per contact.
- `removed.csv`: contacts with no usable email, with `rw_verdict` and `rw_reason`.
- A summary: contacts in, valid as-is, fixed with a new email, titles filled, still unusable, and lookups used.
Working files keep `rw_status` (`ok`, `not_found`, `error`, `dropped`), `rw_verdict` and other `rw_<field>` columns.

## Rules

- Never re-add or email contacts who unsubscribed or opted out. Ravn's own opt-out page is [/privacy#optout](https://askravn.com/privacy#optout).
- Drop invalid and risky addresses from any sending list.
- No FCRA uses: do not clean contacts to decide credit, employment, insurance or housing.
- On a 429 `fair_use_exhausted` or a 403 `provider_key_required`, stop and tell the human. Rows not reached are `dropped`; rerun later to finish.

## Example prompt

I exported all 3,200 contacts from HubSpot. Half of them are from an old trade show. Verify the emails, find new ones where they bounced, and give me a file I can import back without duplicates.

## More [skills](https://askravn.com/skills)
Install them all with `npx ravn skill install --all`.
- [Identify Website Visitor Companies from IPsUse when someone has server or analytics logs and wants to know which companies visited, turning IPv4 addresses into organisations with honest gaps..](https://askravn.com/skills/identify-website-visitors)
- [LinkedIn Profile URL to Verified EmailUse when someone has LinkedIn profile URLs and wants a verified email for each person, work email first, via your own data provider..](https://askravn.com/skills/linkedin-to-email)
- [Meeting Prep Brief on a Person and CompanyUse before a call or meeting when someone wants a short brief on the person they are meeting and that person's company, from an email, name or LinkedIn URL..](https://askravn.com/skills/meeting-prep)
- [Monitor Ravn Usage and Credit SpendUse when an agent or person needs to stay within a Ravn budget by checking lookups and provider-key status before, during and after a job..](https://askravn.com/skills/monitor-usage-and-credits)
- [Ravn Core Skill for ClaudeUse Ravn from Claude or the terminal to validate emails, find work emails, enrich CSVs, and look up companies, phones and people..](https://askravn.com/skills/ravn)
- [Reduce Email Bounce Rate on a Stale ListUse when bounces are hurting deliverability and someone wants a stale list re-verified, segmented by risk score and given a clear re-send policy..](https://askravn.com/skills/reduce-bounce-rate)
