This walkthrough takes you from an empty folder to a filtered CSV of local businesses, with Claude Code doing the API calls. We’ll use plumbers in Austin as the example. Swap in your own niche and city.
You need three things: Claude Code installed, a LeadMerlin account (the free plan includes 100 lead credits), and your API key from the dashboard. Keys start with lm_.
Step 1: Keep the API key out of your files
Put the key in your environment, not in the skill or the project:
# ~/.zshrc or ~/.bashrc
export LEADMERLIN_API_KEY="lm_your_key"
Open a new terminal so the variable is loaded. When you ask Claude Code to use it, it can read $LEADMERLIN_API_KEY in its shell commands without the key ever appearing in a file you might commit.
Step 2: Add the skill
Claude Code loads skills from .claude/skills/<name>/SKILL.md in your project (or ~/.claude/skills/ for every project). Create the folder:
mkdir -p .claude/skills/leadmerlin
Copy the skill text from the docs page into .claude/skills/leadmerlin/SKILL.md. Add a frontmatter block at the top so Claude Code knows when to use it, plus one line telling it where the key lives:
---
name: leadmerlin
description: Search local businesses by niche and city with the LeadMerlin API, enrich them (owner names, verified emails, phone line types, website tech) and export CSV. Use for lead generation and local prospect lists.
---
API key: read it from the LEADMERLIN_API_KEY environment variable and send it
as the x-api-key header. Never write the key into files.
# LeadMerlin — Search & Enrich Local Business Leads
...rest of the skill from the docs...
Restart Claude Code in that folder. The skill now shows up when you ask for leads.
Step 3: Dry-run on the demo endpoints (no credits)
Before spending credits, have the agent walk through the flow against the demo API. It uses the same shapes as production, returns fixture data, and marks every response with "demo": true:
Use the leadmerlin skill against the demo endpoints only. Look up “austin”, start a plumber search, poll the job, fetch the results, and show me the fields you get back.
Behind the scenes it will run calls like:
curl "https://api.leadmerlin.com/api/v2/demo/locations?q=austin"
{"demo":true,"locations":[{"location_code":1026201,"name":"Austin","region":"Texas","country":"US","type":"City","full_name":"Austin, Texas, US"}]}
The job status response tells you how many results there were and how they broke down:
{
"job_id": "demo-job-plumbers-irvine",
"type": "search",
"status": "completed",
"keyword": "plumber",
"total_unique": 2,
"enriched_count": 2,
"skipped_count": 0,
"off_niche_count": 0,
"strictness": "moderate",
"category_facets": { "Plumber": 2 },
"progress": 100,
"demo": true
}
Each business in the results carries owner, email, phone and phone_type at the top level, plus nested contact.all_emails[] (each with a status of verified, catch-all, invalid or unverified), reputation (rating, reviews, claimed), services and web.tech (CMS, chat widget, analytics, ad pixels). The docs list every field.
Step 4: Pick a sharp keyword
Generic words pull in businesses that only match by coincidence. Ask the agent to check first:
Before searching, call /v2/suggest for “plumbing” and tell me the best Google categories and keywords.
/v2/suggest is free. It returns real Google Business Profile categories and sharper search phrases. For plumbing you would typically choose plumber, or drainage service if you only want drain specialists.
Step 5: Run the real search
Search “plumber” in Austin, TX with moderate strictness. Poll every 5 seconds until it completes, then summarize the category facets and how many listings were skipped or off-niche.
The request the agent sends:
curl -X POST https://api.leadmerlin.com/api/v2/searches \
-H "x-api-key: $LEADMERLIN_API_KEY" \
-H "content-type: application/json" \
-d '{"keyword":"plumber","location_codes":[1026201],"strictness":"moderate"}'
How credits work, so the summary makes sense:
- 1 credit per business that has a website. Those are the ones that get crawled and enriched.
- Listings without a website are free. They come back with
skippedstatus, still with Maps data like phone, address and rating. - Off-niche listings are free. The niche filter drops businesses that only matched the keyword by coincidence and reports them as
off_niche_count. - Failed enrichments are refunded automatically.
You can pass up to five location_codes in one job if you want several cities at once.
Step 6: Filter before you export
This is where an agent beats a spreadsheet. Ask for the list you would actually work:
From the results, keep businesses where the best email is verified and not role-based (skip info@ and office@), rating is at least 4.0, and the website has no chat widget. Sort by Google Maps rank.
Each condition maps to a real field: contact.all_emails[].status, contact.all_emails[].is_role_based, reputation.rating and web.tech.chat. The agent can also read web.pages[].text, which is the crawled site text, to find things like “24/7 emergency” or “financing available”.
Step 7: Export the CSV
Export the filtered list to plumber-austin-leads.csv using the CSV header from the skill.
The skill defines a fixed column order: rank, name, category, website, owner, email, phone, phone type, address, rating, reviews, then up to five emails and phones with their status and carrier, then up to five crawled pages. That imports cleanly into most CRMs and sending tools.
Step 8: Use the data in the first line
The point of enrichment is a first line that could only go to that business. A useful prompt:
For the first 10 leads, draft a one-sentence opener referencing something specific from their website text or reviews. No flattery, no claims we can’t back up.
Review every message yourself before sending. Also make sure your emails follow the rules for commercial email. Our CAN-SPAM checklist for local business outreach covers the basics.
Troubleshooting
- 401 errors: the key isn’t reaching the request. Run
echo $LEADMERLIN_API_KEYin the same terminal Claude Code was started from. - “Insufficient credits”: your balance is 0. Check with
GET /v2/usage. With a low balance, a search enriches as many top-ranked businesses as the balance covers; passmax_leadsto cap it. - Weird businesses in results: use a more specific keyword, or set
"strictness": "strict"to drop adjacent trades as well. - Fewer emails than expected: only businesses with websites are enriched, and some sites publish no email at all. Phone and Maps data are still there for those.
That’s the whole loop: describe the list you want, let the agent run the API, and spend your time on the messages.