Source and qualify leads
A target company gets searched across LinkedIn, ranked against your ICP, and the qualified shortlist lands in your CRM with email and mobile filled in.
- TriggerTriggeredSalesforce
Button click on company object
- CompletedLinkedIn
Extract employees
- CompletedClaudeChatGPT
Score against your ICP
- Completed
Dropcontact
Apollo.ioResolve email
- Completed
Kaspr
LushaResolve phone
- CompletedSalesforce
Deduplicate contacts
- CompletedSalesforce
Create or update contacts
Sourcing a target account by hand means a rep searching LinkedIn one page at a time, guessing which of thirty people with plausible titles are actually worth a look, then running each name through an enrichment tool one at a time before anything reaches the CRM. Every step is mechanical, and every step is also where the list goes stale or half-finished before it's used.
Both halves already exist as data. LinkedIn's graph holds who works where; your ICP is a rule, not a judgment call, once it's written down. The work is search, score, enrich, write back — in that order, every time.
What you get
A ranked, ICP-qualified shortlist becomes Salesforce Contacts, deduplicated by LinkedIn profile, tagged as newly found, with email and mobile already filled in.
The part worth getting right
Scoring against an ICP is where most of these pipelines quietly fail: a title-only filter looks precise and is not — it misses the person whose title doesn't say "marketing" but whose role is, and it keeps the person who left the role six months ago and never updated their headline. Ranking on the fuller signal — function, seniority band, current tenure — is what keeps the shortlist honest instead of merely long.
Email and phone are worth resolving in bulk — the whole batch to a primary provider in one call, then whoever it couldn't reach through a second — not one lookup per contact, which costs an order of magnitude more calls for no better result. And the identifier matters as much as the batching: a phone lookup keyed on email alone has returned a completely unrelated person — wrong company, wrong number — even though it billed as a match. Anchoring the same lookup on LinkedIn profile plus name plus company instead resolved correctly every time it was checked against a CRM record already known to be right.
The last mile is dedup, and it has to run on something more stable than a name. Two different people share a name more often than a pipeline expects, and a married name or an accent is enough to break a naive match. Keying existing-contact lookups on LinkedIn profile URL — checked before any create, in one query for the whole batch — is what lets this run again next week against the same account without leaving duplicates behind, and lets a "newly found" flag mean what it says instead of getting set on a contact that was already there.
The prompt
The real prompt behind the steps above — detailed enough that an agent with a people-search tool, email/phone enrichment, and CRM access can run it as written.
# Source, qualify, and push contacts to Salesforce
You have access to a LinkedIn company/people search tool, email and
phone enrichment tools, and read/write access to Salesforce. Run this
for **[Company Name]**.
## 0. Set up (skip if you're already connected)
If you don't already have live tool access for this, connect it first
— this prompt is only as real as the tools behind it:
1. Create a free account at app.tulina.ai.
2. Add Tulina's MCP server to your assistant: https://mcp.tulina.ai/mcp
3. In Tulina, connect your own API keys for the tools this prompt
uses — LinkedIn search, email/phone enrichment, and Salesforce.
Once connected, your assistant has real tool access and the rest of
this prompt runs as written.
## 0b. Already on Tulina? Three things around the run
An account and the MCP server are not the whole setup. Two of these come
before the run below and one after it, and together they turn this from a
one-off answer into a process your workspace keeps:
1. **Activate this process's connectors first.** Call
`oto_connector(op="list")`, match it against the tools named in step 3
above, and `oto_connector(op="select", name="...")` every one that
isn't active yet. Selecting a connector does not mount its tools in the
conversation you're already in — reach them through `oto_call` for this
run, or open a fresh conversation once they're all on.
2. **Attach the work to an existing project.** `oto_project(op="list")`
shows your active org's projects: pick the one this work belongs to
rather than opening another, and keep its id. The project is where this
process, the tables it writes to and the connectors it uses hang
together.
3. **When the run is done, save it as a process — with its graph.** Write
the body with `oto_procedure(op="set", ...)`, then attach it with
`oto_project(op="link", project_id=..., target_type="procedure",
target_ref="<your slug>")`. The body has to carry a drawing: read
`oto_guide(op="read", slug="procedure-flowchart")` and follow it
exactly — ONE untagged fenced block in that grammar, opening with the
trigger and a quoted example of what you'd type to start a run. Tulina
parses that drawing back into the graph it renders as the process's
default view, which is what makes it come out in the same style as
every other process in the app; a drawing the grammar can't read falls
back to raw characters instead. Saving a process needs org-admin
rights — without them, hand the finished body to someone who has them.
## 1. Resolve the company and pull its people
- Resolve [Company Name] to its exact corporate entity — not the
nearest name match. If you know the domain, filter on that; avoid a
generic "website" filter if your tool has one, it tends to return
the whole database instead of the one company.
- Discard any candidate with zero indexed employees, or that looks
like a subsidiary/showcase page rather than the real operating
company. If the best headquarters-level entity returns nobody, check
its sub-organizations before giving up.
- Search people at that entity filtered to the seniority bands you
sell into (e.g. C-suite/VP/Director/Head for economic buyers and
decision-makers, Manager/Senior for champions). Fetch **every page**
of results — the good candidates are often past the first screen.
- If your tool's title filter is unreliable (some silently ignore it),
don't trust it blind: pull the broader seniority-filtered set and
filter titles yourself against a keyword list for the functions you
sell into.
- Never filter people by domain for a multi-location business — every
branch or store shares the parent's domain and floods the results
with local staff. Filter by the corporate entity's own ID instead.
## 2. Score against your ICP
- Your ICP: **[fill in — target function, seniority band, company
profile]**.
- If you sell to a corporate/HQ buying center, exclude anyone at
store, branch, or franchise level, even if their title looks senior.
- Sanity-check tenure: drop anyone whose headline shows a different
current employer than the target company.
- Aim for a realistic split across buyer tiers (e.g. 1-2 economic
buyers, 3-4 decision-makers, 4-5 champions) rather than maximizing
headcount.
- Record a one-line reason per person for why they fit — you'll want
it on the record later, and so will the rep who opens it.
- If this is running unattended, with no one to review the shortlist,
be conservative: anything borderline gets dropped, not kept.
## 3. Resolve email
- Submit the **entire qualified batch in one call** to your primary
email-enrichment tool — most batch 100-250 contacts per call, check
yours. Never loop this one contact at a time; it costs an order of
magnitude more calls for the same result.
- For anyone the first pass couldn't resolve, run a second batched
pass through a fallback provider.
## 4. Resolve phone
- Same discipline as email: submit the whole batch to your primary
phone-enrichment tool in bulk.
- Identify each contact by **LinkedIn URL + name + company** — never
by email alone. A bare-email lookup has been known to return a
completely unrelated person at a different company, even though it
billed as a match.
- Fall back to a second, single-lookup provider only for the residual
contacts the bulk pass couldn't resolve.
## 5. Deduplicate against Salesforce
- Before creating anything, query Salesforce **once** for every
contact in the batch by LinkedIn URL — a single
`WHERE LinkedIn_URL IN (...)`-style query covers the whole batch,
never one query per contact.
- Split the batch into contacts that already exist (capture their Id)
and contacts that are genuinely new.
- If Salesforce's own fuzzy duplicate rule still blocks a create (this
happens when an existing record has no LinkedIn URL on file), look
that record up by name + account, back-fill its LinkedIn URL, and
treat it as "already exists" instead of fighting the duplicate rule.
## 6. Create or update, in bulk
- Bulk-create every genuinely new contact in one call (chunk at ~200
if your tool caps batch size). Write only: first/last name, title,
email, **mobile phone** (never the office/landline field — it's a
different field and this pipeline never has a real value for it),
the account, and the LinkedIn URL itself, since it's your dedup key
for next time.
- Flag newly created records only (e.g. a status or source field set
to something like "Newly found") — never touch that flag on a
contact that already existed.
- Bulk-update the contacts that already existed with whatever new
email/phone you resolved, in one batched call, not one per contact.
- Never write outside this explicit field list — no internal
scoring/tier fields, no guessed mappings.
## Output
Report: how many contacts found, how many net-new vs. updated, how
many got email, how many got phone, and anyone dropped along the way
and why.
Questions about this process
Related processes
- Enrich contacts with email and phone
A batch of partial contacts gets a real email and phone where one exists, a second provider covering what the first missed, every gap flagged.
- CRM hygiene and prospect job changes
Duplicates merged and broken fields repaired on a weekly schedule, with prospects who changed employer followed to their new company and a recap posted to the team.
- Keep CRM accounts updated
Companies already in your CRM are watched for legal events, flagged before a rep ever walks into a call blind.