sby @shipgtm
Resolve a personal email into its likely company
Researches the person behind a personal email with Exa, enriches the company with Harmonic, and logs the result in HubSpot.
Outcome
The likely person and company behind the email, each with a citation, or a clear "unresolved" when the sources disagree or nothing turns up.
A HubSpot contact logged with the match and its identity confidence.
A fit score against your target segment, with low-confidence matches flagged for review.
How it works
- 1
Search for the person
ExaAsk who publicly holds
personal_email's handle or the name clues it gives, grounded in web sources. Keep the candidate's name, LinkedIn URL and claimed employer, with the citations. - 2
Corroborate the profile
ExaRead the candidate's LinkedIn or bio page directly. Keep whether it confirms the same employer and role step 1 found, as the identity confidence.
- 3
Enrich the company
HarmonicLook up the employer from step 1, by domain when you have one. Keep its funding, headcount and traction for a fit check.
- 4
Log the match
HubSpotCreate or update a contact for
personal_emailwith the resolved name, employer and identity confidence, matched on email. - 5
Score and flag
Your agentGive the match a fit score from whether step 3's company matches
target_segment. Flag anything low-confidence or conflicting for manual review instead of guessing.
You'll be asked for
The personal email address to resolve
e.g. jane.doe@gmail.com
The kind of company that counts as a fit
e.g. Series A-B B2B SaaS in the US
The file your agent runs
personal-email-enrichment.md
Resolve a personal email into its likely company
Researches the person behind a personal email with Exa, enriches the company with Harmonic, and logs the result in HubSpot.
Set up the tools below, then run the steps in order for the user, carrying each step's results into the next. The run is done when the user has the outcome below.
Outcome
- The likely person and company behind the email, each with a citation, or a clear "unresolved" when the sources disagree or nothing turns up.
- A HubSpot contact logged with the match and its identity confidence.
- A fit score against your target segment, with low-confidence matches flagged for review.
Inputs
Ask the user for these before you start.
personal_email: the personal email address to resolve, e.g. jane.doe@gmail.comtarget_segment: the kind of company that counts as a fit, e.g. Series A-B B2B SaaS in the US
Set up
Exa (tool:exa/answer-question, tool:exa/get-page-contents)
For each call, use the first option your agent supports that lists it.
MCP (official, remote)
Add this server to your agent's MCP settings, then sign in when asked.
{ "mcpServers": { "exa": { "url": "https://mcp.exa.ai/mcp?login" } } }
- Read web pages: call the MCP tool
web_fetch_exa
API (official)
- Base URL: https://api.exa.ai
- Answer a question from the web:
POST /answer - Read web pages:
POST /contents - Auth: send the header
Authorization: Bearer $EXA_API_KEY - Get a key: https://dashboard.exa.ai/api-keys
Enrich a company (Harmonic, tool:harmonic/enrich-company)
Use the API.
- Base URL: https://api.harmonic.ai
- Endpoint:
POST /companies - Auth: send the header
apikey: $HARMONIC_API_KEY
Note: A company not yet in Harmonic's system returns a 404 with an enrichment ID; poll the enrichment status endpoint until it resolves instead of treating the 404 as no match.
Create or update contacts (HubSpot, tool:hubspot/upsert-contacts)
Use the first option your agent supports.
Note: Matches each contact on idProperty, email or a custom unique property. On MCP, manage_crm_objects waits for the user to confirm the proposed changes before it writes.
MCP (official, remote)
Add this server to your agent's MCP settings, then sign in when asked.
{ "mcpServers": { "hubspot": { "url": "https://mcp.hubspot.com" } } }
Call the MCP tool manage_crm_objects.
API (official)
- Base URL: https://api.hubapi.com
- Endpoint:
POST /crm/objects/2026-09/contacts/batch/upsert - Auth: send the header
Authorization: Bearer $HUBSPOT_API_KEY
Note: Use a service key or an app's static access token with the CRM scopes the calls need; paths carry a dated version such as 2026-09.
Before step 1, confirm access to each service with its cheapest read-only call, like a list or a search. Never send or change anything to test access.
Steps
- Search for the person with Answer a question from the web (Exa). Ask who publicly holds
personal_email's handle or the name clues it gives, grounded in web sources. Keep the candidate's name, LinkedIn URL and claimed employer, with the citations. - Corroborate the profile with Read web pages (Exa). Read the candidate's LinkedIn or bio page directly. Keep whether it confirms the same employer and role step 1 found, as the identity confidence.
- Enrich the company with Enrich a company (Harmonic). Look up the employer from step 1, by domain when you have one. Keep its funding, headcount and traction for a fit check.
- Log the match with Create or update contacts (HubSpot). Create or update a contact for
personal_emailwith the resolved name, employer and identity confidence, matched on email. - Score and flag yourself. Give the match a fit score from whether step 3's company matches
target_segment. Flag anything low-confidence or conflicting for manual review instead of guessing.
Notes
This looks up public business identity only; discard anything below your confidence bar rather than logging it, and never treat a candidate step 2 couldn't confirm as resolved.
Adapted from ShipGTM's personal email enrichment guide, which uses the Exa API for people research, Harmonic AI for company funding data, and HubSpot as the CRM of record.
Rules
- Use only the services set up above. The read-only calls they need, like listing ids or polling for results, are fine.
- Ask the user before anything that sends messages, costs money, or changes data, and say how many records it touches. One approval covers a batch the user has seen.
- Never print API keys.