Marion County + Ocala Property Lead Pipeline | Feasibility & Master Plan

Property Lead Pipeline: GIS Lookups on Code-Enforcement & Lien Notices

City of Ocala and Marion County, Florida. Feasibility assessment and automation master plan.

Executive Summary

Goal: an automated pipeline that finds Ocala + Marion County properties carrying overgrown-lot / weed / nuisance code-enforcement notices or recorded liens, joins each to GIS parcel data (owner name, mailing address, situs, geometry), and emits a deduped, map-ready lead list.

Verdict: FEASIBLE

The GIS join is the easy part. Clean, public parcel and owner data is confirmed live and queryable. The friction sits on the code-enforcement and lien side, where there is no single clean API, so it takes targeted scraping plus fuzzy address-to-parcel matching. A county-only MVP ships in about a day; the full two-jurisdiction system in three to four.

Confirmed Data Sources

Status reflects live probes run during the assessment (2026-06-09). “Needs check” means the endpoint exists but timed out from the dev sandbox. That is almost certainly a geo or firewall block, so re-verify from the Contabo production host.

SourceEndpointStatusRole
FL Statewide Cadastral
(FDOR 2025)
services9.arcgis.com/Gh9awoU677aKree0/…/Florida_Statewide_Cadastral/FeatureServer/0 Verified Join backbone. Public, no token, queryable, 2,000 rec/req. Fields: OWN_NAME, OWN_ADDR1/2, OWN_CITY/STATE/ZIP, PHY_ADDR1/2 (situs), S_LEGAL, PARCEL_ID, CO_NO. Filter CO_NO=42 for Marion.
County parcels (self-host) gis.marionfl.org/public/rest/services/General/Parcels/MapServer Needs check Richer geometry fallback. Exists; timed out from dev sandbox. Run from Contabo.
County code-enf lien search bcc.marionfl.org/billing/paycode-demo.aspx Needs check Violation and lien lookup. Scrape target. Exists; timed out.
Marion Clerk official records marioncountyclerk.org records search Needs check Recorded liens by document type (municipal / code-enforcement lien).
Ocala code enforcement ocala.granicus.com + ocala.legistar.com board agendas Needs check Case notices live in board agendas / minutes (PDF + HTML). Primary Ocala path.
Ocala iWorQ portal (guessed) ocalafl.portal.iworq.net Blocked 404, does not exist. Discard. (An Ollama-suggested lead that failed the live check.)
Marion Property Appraiser (AGOL) services3.arcgis.com/hrGHbYKdjpN9Dagg/…/Parcels Blocked Token required (private). Discard; use FL Cadastral instead.

Ollama Pro Research Test

I ran deepseek-v4-pro at the endpoint-discovery question. It knew the territory, naming Granicus, the Clerk records system, and the Geocortex GIS pattern. Better still, it returned UNKNOWN rather than hallucinate exact endpoints. But the one lead it gave with confidence, the Ocala iWorQ URL, 404'd on the live check.

Conclusion: Ollama Pro is an inference engine with no live web access. It is the wrong tool for discovery, and the right tool for the normalize / fuzzy-match / extract layer (free, flat-fee). Discovery must use live fetch tools. This split matches the house economic rule: the subscription model does the bulk work, live tools verify.

Architecture

Seven stages. Live tools own discovery; Ollama Pro owns text normalization; plain Python owns the GIS join and output.

  1. Discovery (live tools, monthly re-verify)WebFetch, curl, and chrome-devtools confirm endpoints, then capture iWorQ and Granicus URLs into endpoints.json.
  2. Fetch (Python cron)Ocala Granicus/Legistar agendas, County bcc.marionfl.org lien search, Clerk official records.
  3. Normalize (Ollama Pro)Extract address, case number, and fine from messy text; clean and standardize address strings.
  4. Parcel join (Python)Query FL Cadastral CO_NO=42 by parcel or address for owner, mailing address, geometry.
  5. Geocode fallback (free)Census and Nominatim fill any unmatched situs addresses.
  6. Dedupe (ledger)14-day cooldown ledger emits new-only leads.
  7. OutputCSV + GeoJSON map + email digest.

The Two Hard Parts

  1. Ocala has no clean case API. Notices live in Code Enforcement Board agendas and minutes (Granicus plus Legistar). That means PDF and HTML parsing, which is inherently brittle. This is exactly where Ollama Pro earns its keep: pulling structured cases out of agenda text.
  2. Address-to-parcel matching is fuzzy. Code-enforcement situs addresses are abbreviated or typo'd; cadastral PHY_ADDR1 is formatted differently. Ollama normalization plus a geocode fallback closes most of the gap. Expect roughly 85-90% auto-match, with the rest flagged for manual review.

agent-os Build Plan

StageToolOutput
0. Discover (monthly)WebFetch / curlendpoints.json, verified live URLs
1. Pull OcalaPython + Granicus/Legistar scrapeRaw cases (address, case #, fine, date)
2. Pull CountyPython scrape bcc.marionfl.org + ClerkRaw violations + recorded liens
3. NormalizeOllama Pro (deepseek_pro / kimi)Clean address + structured fields
4. Parcel joinPython → FL Cadastral CO_NO=42+ OWN_NAME, mailing address, geometry
5. Geocode fallbackCensus / Nominatim (free)Fill unmatched
6. DedupeLedger /var/lib/agent-os/weed-liens/New-only, 14-day cooldown
7. OutputPythonCSV + GeoJSON + Leaflet map + email

Pattern: pure-Python drainer mirroring index-submit-drainer.py; weekly cron on Contabo 194; reuses the existing agent-os email-zip + ledger plumbing.

MVP Cut

County-only path, skipping Ocala Granicus (the hardest piece): bcc.marionfl.org lien search → Ollama normalize → FL Cadastral join → CSV. That alone gives you Marion County overgrown-lot and lien parcels with owner names and mailing addresses, a usable lead list on day one. Ocala agendas and Clerk recorded-liens come in phase 2.

Effort & Phasing

  • Phase 1, MVP (county only): about 1 day
  • Phase 2, Full (Ocala agendas + Clerk + map + weekly cron): about 3-4 days, most of it absorbed by Ocala PDF brittleness