Skip to content
← Processes

Build a target list from a sentence

AI lead generation from one sentence: companies sourced and scored on dated signals, contacts verified, checked against your CRM and staged as a campaign.

Apollo.io→HubSpot→TheirStack→Serper→Apify→FullEnrich→Lemlist
Starts
When you ask
Steps
6
Checks and gates
0
A person decides
Never, runs alone

Logistics companies in France, 250 to 1,000 employees, hiring supply chain roles. Source 40 accounts.

One-sentence brief in chat

See it in a demo

Claude runs the rest autonomously

  1. 1

    AI shortlists accounts and their people.

    Apollo.io

    Apollo.io

    Matching companies are scored on what the search already returned, and each one kept gets two or three people fitting the persona described.

  2. 2

    AI drops contacts the CRM already has.

    HubSpot

    HubSpot

    Anyone the CRM shows as a customer, an open deal or in a colleague's sequence is dropped, matched by email or else by company domain.

  3. 3

    AI gathers signals for what survived.

    TheirStack

    TheirStack

    Each remaining company gets its open roles and technology, recent funding, moves and expansions, and details from its own pages, each with its source URL.

    Serper

    Serper

    Apify

    Apify

  4. 4

    AI finds verified emails and numbers.

    Apollo.io

    Apollo.io

    Each contact gets a verified address and direct number, a second source fills what the first missed, and anyone still unfound is marked unreachable, not guessed.

    FullEnrich

    FullEnrich

  5. 5

    AI writes each opener from a signal.

    Each opener names one dated finding about that company and cites its URL, and a company with nothing found gets a plainer version, never an invented hook.

  6. 6

    AI stages the campaign, updates the CRM.

    Lemlist

    Lemlist

    The sequence sits as a draft with each contact's own opener, the qualified list is in the CRM with its signals as a note, and the launch is left to a person.

    HubSpot

    HubSpot

Building a prospecting list is a morning of tab-switching. Someone opens a database, guesses at the filters, exports a few hundred rows, pastes them into a sheet, spot-checks a dozen companies by hand, gives up on checking the rest, and hands over a list whose quality nobody can describe.

The sentence in someone's head is the real specification, and it never survives the trip into a filter panel intact. Meanwhile the evidence that would qualify those companies properly is public, dated and sitting behind an API: who they are hiring, what they run, what they announced last quarter, what their own pages say. The join between the two is the whole job, and so is knowing which of those calls to pay for and in what order. That order is what an AI prospecting agent can hold to on every run.

What you get

A list that matches the sentence you wrote, scored on dated evidence with a source URL behind every claim, enriched with verified addresses and real direct numbers, deduplicated against your CRM, and staged as a campaign ready for a person to launch.

From one sentence to a scored account list

Print the inferred filters before spending anything. A sentence is genuinely ambiguous and a filter panel is not, so the ambiguity has to be resolved somewhere, and the only cheap place is out loud, before the search runs. "Mid-sized" resolved to 50 to 250 when the reader meant 250 to 1000 is a completely different list, and finding out afterwards means paying for the wrong one twice. Anything the sentence did not specify stays unset.

The company search in Apollo then asks for a count before pulling rows. Under 50 means the filters are too narrow; over 2,000 means asking before spending anything. Keyword tags are applied loosely, so a search for one vertical comes back with companies from others, and results are filtered on the industry classification code before any row is written. Every surviving company is scored on what the search already returned, banded into three tiers, and the bottom tier is not worked further. The top two tiers get two or three people each, matching the seniority and function the sentence asked for.

Spending in the right order

Every step after that is a gate on the next one, and the order is the design. Sourcing is nearly free, scoring on what the search already returned costs nothing at all, finding people costs, signals cost more, and enrichment is billed per lookup. So the check against HubSpot runs before either of the expensive steps: a hundred and twenty contacts you already have in pipeline are a hundred and twenty lookups you can simply not buy, and the check that finds them is free. Signals are bought only for companies that still have a reachable contact, because research on a company you cannot reach is research you paid for and cannot use.

The signals come from three sources, each answering something the others cannot: open roles and technology from TheirStack, recent funding, acquisitions and leadership moves from Serper web search, and the detail a snippet drops from the company's own pages through Apify. This is also where the agent checks whether a company has been acquired or absorbed, since firmographic data goes stale and no score survives that. Every finding is written with its source, date and URL. A company with nothing found is recorded as having no signal, and an invented signal is never allowed.

Verified contacts and openers from signals

Enrichment cascades, and the second provider's answer still gets checked. The contact database answers first and FullEnrich picks up what it missed, which is the only way to get the hit rate up on a real batch. But a waterfall will sometimes return the exact address the first provider already flagged as hard-bounced, with nothing on the record to say it is dead, so the two answers get compared rather than the later one quietly overwriting the earlier. Same story on phone numbers: a search result will claim a direct line for almost everybody and then hand back the company switchboard, identical for every contact at that company, which is worth keeping and worth labelling but is not a direct line.

Two tiers of opener keep the personalisation honest. Where there is a signal, the email names it and carries the URL it came from, so the recipient can go and look. Where there is not, pretending otherwise produces the vague gesture at relevance that makes outbound read as automated, and a plainer email that claims less is the better failure mode. The campaign is then loaded into Lemlist as a draft with each contact's opener attached, the qualified list goes back to the CRM with its signals as a note, and the launch is left to a person.

The prompt

The real prompt behind the steps above, detailed enough that an agent with the same tools can run it as written. The Run buttons copy the full version, which also carries the steps for connecting those tools.

# Build a target list from a sentence

You have access to a B2B contact database, a hiring and technology
signal source, a web search API, a hosted scraper, a waterfall
enrichment provider, a CRM, and an outreach tool. Run this for **[one
sentence describing the companies and people you want]**.


## 1. Turn the sentence into filters, and show your work

Read the sentence and write out the structured filters you inferred
from it before running anything: headcount range, sectors, countries,
seniority, job functions. Print them.

This step exists so a wrong reading is caught in five seconds rather
than after eight hundred credits. "Mid-sized logistics companies in
France" has to become an explicit headcount band, and if your band is
50 to 250 and the reader meant 250 to 1000, they need to see that
before the search runs, not after.

Anything the sentence did not specify stays unset. Do not invent a
country filter because most customers are French.

## 2. Shortlist the accounts, scored before spending

Run the company search with those filters. Ask for the count first,
then decide:

- Under 50 results, the filters are too narrow. Report that and say
  which filter to loosen rather than proceeding with a list nobody can
  run a campaign on.
- Over 2,000, they are too broad. Report the count and ask before
  spending anything.

**A wide net costs the same as a narrow one.** Most databases bill per
page of results, not per filter, so widen the keywords and narrow
afterwards. Splitting a vertical into several single words returns far
more than one compound phrase does.

**The result set will not be the vertical you asked for.** Keyword
tags are applied loosely and a search for wholesale distribution will
return cosmetics manufacturers and EV charging networks alongside the
real matches. Filter on the industry classification code before
writing any rows, and give a reason for anything that survives
outside it.

Then score every company that made it through, using only the data
the search already returned. No paid signal is bought at this stage.
Rate each one on the criteria the sentence implies, band them into
three tiers, and stop working the bottom tier entirely. This is the
cheapest filter you will ever run and it decides what the expensive
steps operate on.

## 3. Shortlist their people worth reaching

For the top two tiers only, find contacts matching the seniority and
function from step 1. Cap it at two or three per company. More than
that and you are emailing an entire department, which gets noticed
internally and reads as a blast.

A company with no reachable contact is not a target. Mark it and stop
spending on it, whatever it scored.

## 4. Drop contacts the CRM already has, before you buy anything else

Check every contact against the CRM. Match on email where you have
one, and on company domain where you do not, because a bare name match
will happily return a different person at a different company.

Drop anyone who is already an open opportunity, an existing customer,
or under active sequence by a colleague. Keep the CRM record id
against the ones you keep, so the write in step 8 updates rather than
duplicates.

Do this before signals and before enrichment, not after. Both are
billed per lookup, and paying to research a company you already sell
to is pure waste. A list of eight hundred contacts where a hundred and
twenty are already in pipeline is a hundred and twenty lookups bought
to rediscover what you were already sitting on, and the check that
avoids it is free.

## 5. Gather signals only for what survived

Now, and only for companies that still have a live contact, gather the
evidence the outreach will be built on. Three sources, each answering
something the others cannot:

- **Open roles and the technology behind them.** A company hiring for
  the function your product serves is the strongest single signal
  available, because it is dated, public and carries a URL. The stack
  matters too, in both directions: a tool you integrate with is a
  reason to call, and a direct competitor already installed is a
  reason not to.
- **Recent events, from web search.** Funding rounds, acquisitions,
  new facilities, leadership changes in the function you sell into.
  Set the country explicitly if the market is not the search
  provider's default, or you will get the wrong region's results.
- **The pages themselves, from a hosted scraper.** Where the search
  returns a thin result, run a scraper against the source the result
  points at, the careers page, the company profile, the location
  listing. This is what gets you the detail a snippet drops.

Three things that will mislead you if you do not expect them. The
signal source may return **duplicate company records for one domain**
with different headcounts, so take the union of what they say rather
than the first row. It will have **no record at all for many mid-size
firms**, which is a normal result and not an error. And it **misses
parts of the stack**: where a layer that sits on top of a system
appears with nothing under it, the system underneath is almost
certainly present but unnamed, and the contact database's own
technology field is a usable second opinion.

**Re-check independence here, because this is the only step that can.**
Search explicitly for the company being acquired, merged or absorbed.
Firmographic data goes stale, and a company that was folded into a
group last quarter can still score at the top of the batch on
yesterday's record. If it has been, stop and say so with the source
URL. No score survives that.

Write every finding with its source, its type, the detail, its URL and
the date it was captured. **The URL is what lets a human check the
claim before repeating it in an email.** A company where you found
nothing keeps its score and gets recorded as having no signal. An
account with no signals is allowed; an invented signal is not.

## 6. Find verified emails and numbers

Enrich only what is left. Take the contact database's own match first,
then fall through to the waterfall provider for whatever it missed.

**Read the contact layer, not just the person layer.** A record can
report an address as verified at the top level while its own contact
detail carries a hard-bounce flag and no deliverable address. That
address has already bounced. An address is only usable when both
layers agree, and sending to one that a provider itself has flagged as
dead is how a sending domain gets burned.

**The waterfall is not an independent check.** Run it where the first
provider returned nothing usable and a profile URL is known, then
compare what comes back against the address the first provider already
rejected. A fallback that hands you the same dead address, with no
indication that it is dead, is not a second source. Only treat it as
new information when it differs.

**Phone data promises more than it delivers.** A search result will
report a direct line for almost everyone, and the matched record then
returns the company switchboard, identical for every contact at that
company. Only a mobile or a direct number is a real number. Write the
switchboard if it is all there is, and label it as such so nobody
calls it expecting a desk to ring.

Record the source of each address and each number honestly. "None" is
a valid value and is the right value for a bounced address. Where
nothing answers at all, mark the contact unreachable rather than
dropping the row, and keep it if the name and title are good, because
a name and a title are enough for a call even when a send is not
possible.

## 7. Write each opener from a signal

Write in two tiers. Where a company carries a signal, the opener names
it and cites the URL it came from, so the recipient can go and look.
Where it does not, the plain version goes out and claims less.
Pretending otherwise produces the vague gesture at relevance that
makes outbound read as automated, and a plainer email is the better
failure mode.

Rules that hold in both tiers:

- The opening detail comes from a captured finding on **that** company.
  No hook is ever invented to fill the slot.
- An observation about their business, never a compliment. Zero
  flattery.
- Plain text. No markup, no links, no signature block. Sequence copy
  is usually HTML and a variable is dropped into it verbatim, so an
  ampersand or an angle bracket in the text will break the markup
  around it.
- Some findings are true, relevant and still not openers. A disclosed
  control weakness or a restructuring reads as an attack when it opens
  a cold approach. Keep it in the notes as second-conversation
  material and open on something structural.

## 8. Stage the campaign, update the CRM

Two writes, and neither of them sends anything.

**To the outreach tool:** load the campaign as a draft and attach each
contact's own opener as a per-contact variable that the sequence
resolves at send time. Read the campaign's copy first and write down
every variable it references, because a variable with no value on a
contact is a contact the tool holds back rather than sends. Before the
first real add, validate one payload against the campaign without
adding anyone.

**To the CRM:** read the field definitions first, every run, because
field keys are per-workspace and hardcoding them is how a run writes
into nothing. Upsert the company, then the person, passing the record
id you kept in step 4 so an existing record updates instead of
duplicating. Attach the signals and their URLs as a note, and check
whether you already wrote one for this contact: notes usually cannot
be updated, so a second run writes a second note. Tag everything with
this run's name and date.

Then stop. The launch is a person's decision.

## Output

Report: the filters you inferred, companies found, how many survived
scoring, contacts sourced, how many were dropped as already known and
why, how many companies carried a signal and how many did not,
enrichment hit rate split by provider, how many addresses were
rejected as undeliverable, and the campaign's draft status.

Why run it with Tulina

A prompt helps one person. A process moves a team.

Pasted into a chat, the prompt above works once, for whoever pasted it. In Tulina, "Build a target list from a sentence" becomes a process the team shares, that keeps its history, runs on its own, and stays inside the same security perimeter as the tools it calls.

  • The whole team works on the same one

    PersonalTeamOrganisation

    A process lives where it belongs: yours, your team's or the whole organisation's. Whoever runs it can improve it, and everyone starts from the best version instead of explaining the job again.

  • Every edit is a version

    v1v2v3

    Each change is a new version with the previous one kept, so a bad edit is undone by restoring an earlier one. Every run records the version it followed, and what a run teaches goes back into the process.

  • It runs without you

    schedulewebhookon demand

    A hosted agent runs the process on Tulina's own infrastructure, on a schedule or when an event arrives, and keeps going when you close the chat. Nothing to host. Every run is tracked to its outcome.

  • Inside the same security perimeter

    vaultrolesrun log

    Credentials stay in the vault, never in the prompt. Roles decide who may run what, every call is logged, and a step a person has to approve waits for that person.

Questions about building prospecting lists with AI

Yes, as long as it shows how it read the description before running anything. The filters inferred from the sentence are printed first, so an ambiguous phrase like "mid-sized" surfaces as an explicit headcount band you can correct. Nothing is sourced, scored or enriched until the reading is right.

By reading the contact layer as well as the person layer, since a record can report an address as verified while its own contact detail carries a hard-bounce flag. The contact database is asked first and only what it misses falls through to the waterfall, which cascades across several sources in a single call. The waterfall's answer is compared against the first instead of overwriting it, because it will sometimes hand back the exact address the first provider already flagged as dead.

Open roles and the technology behind them, recent events such as funding rounds, acquisitions, new facilities or leadership changes, and details from the company's own pages. Each one is dated, public and carries a URL, so a claim built on it can be checked by the person receiving the email instead of taken on trust. Every finding is stored with its source link for exactly that reason.

Yes, and here that check runs before any paid signal or enrichment. Every contact is matched against the CRM by email, or by company domain where there is no email, and anyone already a customer, an open deal or in a colleague's sequence is dropped. At the end, the qualified list is written back with the signals attached as a note. Both are ordinary read and write operations, so any connected CRM supports them.

Two or three at most, matching the seniority and function you asked for. Emailing more than that across one company is visible internally and reads as a blast rather than as outreach.

Processes that share tools with this one. The shared tools are lit.

See Tulina in a 30-minute demo.

Book a demo