Copy · paste · fill in five lines

the permit lead prompt

Every building permit pulled in your county is a public record: who is building, what, where, and roughly what it costs. This is the prompt that turns that into a scored lead list and drafted outreach — for any trade, in any US county.

Paste it into Claude Code, fill in the five lines at the top, and let it work.

PERMIT LEAD PIPELINE — build this for my business.
Work in phases. Stop and report after Phase 1. Do not build anything before I confirm.

=== MY BUSINESS (fill in) ===
What I do:              [e.g. commercial roofing / residential solar / HVAC service / pool builder / restoration]
Where I work:           [County, State — plus neighbouring counties if relevant]
Who I sell to:          [contractors / property owners / GCs / architects / both]
Job size worth chasing: [e.g. $25,000+]
A good lead looks like: [1–2 sentences in plain English]

=== PHASE 1 — FIND OUT WHAT'S ACTUALLY THERE (build nothing yet) ===
Find how this county publishes permit records. Check in this order:
  1. An ArcGIS REST service — look for the FeatureServer/MapServer behind any public
     permit map the county publishes. Usually open, no API key, and by far the best source.
     Get the layer list and query it directly.
  2. A Socrata or open-data portal.
  3. A public permit search portal (Accela Citizen Access, Tyler EnerGov, CityView, OpenGov).

Then report back honestly:
  - The exact endpoint(s) and layer names
  - Every available field
  - ACTUAL FILL RATES, not the schema. For each field I'd need — contractor name, owner
    name, address, valuation, work description, dates — run real COUNT queries and tell me
    what percentage is actually populated. A column existing is not the same as it having
    data in it. Assume it's empty until you've counted.
  - Whether emails or phone numbers exist anywhere (they essentially never do — say so plainly)
  - How current the data is, and how far back it goes
  - Any access blocks you hit, and what you did about them

Do NOT write the scraper yet. Tell me what's real first, including what ISN'T available.

=== KNOWN TRAPS (check every one of these) ===
  - Many county web portals sit behind a WAF that returns 403/000 to curl and other
    scripted clients. The ArcGIS REST endpoint usually is NOT blocked. If you need the
    portal itself, drive it with a real browser, not a script.
  - ArcGIS services are often Oracle-backed, where '' IS NULL. A filter like
    `FIELD <> ''` is NEVER true and silently returns zero rows. Only ever use IS NOT NULL.
    If a count comes back 0, suspect your WHERE clause before you believe the data is empty.
  - Trade permits (electrical / plumbing / gas / mechanical) are usually the highest volume
    AND the most likely to have the contractor column present but completely blank.
    Check them separately from building permits.
  - Paginate with resultOffset / resultRecordCount; page size caps around 1000–2000.
  - Dates usually come back as epoch milliseconds. Filter with something like
    `ISSDATE > CURRENT_TIMESTAMP - INTERVAL '30' DAY`.
  - Issue date is the "job is starting now" trigger. Application date is not.

=== PHASE 2 — BUILD IT (after I confirm Phase 1) ===
Write a script that pulls permits from the last N days and produces an Excel workbook:
  - Summary tab: total permits, total declared value, breakdown by permit type
  - Leads tab: only rows with a name I can actually contact
  - All Permits tab: everything, sorted by value

Requirements:
  - SCORE each permit for MY business specifically. Derive the scoring from what I told you
    above — the permit types, work-description keywords, and valuation bands that mean a
    real job for my trade. Show me the scoring rules in plain English so I can correct them.
  - REMEMBER what you already pulled, so when I run this weekly I only see what's new.
  - Segment rows into: has-contractor-name / has-owner-name / address-and-scope-only.
    Never merge these or imply the third group is contactable.
  - Run it against the live source and show me the REAL numbers before you tell me it works.
    If something is thinner than expected, say so instead of smoothing it over.

=== PHASE 3 — OUTREACH DRAFTS ===
Take the top N leads and draft one message each.
  - Reference the specific permit — scope and address — in the first line, and say it came
    from public county records
  - Never quote the declared valuation back to them. It's a filing estimate, it's often
    wrong, and it reads like surveillance
  - One clear ask. Short. No fake familiarity, no invented mutual connections
  - Include who I am and a real opt-out line
  - Nothing that implies the county sent me or endorsed me

Put them in one file as a review queue. Do not send anything. I'll read them and tell you
which ones go.

=== RULES ===
  - Permit records are public and using them for outreach is lawful. Implying county
    affiliation is not.
  - Every commercial email needs real sender identity, a physical address, and a working opt-out.
  - Property owners are consumers, not businesses: no autodialing or texting them off this
    list, and in most states soliciting home improvement work from homeowners needs a license.
  - If you can't find or verify something, say so. A short honest list beats a padded one.

why it’s shaped like this

The load-bearing part is Phase 1 — the instruction to find out what’s really in the data and then stop. Almost every way this goes wrong is the same failure: assuming something instead of counting it, then building a campaign on top of the assumption.

We built this against Baltimore County first — 9,127 permits and $717M of declared work in 90 days. Every one of the traps below is something that actually bit during that build, not a hypothetical.

The column exists. The data doesn't.

A schema will happily list a CONTRACTOR field on every permit type. In Baltimore County it was filled on about 5% of building permits — and on exactly zero electrical, gas, or plumbing permits, which are the highest-volume ones. Counting is the only way to know.

An empty string is never equal to an empty string

These services are usually Oracle-backed, where '' IS NULL. A filter like FIELD <> '' can never be true, so it returns zero rows and looks exactly like missing data. This one cost us a wrong conclusion mid-build.

The website blocks you. The data doesn't.

County sites often sit behind a WAF that refuses scripted requests outright. The ArcGIS endpoint behind their public permit map is usually wide open — no key, no rate limit.

There are no emails. Anywhere.

No county permit feed carries an email address or phone number. Anything attached to a lead came from somewhere else and needs verifying before you write to a stranger with your name on it.

fitting it to your trade

The scoring is derived from what you write in the first five lines, so be specific there. What a permit means differs completely by who you are:

RoofingReroof and storm-repair permits, plus any new build reaching dry-in.

SolarPV and electrical service upgrades — and new residential construction 6–9 months out.

HVAC / plumbingMechanical and plumbing permits, plus commercial tenant fit-outs.

Pools / landscapePool, deck, grading and hardscape permits on residential parcels.

Suppliers / distributorsLarge commercial permits — the GC gets bought out within about 60 days.

RestorationDemo, fire and water-damage repair permits, filed fast after an event.

the part everyone skips

The prompt ends by drafting messages into a review queue and sending nothing. Keep it that way. Unreviewed cold email to scraped addresses is the fastest way to get your company domain flagged as spam — and once that happens, your estimates and invoices stop reaching people too.

AI does the finding, the sorting and the drafting. A person decides what goes out. That still takes the job from a week to about twenty minutes, which was the point.

want the whole thing set up properly?

The prompt is yours to run for free — that’s the point of the page. If you’d rather have it wired into your CRM, running on a schedule, and tuned to the trades and job sizes you actually chase, that’s what we do.