Highlights
  • The loop is one contact record assembled by hand across a search tab, a company site, a spreadsheet and a sequencer, about five minutes a go.
  • The lookups are not the work. Deciding who belongs on the list is the work, and it is the only part of this loop a person should still be doing.
  • The prompt turns a raw list of names and companies into clean, normalized rows with the guesses labeled as guesses.
  • The script does the lookups for real: company, contact, verified address, written once into the destination with no duplicates.
  • A record built the same way every time is a record you can trust, which is the whole point of being able to fill in your contact data automatically.

Welcome to The Loop. Every Wednesday we take one real, repetitive workflow that someone does by hand and unwind it into something you can run. This week: the four tabs it takes to turn a name on a list into a contact record somebody can actually send a message to.

The boring task you repeat is a specification in disguise. Nobody wrote down how a prospect record gets built at your company, because it never felt like a process, it felt like five minutes of common sense repeated until the list ran out. But every one of those five minutes is a rule: which title counts, which domain is the real one, what to do when there are two people with the same name, what gets typed into the notes field. Say those rules out loud once and the typing stops being yours.

This is the oddly specific automate lane rather than the troubleshooting lane, and the specificity is the point: the generic version of this article is about lead generation, which helps nobody. The build below is about one record, start to finish, and then about two hundred of them.

The Loop, in Full

See the loop clearly before automating it, because the part that looks like the job is not the part that costs anything. Priya runs sales for a nine person company and does her own prospecting on Tuesday mornings. She has a list of forty companies from a conference attendee page. For each one she opens a search tab and works out who owns the problem her product solves, which is usually a title she has to infer from three near misses. She finds a plausible person, opens the company site to confirm the domain is the one they actually use for mail rather than the marketing redirect, guesses the address from the pattern she saw on a press contact, pastes name and title and company and address into her spreadsheet, adds a line in the notes about why this person, and then uploads the sheet to the sequencer, where half the columns need remapping because the header names drifted since last month. Forty companies later it is lunchtime and she has not spoken to anybody.

  1. Search the company and work out which human owns the problem you solve.
  2. Open the company site to confirm the real mail domain rather than the redirect.
  3. Guess the email address from whatever pattern you have seen before.
  4. Paste name, title, company, domain and address into the spreadsheet by hand.
  5. Type a one line note on why this person, then upload the sheet and remap the columns.

Every step is easy, which is exactly why it has survived. None of it requires judgment beyond a handful of rules Priya applies the same way every time, and the one step that does require judgment, step one, gets the least attention because the other four have already eaten the morning. That inversion is the signature of a loop worth unwinding: the mechanical parts have crowded out the decision, and mechanical parts are what you hand to a bot that types for you so the decision gets the time it deserves.

The Manual Tax

The cost is five minutes a record, plus the bounces, plus the two weeks a list sits half built because nobody has a clear morning.

The aggregate version of this is documented well enough to settle arguments. In its 2026 State of Sales research, Salesforce reports that sales reps spend 60% of their time on non-selling tasks, and names the specific offenders: hunting for material, manually entering customer notes into the CRM, chasing internal approvals. The same report puts the average seller on eight tools to close a deal, which is the other half of this loop expressed as a number. Five minutes per contact is not a story about typing speed. It is a story about a person acting as the connective tissue between eight systems that will not talk to each other.

  • Errors. The guessed address is the expensive one, and it fails in two directions. A bounce costs you the contact and a little of your sending reputation, which you pay for later on messages that had nothing to do with this list. The quieter failure is a guess that delivers to the wrong person with the same surname, so your careful opening line about their recent funding round lands in a stranger's inbox. Neither shows up as an error in the spreadsheet. Both show up as a list that underperforms for reasons nobody can name.
  • Latency. Prospect data decays while it waits. A record built on Tuesday and sequenced three weeks later has had time for the person to change roles, the company to rebrand the domain, or a competitor to get there first. The list is at its most valuable on the day the trigger happened, and a loop that only runs when somebody has a free morning guarantees that the list is always a few weeks past its best.

A record you assembled by hand is not more trustworthy than one a script built. It is less trustworthy, because the script would have told you which fields it was unsure about.

So the goal is not a faster morning. The goal is to stop having a person in the middle of a data pipeline at all, which is what it looks like to turn a bare list into finished contact records on its own and leave the human with the one question that actually needs answering.

Unwinding the Loop

Automating starts with description, not code. Write this loop down as a spec and the API calls turn out to be the boring part, while four rules you have never written down turn out to be the whole thing.

Part of the loopWhat it is for this workflow
TriggerA new row arriving on the list: a conference export, a form fill, a saved search, a company added by hand. One record in, one record out.
InputThe least you ever actually start with, which is usually a company name and sometimes a person's name. Everything else on the record is derived, not given.
DecisionWho owns the problem at this company. Stated as a ranked list of titles with the near misses you will accept, not as a job title you hope matches exactly.
DecisionWhat counts as an address you are willing to send to. Verified, pattern-matched, or neither, with a different destination for each so an unverified guess never reaches the sequencer by accident.
OutputOne record in the destination system, fields filled in the shape you defined, every value carrying its source and the date it was found.
Success signalThe bounce rate on the list, and the number of records a human had to touch before sending. Both should fall, and the second one should fall further.

Two of those rows are plumbing and four are judgment, which is an unusually good ratio and the reason this loop is worth the hour. Writing the spec before any step is configured is also exactly how BYOBot turns a described task into a running workflow, so the description is not the preamble to the build, it is most of the build. The destination half of this will look familiar if you read our first installment on moving leads from a spreadsheet into a CRM, and the two compose cleanly: that one owns the write, this one owns everything that has to be true before there is anything worth writing.

Try It Now

Tell BYOBot what one finished prospect record looks like at your company and it will design the build: which titles count, where each field comes from, and what happens to an address it cannot verify.

Turn my list of company names into finished contact records…

The Build: One Loop, Three Ways to Run It

The same described loop becomes three builds, and which one you want depends only on how hands-off you need it to be. Start at the top and stop whenever it is good enough.

The Prompt

You can take a real bite out of this today with no setup at all. The prompt cannot look anything up, and pretending otherwise is how people end up sequencing invented email addresses. What it can do is the normalizing: take the mess you exported, put it in the shape your systems expect, rank the titles against your actual buyer, and mark every derived value as derived so nothing unverified gets treated as fact.

Below is a raw list of prospects I exported. Columns are
inconsistent, names and titles are formatted however the
source felt like it, and some rows are incomplete.

Normalize it into exactly these columns, one row per person:

  first_name | last_name | title_raw | title_bucket |
  company | domain | fit | fit_reason | needs_lookup

Rules:

1. title_bucket is one of: OWNER, ADJACENT, WRONG, UNKNOWN.
   My buyer is the person who owns [THE PROBLEM I SOLVE].
   OWNER means they own it. ADJACENT means they sit next to
   it and can forward. WRONG means they cannot help.
2. fit is HIGH, MEDIUM or LOW, and fit_reason is one short
   clause citing only what is in the row. No speculation
   about budget, intent, or company plans.
3. Never invent an email address. If a row has no address,
   write needs_lookup = EMAIL and leave the field empty.
4. Never invent a domain. If the domain is missing or looks
   like a marketing redirect, write needs_lookup = DOMAIN.
5. Normalize names to proper case and strip honorifics,
   certifications and emoji. Keep title_raw exactly as given
   so I can audit your bucketing.
6. Flag any two rows that may be the same human, with the
   reason, in a separate DUPES list at the end.

Then list the three bucketing calls you were least sure
about and what you would need to decide them.

Run that and the forty row list comes back sorted, with the rows that need a real lookup separated from the rows that are ready. The audit at the end is the part worth reading: the calls it was unsure about are usually the titles your own rules never covered, which means you just found the gap in your spec for free. From there the rows marked HIGH and OWNER are the ones worth a human's attention, and the rest can wait for the build that will keep your CRM filled in without you typing.

The Script

Here is the honest version: almost none of this build needs AI at runtime. Finding a company, finding a contact, verifying an address and writing a record are API calls, and a model in the middle of that chain only adds a way to be confidently wrong. The pieces are all documented and most have usable free tiers for a list this size. Email discovery and verification are what Hunter exposes directly, including a confidence score you should store rather than discard. Broader company and person lookups live behind the Apollo developer API. The write at the far end, including the search-before-create that keeps you from making duplicates, is the standard contacts endpoint in HubSpot's CRM API or its equivalent in whatever system you actually use.

TITLES   = ranked_list("config/buyer-titles.yml")
MIN_CONF = 85          # below this, nobody sends to it

def build_record(row):
    company = find_company(row.company)        # 1 call
    if not company: return park(row, "no company match")

    person = best_contact(company, TITLES)     # 1 call
    if not person: return park(row, "no title match")

    email, conf, pattern = find_email(person, company.domain)

    rec = {
      "name":   normalize(person.name),
      "title":  person.title,
      "bucket": bucket(person.title, TITLES),
      "domain": company.domain,
      "email":  email,
      "source": {"found": today(), "conf": conf,
                 "via": "verified" if conf >= MIN_CONF
                        else "pattern:" + pattern}
    }

    key = rec["email"] or (rec["domain"], rec["name"])
    existing = find_in_crm(key)                # before writing

    if conf < MIN_CONF:  return queue_for_review(rec)
    if existing:         return update(existing.id, rec)
    return create(rec)

Four details carry the value here. The lookup is keyed on a ranked title list in a config file, so changing who you sell to is a file edit rather than a rewrite. Every record stores how its address was obtained, so a later run can tell a verified address from a hopeful pattern. The duplicate check happens before the write, not as a cleanup job on Friday. And a record below the confidence floor goes to a review queue rather than to the sequencer, which means the build never silently sends on a guess. BYOBot will generate the working version against your actual tools, including the rate limiting and the parked-row report, so you can fill in the missing fields on every new contact automatically instead of on Tuesdays.

The Schedule

Now make it boring. The script already does the work, so the schedule tier is about two jobs that only matter once the list is not a one-off. The first is the obvious one: run the build against whatever arrived since the last run, every morning, so a record is enriched on the day the trigger happened rather than three weeks later. The second is the one people skip, a monthly re-check of records you have not contacted yet, because an address verified in January is a claim about January. Both run from a cron entry on any always-on machine, or from the free schedule trigger in GitHub Actions if you would rather not own a server. Keep the parked rows in one report that a person reads on a schedule, because the rows your build could not finish are the most interesting output it produces.

BuildWhat runs itSetupRuns unattended?
The promptYou, in any AI chat tool, normalizing and ranking the raw listMinutesNo
The scriptLookups, verification and a deduplicated write, no model involvedAn hour, onceOn demand
The scheduleA daily pass on new rows plus a monthly re-verify of stale onesA few extra minutesYes

Steal This Build

Here is the whole loop as a spec you can copy into your own stack this afternoon, or hand straight to a system that will turn the description into a running workflow for you.

  • Trigger: one row arriving on the list, from an export, a form, a saved search or a human.
  • Resolve: the company and its real mail domain, before anything else is attempted.
  • Choose: the person, against a ranked title list that lives in a config file, not in your head.
  • Verify: the address, store the confidence, and route anything under the floor to a review queue.
  • Report: what was written, what was updated, and every row the build parked and why.

The shape is universal. Somewhere in your week there is a record that starts as one thin fact and gets fattened by a human opening tabs: a supplier you are onboarding, a candidate you are screening, an asset you are cataloging, a property you are listing. The spec barely changes. One thin input, a chain of lookups each of which can fail, a confidence threshold, a key that prevents duplicates, and a parked pile for the ones that need a person. That pattern covers most of what gets filed as the repetitive work you want off your plate, and the version you write for prospects is the one you will reuse for everything else.

Build Your Version

Tell BYOBot about a loop in your week

Describe the task you keep doing by hand and BYOBot will design the full playbook: the prompt, the script, and the schedule that runs it for you.

Frequently Asked Questions

  • By hand it runs about five minutes per contact once you include the searching, the email guess, the copy into a sheet and the upload to the sequencer. Published estimates for doing it properly from public sources range from roughly seven minutes to half an hour per person, and the spread tells you something: the time depends almost entirely on how much of it is lookups. With the lookups automated, the work per record drops to the part a machine cannot do, which is deciding whether this person belongs on the list at all. That is the whole argument for letting a build complete your contact records for you.
  • A pattern is a hypothesis, not an address. Guessing first.last at the domain works often enough to feel safe and fails in exactly the ways that hurt: a bounce on a named executive you only get one shot at, or worse, a delivered message to a different person with the same surname. Treat the pattern as a candidate, verify it before it is allowed anywhere near a sequencer, and store the confidence next to the address so every later run can tell verified from assumed. The point is not to never guess. It is to never forget that you guessed.
  • Not for the lookups, and that is the honest part. Fetching a company record, finding a contact, verifying an address and writing a row are all plain API calls with no model involved. AI earns its place at exactly two points: normalizing messy inbound names and titles into the fields you defined, and judging whether a title actually matches your buyer when the words do not line up, which is a language problem rather than a data problem. Everything else is deterministic code, and keeping it that way is what makes the build safe to leave running without you.
  • A key you chose in advance, checked before anything is written. Verified email is the usual one, with company domain plus normalized full name as the fallback for records that have no address yet. Search the destination system first, update the existing record rather than creating a second one, and keep the source and the run date on every field you write, so you can tell later which run put a value there and whether it is still worth trusting. Picking the key is a five minute decision that saves a recurring afternoon of merging.
BYOBot Autopilot
BYOBot Autopilot
Automated AI publishing system · editorial rules by Luke Grace LinkedIn →

This article has been published in an automated fashion with fully AI-written copy. These articles are meant to curate AI news from around the globe and bring a fresh perspective to using AI tools to accomplish big things. No person reviewed this specific piece before it went live, so check anything that matters against the sources linked above. Luke Grace sets the rules the system writes to. He's an algorithms and natural language expert with over 13 years experience and the creator behind BYOBot, the Build Your Own Bot platform that helps anyone build a multi-tasking agent to take over their repetitive tasks. For consulting help or more advanced AI workflow orchestration, you can reach Luke on LinkedIn.