If you sell to local businesses, roofers, plumbers, HVAC, landscapers, dentists, auto dealerships, med spas, whatever, you already know Google Maps is the best source.
What you probably don't know is how much of it you're not getting. Too many people expect too little from it, and from the vibe-coded tools that sell you 50,000 listings for a lollipop.
Paging deeper from one map centre keeps handing you the same central neighbourhoods. Coverage comes from more viewpoints, not more pages, and we measured the gap in Houston on the query "roofing contractor", same centre, same spend of $0.38.
Deep paging from a single point returned 255 businesses. A 76-point grid returned 1,061, of which 977 sat inside 25km of the centre. That's 4.2x the results for the same money.
Two honest caveats, because the number gets quoted at us. Those are raw Google Maps results for that query, deduplicated by place ID and filtered only by distance, so they're not all confirmed roofers. And 255 is a floor rather than a ceiling: that provider was still returning full pages when it hit the 15-page limit, so it hadn't run out either.
That's the first thing, and the reason to keep reading. It's not the thing I want to talk about.
We just finished the work that lets you run all of it from your own application. Your CRM, your Clay table, your n8n workflow, your Python script, your Claude project. You get an API key, you point your LLM at the developer docs and the feature list, and it builds you a pipeline. You can go months without loading our site.
What the API lets you do
Count before you spend
POST /api/v1/count tells you exactly how many of your saved leads match any filters you choose, and it's free. So before you pay to find contacts, verify emails or enroll leads you imported, you can see how many actually need it.
Search whole areas
POST /api/v1/searches takes a keyword and a list of areas, and we sweep each one with the same grid the Search page uses, live against Google Maps, as a job. Poll it or let a webhook tell you it's done, then read the leads back with every filter we have. A name that several towns share, like the four Houstons in our US list, is never guessed: you get the candidates back and pick one. One token per new business, and you never pay twice for the same listing. The grid estimate is free if you want the size first.
Enrich
Every business a search finds arrives enriched at no extra cost. Its website is checked against 1,519 named technologies, including 400 chat widgets, 185 booking systems and 65 CRMs, vertical ones like ServiceTitan and Jobber among them. Plus ad pixels, DMARC, SSL, whether they have a contact form or online booking, domain age, and a relevance check that reads their actual website and tells you whether this roofer is a roofer, with the sentence from the page that proves it.
Pay once, and it stays fresh
A lead that's enrolled in enrichment gets re-checked about once a month for as long as you keep it, and that never touches your monthly tokens. Leads a search finds are enrolled for free. A lead you import you can enrich at five businesses per token, or enroll at two businesses per token, once, which enriches it right away and keeps it re-checked. There's a filter for enrolled or not, so your code always knows which leads are kept current.
Contacts
One call finds the named humans and SMTP-verifies their mailboxes, at 2 leads per person found and nothing where nobody turns up. About 70% of attempts come back with a name. About 25% come back with a name and a mailbox that answered, and that varies by segment. We measured it on 200 US businesses across ten trades this month, not a brochure figure.
Contact discovery and verification run as jobs rather than blocking. You get a job ID back and poll it, or let a webhook tell you when it lands. Checking four thousand businesses isn't a request you want held open.
Get the contacts into your own tools
GET /api/v1/people returns every contact we've found, with their title, their company and whether their mailbox is verified. Filter by seniority, verification status or LinkedIn profile, and your CRM or sending tool gets a list it can use straight away.
Sync what you already have
Send us the businesses already in your CRM, up to 1,000 per call, and get their IDs back. Importing is free. Do it before your big search, because a search that later finds a business you imported doesn't charge you for it: we match it on its website and stamp the Google place ID onto your row. Enrich them at five businesses per token, or enroll the ones that matter, and they're ready for contact discovery and verification like everything else.
Verify what you already have
Contact discovery already SMTP-verifies the addresses it generates at no charge, so you never pay twice for that. Standalone verification is included too, and is for addresses you already hold and we never found: the ones that came in with your own import, or anything sitting in your CRM. Included, up to 2,000 per call, and a re-check inside 90 days is free, so running a list again before a campaign costs nothing for anything checked recently.
Query everything
Over 120 filters. Every roofer in Houston with more than 100 reviews, no Facebook pixel, no online booking, and a verified contact. That's one request.
Signals
This is the part a static database can't do. When we re-check an enrolled lead, we tell your application what changed. A landscaper installs a booking widget. An HVAC company adds a Facebook pixel. A dentist swaps their chat widget. A plumber's review count grows 5% in a month. Your system hears about it the same month, and we can push it to you rather than making you poll for it.
On the push: subscribe an endpoint and we sign every delivery, HMAC-SHA256 over the timestamp and the body, so you can prove it came from us. Failed deliveries retry five times over about 12 hours, long enough to fix a broken endpoint and still get the event. There's a delivery log you can read, and a test-fire endpoint so you can prove your side works before a real signal ever arrives.
Two rules on that, because they matter. A change event only fires between two successful enriched runs, so a failed scrape never reads as "they removed it". And a disappearance needs two consecutive misses before we call it gone. We'd rather tell you nothing than tell you something wrong.
Optimal setup depends on how you sell
If you work the phones
Consider not paying for contact discovery. Between 97% and 99% of the US businesses we hold have a phone number, across every trade we've checked. Roofers 98%. HVAC 98.9%. Plumbers 97.7%. Electricians 99.4%. Landscapers 97.2%. Phone comes off the Google Business Profile, so it barely moves by industry. We also read the phone numbers businesses list on their own websites and flag when they don't match Google.
Spend your whole allowance on volume. The signals come free. Pull the market, filter on relevance and the signal that means "something just changed", and hand your dialer a list where every row has a reason to be called today.
If you work email
Invert it. Volume is not your best friend, verified mailboxes are. Budget roughly three leads per business you actually want to reach: one to find and enrich it, one to find and verify the human.
On the $39 plan that's 3,750 businesses worked properly and about 669 verified contacts, roughly six cents a contact. On the $99 plan, 11,250 businesses and about 2,000. Filter hard before you spend. Ask your LLM which filters fit what you sell.
If you do both
And most people do. Run them as two lanes off one pull. Phone gets the whole market because phone coverage is near total. Email gets the slice that passed relevance and has a verified mailbox. Same data, two exports, no double spend, because you never pay twice for a listing you already own.
What to hand your model
Every endpoint is documented in an OpenAPI spec that any competent model can read and build against without asking you what the fields mean. There's a data dictionary listing every field we ship, generated from the live export so it can't drift, and a guide written for the agent rather than for you, covering what a blank value does and does not tell you, and where our coverage is weak. Rate limits are counted in leads and printed on the pricing page: on the $39 plan that's 60,000 leads read a minute.
If you're using Claude or Cursor, skip the docs and connect the MCP server at lyreleads.com/mcp. Fourteen tools, one config block, and your assistant can run the same grid searches, count, enrich, find contacts, verify emails and check job status directly.
Go point your AI at it. Tell it what you sell and how you sell it, and let it build the thing.
Lyre Leads