All workflows

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. 1

    Search for the person

    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.

  2. 2

    Corroborate the profile

    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.

  3. 3

    Enrich the 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.

  4. 4

    Log the match

    HubSpot

    Create or update a contact for personal_email with the resolved name, employer and identity confidence, matched on email.

  5. 5

    Score and flag

    Your agent

    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.

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.com
  • target_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)

Enrich a company (Harmonic, tool:harmonic/enrich-company)

Use the API.

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

  1. 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.
  2. 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.
  3. 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.
  4. Log the match with Create or update contacts (HubSpot). Create or update a contact for personal_email with the resolved name, employer and identity confidence, matched on email.
  5. 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.