Connor Faulkner
← Back to Work

Work entry

PlanningWatch — Planning Application Monitoring for Ireland

2026 · Independent Project

A live SaaS at €29/mo tracking planning applications across 31 Irish councils — nightly ingestion, per-council health checks, and a Bearer-token API with webhooks for developers building on top of the data.

Django PostgreSQL Data Engineering SaaS API Stripe

Open live app / source →

Overview

PlanningWatch is a live SaaS at €29/mo that tracks planning applications across 31 Irish councils, with paying users on it now. The database holds around 12,300 applications, up from 8,201 after a data-integrity fix I’ll get to below. Users set up saved properties or areas and get alerted when something is lodged nearby.

Map of Ireland's 31 local authorities shaded by planning applications lodged in the last 30 days. Busiest: Dublin City with 211. Carlow: 19 in the last 30 days Cavan: 68 in the last 30 days Clare: 92 in the last 30 days Cork City: 50 in the last 30 days Cork County: 207 in the last 30 days Dún Laoghaire–Rathdown: 75 in the last 30 days Donegal: 176 in the last 30 days Dublin City: 211 in the last 30 days Fingal: 51 in the last 30 days Galway: 160 in the last 30 days Galway City: 71 in the last 30 days Kerry: 121 in the last 30 days Kildare: 102 in the last 30 days Kilkenny: 75 in the last 30 days Laois: 79 in the last 30 days Leitrim: 19 in the last 30 days Limerick: 134 in the last 30 days Longford: 30 in the last 30 days Louth: 66 in the last 30 days Mayo: 100 in the last 30 days Meath: 117 in the last 30 days Monaghan: 50 in the last 30 days Offaly: 67 in the last 30 days Roscommon: 44 in the last 30 days Sligo: 41 in the last 30 days South Dublin: 45 in the last 30 days Tipperary: 110 in the last 30 days Waterford: 106 in the last 30 days Westmeath: 50 in the last 30 days Wexford: 4 in the last 30 days Wicklow: 120 in the last 30 days
2660 applications in the last 30 days · gold = busiest council · data 2026-09-07 · boundaries: Tailte Éireann (CC BY 4.0)

The map is rebuilt every night from live data — each authority is shaded by how many applications it lodged in the last 30 days.

The data problem

Every council publishes planning data differently — some run ArcGIS portals, some use Agile Applications, some go through eplanning.ie. Their numeric application IDs overlap across systems, which caused a real bug: the database key was a globally unique reference field, but council references are only unique per-council. Two different counties could both have application “24/1234” and one would silently overwrite the other. 1,284 references collided this way before I caught it. The fix was a composite key on (county, reference), followed by a full re-scrape to recover what had been lost — Kildare went from 33 to 261 records, Wicklow from 17 to 191, just in the affected ranges.

The other lesson was around freshness monitoring. I originally checked data health with a single global “most recent record” query, which looked fine even while individual councils had stopped ingesting entirely — one was silently dead for 70 days before anyone noticed. Health checks are now per-council, at /health/data/, so a single council going quiet doesn’t hide behind everyone else’s activity.

Architecture

Django and PostgreSQL, hosted on Railway. Ingestion runs nightly via Celery beat, with idempotent normalization so re-running a job doesn’t duplicate or corrupt records. Alerts are bounded by lodge-age, so a historical backfill doesn’t fire a wave of notifications for applications that are months old.

API & webhooks

There’s a Bearer-token API with scoped tokens, filtered queries (county, status, date range, keyword), and pagination — plus webhooks with test delivery and a per-webhook enable/disable toggle. Rate limiting is per token.

Status

Live, with paying users. History depth varies by council — most go back further, but Cork City’s data only reaches to late 2025, when its Agile system went live. Coverage is lodgement-onward everywhere; some councils’ historical archives just aren’t deep.