Build your own permit-lead tracker with AI

Copy one prompt into Claude Code, Codex, Cursor or any AI coding assistant, and it will walk you through building a small tracker for one city's open-data permit feed: last week's permits, the contractor on each, and flags for new, busy and expiring. It is free and you own the code. We use the City of Austin feed as the example because it is public, needs no login and is well documented.

Jump to the promptSee what our finished file looks like (CSV)

What you will have at the end

How it works

  1. Paste the prompt into your AI assistant in an empty folder.
  2. Work one milestone at a time. Each milestone ends with an acceptance check the AI has to run and show you, such as matching its row count against the city's own count.
  3. Schedule it for Monday morning on your own computer.

The prompt

Free to copy and change. It uses only the city's official API: no web scraping, no logins, no captchas.

You are helping me build a small permit-lead tracker for ONE city. Work in milestones. After each milestone, run the acceptance check, show me the output, and stop until I say "next".

DATA SOURCE
- City of Austin, TX "Issued Construction Permits" on the city's open-data portal (Socrata).
- Dataset page: https://data.austintexas.gov/d/3syk-w9eu
- API endpoint (JSON, no login): https://data.austintexas.gov/resource/3syk-w9eu.json
- It uses SoQL query parameters: $select, $where, $order, $limit, $offset.
- Columns I care about: permit_number, issue_date, permit_type_desc, permit_class_mapped, work_class, description, status_current, expiresdate, total_job_valuation, permit_location, original_zip, contractor_company_name, contractor_trade, link.
- Before you write any parsing code, fetch 3 rows and print the real column names. If a column above is missing, tell me. Do not guess a replacement.

STACK
- Python 3, standard library plus "requests". One file: tracker.py. Output goes to ./out/.
- No database. Keep a local copy of the last 13 months of permits in ./out/history.csv.

MILESTONE 1: pull one week
- Pull every permit with issue_date from last Monday 00:00 to last Friday 23:59 (city time).
- Page through results with $limit=1000 and $offset until a page comes back short.
- Wait at least 250 ms between requests. On HTTP 429 or 5xx, back off (4 s, 16 s, 36 s...) and retry, up to 6 tries, then stop with a clear error.
- Optional: read a free Socrata app token from the environment variable SOCRATA_APP_TOKEN and send it as the X-App-Token header. Never print it.
- Save ./out/week.csv.
- Acceptance check: print the row count. Then run a second query with $select=count(*) and the same $where, and confirm the two numbers match. If they do not match, stop and tell me.

MILESTONE 2: clean the contractor names
- Uppercase, turn "&" into "AND", strip punctuation, squeeze spaces.
- Build a company_key by also dropping THE and legal suffixes (LLC, INC, CORP, CO, LTD, LP, LLP, PLLC).
- Keep only rows where the contractor looks like a business (has a suffix or a trade word such as ELECTRIC, PLUMBING, ROOFING, CONSTRUCTION, HOMES). Rows that look like a homeowner or a person stay in the file but get business=false.
- Acceptance check: print the 20 most common company_key values with their raw spellings, so I can eyeball bad merges.

MILESTONE 3: flags
- new_contractor = this company_key has zero permits in this city in the 12 months before the week. This needs ./out/history.csv, so first back-fill 13 months (same paging and backoff rules).
- busy_contractor = 3 or more permits this week (make the 3 a setting).
- expiring_soon = expiresdate falls in the next 30 days and status_current is not Final, Expired or Withdrawn. Print the distinct status_current values first and let me confirm the list.
- Acceptance check: pick 3 contractors flagged new and show me the history query that proves they had no permits before.

MILESTONE 4: the Monday file
- Write ./out/permits-YYYY-MM-DD.csv with one row per permit, the three flags, and a source_url (use the row's link if present, else the dataset page) and a pulled_at timestamp.
- Missing values stay blank. Never write 0 for a value the city did not publish. Job value is blank on many rows, and blank is not zero.
- Add a header block in ./out/run-report.txt: rows pulled, rows by status, how many rows have no job value, how many have no contractor name.
- Acceptance check: open the CSV and show me 5 rows with every column.

MILESTONE 5: fail loudly
- If the API returns an error that mentions a missing column, or returns something that is not a JSON list, stop with an error that names the column or shows the response. Do not write an empty file and call it a quiet week.
- If this week's row count is under 30% of the 8-week average, write a warning at the top of run-report.txt.
- Acceptance check: change one column name in the code to a fake one, run it, and show me that it fails with a clear message. Then change it back.

MILESTONE 6: run it every week
- Show me how to schedule it for Monday 6 AM on my machine (cron on Mac/Linux, Task Scheduler on Windows).
- Acceptance check: print the exact schedule line and the command it runs.

RULES
- Use only the official city API. No scraping of web pages, no logins, no captchas.
- Do not add phone numbers, emails or homeowner names to the output, even if a column has them.
- If anything about the data surprises you, stop and ask me instead of guessing.

What it can't do (honest limits)

Build it or rent it?

Build it with this promptOur weekly file
CostFree, plus your time$150 per month or $490 per year, one metro (pricing)
CitiesOne, and you adapt it for each new oneYour pick of Austin, Chicago, Cincinnati, New Orleans or Mesa
When a city changes its feedYou fix itWe fix it
Property facts on each rowNot includedAustin, Chicago and Cincinnati
Expiring and expired home permitsIf your city publishes permit statusAustin, Cincinnati, New Orleans and Mesa
Missing valuesUp to you (the prompt says leave them blank)Left blank, never filled with zero
DeliveryYour computer, if it is awakeA shared Google Drive folder every Monday

Want it kept running for you?

Want 5 cities kept running, flagged and delivered every Monday? That's the weekly file. We keep the permit feeds for Austin, Chicago, Cincinnati, New Orleans and Mesa working, plus the county, Census and FEMA sources behind the property facts. Each plan covers one metro you choose, with one CSV and Excel file every Monday.

Free sample (25 Austin rows, CSV)Order monthly by emailOrder yearly by email

Prefer to pay per row and run it yourself? Contractor Permit Signals on Apify covers the same 5 cities, and we keep it working.

Questions

Is the prompt really free?

Yes. Copy it, change it, use it for your business. No sign-up.

Which AI assistant should I use?

Any assistant that can create files and run Python on your computer. The prompt is plain text and doesn't depend on one product.

Can I point it at a different city?

Yes, if that city publishes permits through an open-data API. Swap in the dataset address and redo milestones 1 to 3 for its column names. Check the city's data license before you use the data commercially.

Why are you giving this away?

The code is the easy part. The ongoing work is keeping several city feeds working every week as they change, and that is what the weekly file pays for.