Package Library
Installable package Verified

Lead Generation

Generate leads for your business.

@quickflo/lead-genby @quickflov1.1.1
lead-gensales

Package overview

Overview

Searches Google Maps for businesses in the areas you pick, researches each one, scores it against what you sell, and gives you a ranked call list with an opening line already written. Run it once or put it on a schedule.

What you need

Connection Required Why Where to get it
google-places yes Finds the businesses Google Maps Platform credentials
anthropic yes Does the research and writes the opening lines Anthropic Console keys
smtp no Only for the emailed report. Skip it and leads still get saved Your own mail provider

For the Google key: create the key, enable Places API (New) on the project, and turn on billing. Google will not serve requests without billing enabled even inside the free tier, and the failure looks like a permissions error rather than a billing one. Setup and pricing are worth a skim before your first large run.

It also creates one table called leads, which is where the results go.

Set it up

Three fields decide what you get back. They go into every research prompt and into the score, so getting them right matters more than anything else here.

Field What to put
offerDescription What you sell, in a sentence or two
idealCustomer What a good customer looks like: size, type, situation
painCriteria What a business would be complaining about if they needed you

Then tell it where to look.

Field What to put
serviceTypes The kinds of business to search for. Each one is searched in each location
searchLocations Where to search. A name on its own is enough: { "name": "Gastonia, NC" }
maxLeadsPerRun How many new businesses to research per run. This is your cost control
minLeadScore Only keep leads at or above this score
notifyEmailTo Who gets the report. Leave empty for no email

Start with maxLeadsPerRun at 10 and one location. A run costs a few cents per business researched, and you want to read the first batch before you spend on a hundred more.

Run it

In the sidebar, open Packages → Lead Generation, then click the workflow called lead-gen. That is the one you run. The others in the package are pieces it calls, and you never open them directly unless you want to change how they work.

Put your values in the Test data panel and press Run. Here is a complete example to edit:

{
  "serviceTypes": ["med spas", "barbers", "nail salons"],
  "searchLocations": [{ "name": "Gastonia, NC" }],
  "maxLeadsPerRun": 10,
  "minLeadScore": 0,
  "notifyEmailTo": [],
  "offerDescription": "24/7 AI call answering and appointment scheduling for local service businesses, so they never miss a customer call or booking.",
  "idealCustomer": "Established local service businesses, roughly 5-50 employees, with steady call volume and limited after-hours coverage.",
  "painCriteria": "Missed or unreturned calls, slow response times, no after-hours availability, scheduling difficulties, long hold times, poor phone communication."
}

Everything below notifyEmailTo is what you change to point this at your own offer. The scoring fields (scoringWeights, idealEmployeesMin, idealEmployeesMax, maxEmployees, excludeBusinessTypes) can be left out entirely until you need them, and are covered under Advanced.

A location name on its own is usually all you need. Google reads it the same way it would if you typed it into Maps, so "Gastonia, NC", "Charlotte metro" and "78704" all work.

If you want to control the exact area instead of letting Google decide, add coordinates and a radius:

{
  "name": "Gastonia, NC",
  "latitude": 35.2621,
  "longitude": -81.1873,
  "radiusMiles": 25
}

radiusMiles caps at 31, which is Google's limit, and is ignored unless both coordinates are set. To find coordinates, search the place on Google Maps and read them out of the URL.

After the run finishes, your leads show up in the Lead Generation dashboard. Start with the Call List at the bottom: it is sorted by score, so the businesses worth phoning first are at the top, and each row carries the phone number and the opening line.

Read those leads before doing anything else. If they look wrong, the fix is almost always in the three fields above, not in the scoring.

What happens on a run

  1. Searches each business type in each location.
  2. Drops anything already in your leads table, before doing any research on it. Re-running costs nothing for businesses you already have.
  3. Researches each new business: who runs it, how big it is, and what its reviews say.
  4. Scores it 0-100 and marks it High, Medium, Low, or Disqualified.
  5. Saves the ones above your threshold and emails you the batch.

Every lead you get back has the business details, whoever the research turned up as the decision-maker, a summary of what its reviews complain about, the score with a breakdown of how it was reached, and an opening line written for that specific business.

If the leads look wrong

Wrong businesses entirely. Your serviceTypes are too broad. Searching "call center" on Google Maps returns government offices, banks and shipping stores, because Maps categorises loosely. Use narrower terms, then add the categories you keep seeing to excludeBusinessTypes (a comma-separated list) to drop them.

Right businesses, wrong order. The default scoring is built for consumer businesses like dentists and plumbers, where Google reviews are plentiful and revealing. If you sell to other businesses, reviews tell you almost nothing and the scoring needs changing. See below.

Everything scores about the same. The research could not find much about any of them. That is common for small private companies, and it is honest: the score does not pretend to separate businesses it has no information about.

Once it's working

Everything so far has been you pressing Run. These three turn it into something that feeds you leads without being asked.

Run it every day

Add a schedule trigger to the lead-gen workflow and pick a time. Each morning it searches the same areas again and only pays attention to businesses that were not there yesterday.

This is cheap for the same reason re-runs are cheap: the dedupe happens before any research, so a day where nothing new opened costs you a Google search and nothing else. New businesses appear constantly, and a daily run means you hear about them within a day of them showing up on Maps rather than whenever you next remember to look.

Pair it with minLeadScore so a quiet day stays quiet instead of emailing you three businesses you would never call.

Send new leads wherever you actually look

The default emails you a report. Most people do not read email that closely, and a lead you notice on Thursday for a business that opened Monday is a worse lead.

on-new-leads is an extension point, which means you can hand it your own workflow at install time and the package will call that instead. It receives the new leads, how many there are, and the notify list. What you do with them is entirely yours: post to a Discord channel, drop a Slack message in the room your sales people already sit in, push straight into your CRM, fire a webhook at your own backend, or load them into a dialer.

The contract is small. Build a workflow that accepts those three inputs, do whatever you want inside it, and bind it to on-new-leads. Nothing else in the package changes.

Call it from your own app

Add a webhook trigger to lead-gen and you get a URL you can POST to. Whatever JSON you send becomes the run's input, exactly like the Test data panel, so you can drive different searches per call:

curl -X POST "<your-webhook-url>" \
  -H "Content-Type: application/json" \
  -d '{
    "serviceTypes": ["dental offices"],
    "searchLocations": [{ "name": "Austin, TX" }],
    "maxLeadsPerRun": 25
  }'

That turns lead generation into something your own product can ask for. A user picks a city in your app and you kick off a search for that city. A new client signs up and you run their territory. A sales rep types a business type into an internal tool and gets a call list back, without anyone opening QuickFlo at all.


Advanced

How the score works

The score is calculated in code, so the same business always gets the same number, and score_reasoning on every lead shows exactly which signals contributed what.

Each signal produces a value between 0 and 1, and scoringWeights decides how much each one counts. The weights get divided by their own total, so they do not have to add up to 100. Setting one to 0 turns that signal off.

Signal Default What it measures
reviewVolume 25 Number of reviews, as a rough proxy for how many customers they deal with
reviewPain 40 How closely the reviews match your painCriteria
afterHoursGap 10 Opening hours suggest nobody covers nights or weekends
missedCallMentions 15 Reviewers saying their calls went unanswered
hasWebsite 5 Has a website
hasPhone 5 Has a phone number
employeeFit 0 Headcount versus idealEmployeesMin and idealEmployeesMax
yearsInBusiness 0 Ten years or more scores full marks
hiringSignal 0 Currently posting jobs
adSpendSignal 0 Currently running ads
contactConfidence 0 How sure the research was about the decision-maker it named

Two behaviours are worth knowing about before you retune.

When the research cannot find something, it scores in the middle rather than at zero. Headcount and founding dates are frequently unavailable for small private companies. If a blank counted against a business, the only ones able to score well on those signals would be large public companies, which is the opposite of what most people want.

maxEmployees and excludeBusinessTypes remove a business from the results rather than scoring it low. If a search returns AT&T, that is not a weak lead, it is the wrong result, and giving it a low score still leaves it in your list. Removed businesses come back marked Disqualified with the reason.

Scoring for businesses that sell to businesses

Review-based signals do not work here. An answering service's customers do not review it on Google Maps, so reviewVolume and reviewPain become noise and the ranking drifts toward whichever company is biggest. Shift the weight onto company facts instead:

{
  "scoringWeights": {
    "reviewVolume": 5,
    "reviewPain": 10,
    "afterHoursGap": 0,
    "missedCallMentions": 5,
    "hasWebsite": 5,
    "hasPhone": 5,
    "employeeFit": 30,
    "yearsInBusiness": 15,
    "hiringSignal": 15,
    "adSpendSignal": 10,
    "contactConfidence": 0
  },
  "idealEmployeesMin": 25,
  "idealEmployeesMax": 500,
  "maxEmployees": 2000,
  "excludeBusinessTypes": "government, bank, corporate office, courier"
}

idealEmployeesMin and idealEmployeesMax set the headcount range you want. Businesses inside it score full marks on employeeFit, smaller ones score proportionally, and larger ones fall away quickly.

Replacing the research or the handoff

Two steps are built to be swapped, and each ships with a working version.

enrich-lead turns one search result into a scored lead. Replace it to use your own data provider or your own scoring. Yours has to return the same fields, including lead_score and priority.

on-new-leads runs when a batch finds something. It receives { leads, leadCount, notifyEmailTo }, where leads is the full enriched records, highest score first. The default sends an HTML report with a CSV attached. See "Send new leads wherever you actually look" above for what to do with it.

If you only want to change the numbers, the weights live in the score-lead step and can be edited directly.

Table and outputs

The leads table is keyed on each business's Google Places ID, which is what makes the deduplication reliable across runs. A run returns { found, candidates, new, leadCount, notified }.

What’s inside

One install, the complete system.

Workflows

1 included

  • Lead Gen

Sub-workflows

3 included

  • Lead Gen Search Places
  • Lead Gen Enrich Lead
  • Lead Gen Notify Default

Dashboards

1 included

  • Lead Generation

Data stores

1 included

  • Leads

Configure during install

Set up what it needs. QuickFlo handles the wiring.

You’ll connect or provide these requirements during guided setup, before anything changes.

Connections

3 connections to map during installation

  • Google Places
  • Anthropic
  • Smtp

Extension points

Designed for your team to make their own.

This package includes clearly defined areas your team can customize without forking or rebuilding the rest of the solution.

Enrich a lead

Choose during setup

Turns one raw Places result into a scored lead. Receives the candidate fields plus your targeting context and scoring config. A replacement must return the same lead shape, including lead_score and priority. Swap this to plug in your own data provider or scoring model.

On new leads detected

Customize when needed

Runs when a run finds new leads. Receives { leads, leadCount, notifyEmailTo }. The default emails an HTML report with a CSV attachment. Swap for a CRM push, Slack message, webhook, or dialer load.