Software for Municipalities: Fixing the Permit, 311 and Legacy System Mess
Build only the layer where your city is genuinely different: routing, fees, the resident front door, and the cross-system view. Keep Munis, Laserfiche and ArcGIS as your systems of record. In Digital Heroes delivery experience across 2,000+ projects, a focused first release (one permit type end to end, plus 311 intake and status) runs $60k to $130k and ships in 12 to 16 weeks. A full platform covering multiple departments, inspections, payments and legacy migration runs $150k to $400k phased over 6 to 12 months. If your workflow changes require a vendor change order, you are already paying more than a build costs.
Why permitting and 311 software makes or breaks a city operator
It is 9:40 on a Tuesday at the community development counter. A contractor wants to convert a 6,000 square foot retail bay into a restaurant. The permit tech opens Accela or Tyler EnerGov to start the record, switches to ArcGIS to confirm the parcel and the overlay zone, opens a spreadsheet a senior planner maintains to compute the plan check fee off the valuation table, emails the Fire Marshal because Fire review is not in the workflow, and tells the contractor to come back Thursday because the grease interceptor question belongs to the sanitary district and nobody at the counter can answer it. In the intake work we have done for community development departments, that counter step alone runs 22 to 35 minutes per commercial application across three systems, and roughly a third of applications get sent back for something the city could have checked in ninety seconds.
Meanwhile the same building holds four other stacks that do not speak: Munis or Naviline for fees and the general ledger, Cityworks or Cartegraph for work orders, SeeClickFix or QAlert for resident reports, Laserfiche for records, Granicus for agendas, and a payments portal bolted on the side. Every seam between them is a person. The clerk re-keys. The inspector re-keys at 4pm from paper cards. The finance analyst reconciles a nightly CSV that lands on an FTP folder because the 1990s AS/400 has no API.
None of this is a technology failure exactly. Your city's process is local, and the software was designed to be the same in Fresno and in Fargo. So the difference gets absorbed by staff hours, by 6 to 8 week resubmittal cycles, and by the council member who calls the City Manager because a constituent's downed-limb report from March is still open.
Problem: one permit, six departments, and no shared clock
A tenant improvement in most mid-size cities touches Building, Planning, Fire, Engineering, Public Works, and often a county health department and a special district. Each has its own queue and its own idea of turnaround. The plans examiner marks up in Bluebeam Revu, the markups never sync back to the permit record, and the applicant receives one merged PDF of corrections with no way to see which reviewer wrote what or which comment is already resolved on resubmittal two.
Accela and EnerGov both technically support parallel routing. The problem is who can change it. Adding Fire as a conditional reviewer when occupancy exceeds 49, or making Engineering's review parallel instead of serial, is a scripted workflow change, which in practice means a scoped change order and a wait measured in months. So departments route around the software with email, and the record stops being the truth.
A custom build inverts this. Routing rules become data your Building Official edits in the admin screen: if use group changes, add Fire; if the parcel touches a creek setback in the GIS layer, add Engineering. Every review is its own object with a due date, a reviewer, a status, and comment threads that carry across resubmittals so comment 14 shows its own history rather than reappearing as new. One clock, visible to the applicant, and a cycle-time report the City Manager can read without asking IT. AI has one useful job at this stage: a model reads the submitted plan set, extracts the sheet index, scope, occupancy and square footage, and checks the application against your intake checklist before it enters a queue. It does not make a decision. It runs a completeness screen, so the missing structural calcs get flagged at the counter instead of on day nine.
Problem: your fee schedule lives in a spreadsheet on one planner's desktop
Council adopts a fee resolution. It changes the building valuation multiplier, adds a park in-lieu tier, and touches three impact fees. The fee logic inside your permitting system is vendor-scripted, so the practical fix is that a plans examiner keeps the real math in Excel and types the answer into the permit as a manual fee. Now your fees are correct in a file nobody backs up and are unauditable when the annual audit asks how a $41,300 charge was derived.
Off-the-shelf cannot fix this because fee logic is exactly the part of your operation that a state-wide product cannot generalize. A custom build treats the fee schedule as versioned, effective-dated configuration: each fee has a formula, inputs pulled from the record (valuation, square footage, fixture count, use type), an ordinance citation, and an effective date. Change the resolution, stage the new version, and it goes live at midnight on the adoption date. Every fee calculation stores its inputs and its formula version, so a fee assessed in 2024 recomputes exactly as it did in 2024. That single property is what ends fee disputes and audit findings.
Problem: a resident reports a pothole and never hears back
SeeClickFix takes the report. Public Works works the job in Cityworks. Those are two systems, and the loop back to the resident is a person who usually has other things to do. So residents report the same pothole four times, the duplicate count inflates your open request numbers, and the only escalation path anyone trusts is calling a council member.
A build changes the shape of the record. One request object with a lifecycle (received, triaged, assigned, scheduled, closed with a reason), an SLA per category set by your department heads, and a work order created in Cityworks by API with the request ID written back so the two records stay linked. The resident gets an automatic status change and a closing note with a photo. AI does the triage that actually costs you money: classify the free-text and the photo into a category, geocode it, and check it against open requests within 50 meters over the last 14 days so duplicates merge into one thread with four subscribers instead of four tickets. An after-hours intake assistant grounded in your municipal code and your adopted amendments can answer "do I need a permit to replace a water heater" with a citation and open an application, which takes the highest-volume, lowest-value call off your counter.
Problem: the address is not the same address in any two systems
The assessor has an APN. GIS has a situs address. Utility billing has a service address. The permit system has whatever the applicant typed. When a lot line adjustment creates two new parcels, or a subdivision drops 60 new addresses, the permitting system finds out when someone notices. So permits attach to the wrong parcel, code enforcement cases lose their history, and nobody can answer "what has ever happened at this address" without three searches and a guess.
You cannot buy your way out of this because the authoritative parcel layer is yours, in ArcGIS, maintained by your GIS analyst. The build treats that layer as the master: an address and parcel service that every module calls, with fuzzy matching on intake, an explicit alias table for the ways people write the same address, and event handling for splits and merges so history follows the parcel rather than the string. Get this right first. Every later integration, from inspections to code cases to utility billing, is cheap once it exists and expensive to retrofit if it does not.
Problem: records requests, retention and the ten-day clock
A public records request lands. The responsive material is in Laserfiche, in the permit system, in six inboxes, and in a shared drive. Your statutory response window is short, redaction is manual, and your retention schedule is a PDF that staff mostly remember. GovQA or NextRequest gives you a request tracker, which is genuinely useful, and does nothing about the search or the redaction.
A custom layer indexes across the systems you already own and returns candidate responsive documents with proposed redactions of personal information, then a staff member approves every page before anything is released. Nothing auto-releases. Retention rules attach to the record type at creation, so disposition is scheduled rather than remembered, and the request log itself becomes evidence you can hand a court.
What this costs and how long it takes
Across Digital Heroes delivery on 2,000+ projects, a focused first release costs $60k to $130k and ships in 12 to 16 weeks. For a city, that scope is usually: address and parcel service against your ArcGIS layer, one permit type end to end (intake, routing, fees, review, issuance), online payment, and 311 intake with status. Enough to prove cycle time in front of council in one budget cycle. A full platform, meaning multiple permit and license types, inspections with offline field capture, code enforcement, records, payments, and legacy migration, runs $150k to $400k phased over 6 to 12 months.
What pushes price up in this category specifically: the number of departments in a single workflow, because each one is a stakeholder with its own conditions; integration with a legacy financial system that has no API, where a nightly file exchange plus reconciliation is real engineering; PCI scope on payments, which you contain by tokenizing through Point and Pay or Invoice Cloud rather than touching card data; WCAG 2.1 AA and Section 508 conformance with a VPAT, which is a design constraint rather than a QA pass; hosting posture if the state or your insurer wants StateRAMP or SOC 2; multilingual resident-facing screens; and data migration, which is almost always the ugliest line item because twenty years of permits carry addresses that never matched a parcel in the first place. Budget migration as its own workstream with a cleanup decision from your staff, not as a task inside development.
Build vs buy: what to keep off the shelf
Buy the systems of record. Do not rebuild your general ledger, your GIS platform, your document repository, or your agenda management. Munis, ArcGIS, Laserfiche and Granicus are good at what they do and rebuilding any of them is how a city project ends up in a newspaper.
Off-the-shelf permitting is also genuinely right for a real class of city: under roughly 25,000 residents, under about 1,500 permits a year, no full-time IT staff, no unusual overlay districts or local amendments. Take OpenGov's ViewPoint or CityView, adopt their process as written, resist customizing, and you will be fine. The mistake is buying an enterprise platform and then paying to make it act like your city.
Build the layer where you are actually different. The concrete signals: you have spent more on change orders and professional services than on license in the last two years; a workflow that matters runs on a spreadsheet one person maintains; three or more systems require a human to re-key between them; your permit cycle time is a council agenda item; you have missed a statutory records deadline; or your vendor quoted you to extract your own data. Any two of those and the build is cheaper than the status quo.
How to choose a developer for municipal software
Ask them to model your domain on a whiteboard before any contract: parcel, address, record, review, condition, fee, inspection, case. If they cannot explain how a lot line adjustment splits history, or why a fee needs an effective date and a stored formula version, they will learn on your budget. The data model is the product.
Ask what they have actually integrated. There is a large gap between "we do APIs" and having pulled fee postings into Munis, written work orders to Cityworks, and consumed a live ArcGIS feature service with parcel updates. Ask for the specific system, the specific method, and what broke.
Ask how they handle accessibility and records law as engineering rather than as a checkbox. You want to hear about keyboard paths, screen reader testing, a VPAT, retention rules attached at record creation, and an audit log a court will accept. Ask about PCI scope containment on payments and where card data never goes.
Finally, get ownership and exit in writing before the kickoff call: your code in your repository, your data in your cloud account, documented schemas, and a stated cost to hand the whole thing to a different firm. A developer who resists that clause is telling you what the next five years look like.
The evidence behind this guide
Independent findings on why this investment pays off. Every link goes to the primary source.
- Only 22% of firms are 'future ready' having significantly transformed digitally; these companies show average revenue growth 17.3 percentage points and net margins 14.0 percentage points above their industry average. Source: MIT Center for Information Systems Research (MIT Sloan) (2022) →
- The federal government spends about 80% of its IT budget on operations and maintenance of existing systems rather than on development or modernization, with many critical systems being decades old. Source: U.S. Government Accountability Office (GAO) (2025) →
- In the Flexera 2025 State of ITAM report, respondents reported roughly 33% of SaaS spend is wasted, underscoring how paying for off-the-shelf seats and tiers that go unused erodes the supposed cost advantage of generic SaaS. Source: Flexera (2025) →
- Workers can expect 39% of their existing skill sets to be transformed or become outdated over 2025-2030; 77% of employers plan to upskill their workforce, and 63% identify skill gaps as the biggest barrier to business transformation. Source: World Economic Forum (2025) →
Rohan advises mid-market and enterprise teams on ERP, CRM and custom software, and has led delivery on dozens of business-software builds.
Writes for Digital Heroes, shipping business software for 2,000+ brands across 55+ countries since 2017.