Skip to content

CSO & Area Data Sources

Last updated: 2026-03-30 Map URL: http://cathaldev3.fcrweb.ie/ Data location: data/map/ (local) + fcrwatcher S3 bucket (roamworkflow/map-data/)


FieldDetail
SourceCentral Statistics Office — Small Area Population Statistics (SAPS) 2022
Downloaddata/cso/SAPS_2022_Small_Area_270923.csv (793 columns, 18,919 rows)
GranularitySmall Area — smallest census geography (~80–150 households each)
CoverageAll 26 counties, 18,919 small areas
FreshnessCensus 2022 (static until Census 2027)
LicenceOpen Data, CSO Open Data Licence

Raw fields used:

CSO FieldDescriptionTable
T1_1AGETM / T1_1AGETFTotal male/female populationT1 — Age
T6_1_THTotal householdsT6 — Housing
T6_1_HB_H / T6_1_FA_HHouses / Flats (household count)T6 — Housing
T6_3_OMLHOwn with mortgage/loan (households)T6 — Tenure
T6_3_OOHOwn outright (households)T6 — Tenure
T6_3_THTotal households (tenure base)T6 — Tenure
T8_1_WTAt work (persons)T8 — Employment
T8_1_TTTotal 15+ population (employment base)T8 — Employment
T9_2_HAProfessional workers (households)T9 — Social class
T9_2_HBManagerial & technical (households)T9 — Social class
T9_2_HTTotal households (social class base)T9 — Social class
T10_4_HDPQTHonours degree / professional qualification (persons)T10 — Education
T10_4_PDTPostgraduate (persons)T10 — Education
T10_4_DTDoctorate (persons)T10 — Education
T10_4_TTTotal 15+ population (education base)T10 — Education
T15_1_2C / T15_1_3C / T15_1_GE4CHouseholds with 2/3/4+ carsT15 — Cars
T15_1_TCTotal households (cars base)T15 — Cars
FieldDetail
SourceOrdnance Survey Ireland via CSO
Filedata/cso/small_areas_boundaries.geojson
Used forCentroid coordinates (lat/lng per small area)
Coordinate systemIrish Transverse Mercator (ITM) — converted to WGS84
Conversiondata/cso/fix_coords.py — custom ITM→WGS84 projection using GRS80 ellipsoid
FieldDetail
SourcePobal (funded by Dept. of Rural & Community Development)
Filedata/cso/pobal_2022.csv (3,418 rows)
GranularityElectoral Division (ED) — ~5–6 small areas per ED
Coverage3,418 EDs (3,099 unique names, matches 18,853 of 18,919 small areas)
Key fieldIndex22_ED_std_rel_wt — relative deprivation score
Categories1=Extremely Disadvantaged, 2=Very Disadvantaged, 3=Disadvantaged, 4=Marginally Below Average, 5=Marginally Above Average, 6=Affluent
MethodologyWeighted composite of: age dependency, lone parents, low education, high education, professional share, lower social class, unemployment (M/F), owner-occupied, private rent, LA rent, persons per room

1.4 Commercial Properties — Tailte Éireann Valuation Office

Section titled “1.4 Commercial Properties — Tailte Éireann Valuation Office”
FieldDetail
SourceTailte Éireann (formerly Valuation Office) — opendata.tailte.ie
Download scriptdata/cso/download_valuation.py
BQ tablefcr_operations.valuation_properties
Records153,410 rated commercial properties
Fieldsproperty_number, category, uses, county, local_authority, address, eircode, centroid_lat, centroid_lng
CategoriesRETAIL (SHOPS), OFFICE, INDUSTRIAL USES, HOSPITALITY, FUEL/DEPOT, LEISURE, MISCELLANEOUS, RETAIL (WAREHOUSE), UTILITY, HEALTH, MINERALS
CoordinatesOriginally ITM from Valuation Office, converted to WGS84
FieldDetail
SourceCompanies Registration Office bulk data
Filedata/cso/companies.csv (810,769 rows raw)
BQ tablefcr_operations.cro_companies_agg (16,782 rows aggregated)
GranularityCounty + NACE sector + registration year
NoteRegistered address, not trading address. Aggregated to county level to avoid “1,000 companies at one accountancy firm” problem
NACE codes2-digit EU economic activity classification (e.g. 69=Legal & accounting, 56=Food & beverage)
FieldDetail
SourceCSO PxStat table NDQ07
APIhttps://ws.cso.ie/public/api.restful/PxStat.Data.Cube_API.ReadDataset/NDQ07/CSV/1.0/en
GranularityEircode routing key (3-character, e.g. “X91” = Waterford)
Coverage139 Eircode areas
PeriodQ1 2012 – Q4 2025 (we use 2023–2025)
Total (2023–2025)98,917 completions
FreshnessUpdated quarterly by CSO, ~2 month lag
FieldDetail
SourceDept. of Housing via CSO PxStat table HSM14
APIhttps://ws.cso.ie/public/api.restful/PxStat.Data.Cube_API.ReadDataset/HSM14/CSV/1.0/en
GranularityLocal Authority
Coverage31 Local Authorities (mapped to 29 county-level entries)
PeriodJan 2021 – Dec 2025 (we use 2023–2025)
Total (2023–2025)112,015 units commenced
FreshnessUpdated monthly by CSO

1.8 Property Price Register (NOT YET INTEGRATED)

Section titled “1.8 Property Price Register (NOT YET INTEGRATED)”
FieldDetail
SourceProperty Services Regulatory Authority (PSRA)
URLpropertypriceregister.ie
GranularityIndividual property sale (address + Eircode + price)
StatusNot integrated — no public API or direct CSV download. Form-based download only (Lotus Domino).
Future planMonitor for API availability. County+Year download via form POST if automatable. Would provide trailing 12-month transaction volumes and median prices by Eircode.

Project: listingmanager-1529856313699 Dataset: fcr_operations

TableRowsDescription
cso_small_areas18,919Original small areas (geo + basic counts only)
cso_small_areas_v218,919Enriched — includes purchasing power fields + Pobal join
pobal_deprivation3,418Pobal deprivation index at ED level
valuation_properties153,410Commercial properties with coordinates
cro_companies_agg16,782Company counts by county + NACE sector + year
CREATE TABLE fcr_operations.cso_small_areas_v2 (
sa_geogid STRING, -- CSO small area ID (e.g. "A017010016")
sa_pub STRING, -- Public ID (e.g. "017010016")
county STRING, -- County name (UPPERCASE, e.g. "WATERFORD")
ed STRING, -- Electoral Division name
urban_flag INT64, -- 1=urban, 0=rural
urban_area_name STRING, -- Town/city name (blank for rural)
total_households INT64, -- Occupied dwellings (Census 2022)
total_population INT64, -- Resident population
houses INT64, -- Houses/bungalows
flats INT64, -- Flats/apartments
centroid_lat FLOAT64, -- WGS84 latitude
centroid_lng FLOAT64, -- WGS84 longitude
-- Purchasing power (derived)
pct_professional FLOAT64, -- % professional/managerial social class
pct_degree_plus FLOAT64, -- % honours degree or higher
pct_homeowner FLOAT64, -- % owner-occupied households
pct_multicar FLOAT64, -- % households with 2+ cars
pct_employed FLOAT64, -- % at work (of 15+ population)
pp_score FLOAT64, -- Composite purchasing power 0–71
-- Pobal deprivation (joined from ED level)
pobal_index FLOAT64, -- Pobal relative deprivation index
pobal_category INT64, -- 1–6 scale
pobal_label STRING -- Human-readable label
);

Script: data/cso/build_purchasing_power.py

Input: SAPS 2022 CSV (793 columns) → 5 percentage fields → 1 composite score

ComponentFormulaWeight
pct_professional(T9_2_HA + T9_2_HB) / T9_2_HT × 10025%
pct_degree_plus(T10_4_HDPQT + T10_4_PDT + T10_4_DT) / T10_4_TT × 10025%
pct_homeowner(T6_3_OMLH + T6_3_OOH) / T6_3_TH × 10020%
pct_multicar(T15_1_2C + T15_1_3C + T15_1_GE4C) / T15_1_TC × 10015%
pct_employedT8_1_WT / T8_1_TT × 10015%

Composite: pp_score = Σ(component × weight) / Σ(weights for non-null components)

Distribution:

PercentileScoreInterpretation
Min2.55Most deprived
P1023.03
P2531.18
Median39.55Middle Ireland
P7545.02
P9049.69
Max71.26Most affluent

Important: This is our own derived metric, not an official index. It uses real census counts but the weighting is ours. Pobal’s deprivation index uses similar inputs but different methodology (factor analysis).

Script: data/cso/build_purchasing_power.py

Join key: cso_small_areas.ed (Electoral Division name) → pobal_deprivation.ED_ENGLISH (case-insensitive UPPER match)

Match rate: 18,853 of 18,919 small areas matched (99.65%). 66 small areas across 3 EDs unmatched due to naming discrepancies:

  • CASTLETOWN (NORTH)
  • DUNDALK RURAL (SOUTH)
  • ST. MARY’S (EAST)

Granularity mismatch: Pobal is at ED level (~3,418 EDs), small areas are finer (~18,919). All small areas within an ED get the same Pobal score.

Script: data/cso/fix_coords.py

CSO GeoJSON boundaries use Irish Transverse Mercator (ITM). Centroids computed as average of boundary polygon vertices, then converted to WGS84 lat/lng using GRS80 ellipsoid parameters:

  • Semi-major axis: 6,378,137.0m
  • Origin: 53.5°N, 8°W
  • False easting: 600,000m, false northing: 750,000m

Sanity check: all 18,919 centroids fall within 51–56°N, 5–11°W (Ireland bounding box).

3.4 Eircode → County Mapping (Growth Data)

Section titled “3.4 Eircode → County Mapping (Growth Data)”

Script: data/map/build_growth_data.py

CSO NDQ07 reports completions by 3-character Eircode routing key (e.g. “X91”). We map these to county names using a hardcoded lookup table (139 Eircodes → 26 counties).

Mapping rate: 98,724 of 98,917 completions mapped (99.8%). 193 completions in Eircodes not in our lookup.

Known limitation: Dublin Eircodes (D01–D24, A94, A96, K78, etc.) all map to “DUBLIN”. The map’s county selector splits Dublin into Dublin City, Fingal, South Dublin, Dún Laoghaire-Rathdown. Growth data shows the combined Dublin figure for any Dublin sub-county. Same applies to Cork/Cork City, Galway/Galway City, Limerick/Limerick City, Waterford/Waterford City.

3.5 Local Authority → County Mapping (Commencements)

Section titled “3.5 Local Authority → County Mapping (Commencements)”

Script: data/map/build_growth_data.py

CSO HSM14 uses Local Authority names (e.g. “Dún Laoghaire-Rathdown”). We map these to our county names using a string-match lookup. 29 of 31 LAs mapped.


Local path: data/map/ S3 path: s3://fcrwatcher/roamworkflow/map-data/ Public URL: https://fcrwatcher.s3.eu-west-1.amazonaws.com/roamworkflow/map-data/

FileRowsSizeDescription
small_areas.json18,9195.0 MBAll small areas with PP + Pobal
cro_companies.json1,938115 KBCRO by county + NACE sector
growth_data.json20 KBCompletions + commencements (2023–2025)
properties_index.json262 KBCounty → property file mapping
properties_{COUNTY}.jsonvaries80 KB–3 MBCommercial properties per county

Total: 29 files, 16 MB

{
"id": "A017010016",
"ed": "CARLOW RURAL",
"county": "CARLOW",
"area": "Carlow",
"lat": 52.844252,
"lng": -6.918703,
"hh": 114,
"pop": 242,
"houses": 105,
"flats": 9,
"pp": 36.87,
"pProf": 14.91,
"pDeg": 25.95,
"pHome": 70.18,
"pCar": 36.84,
"pEmp": 47.27,
"pi": -2.21,
"pc": 4,
"pl": "Marginally Below Average"
}
{
"meta": { "sources": [...], "updated": "2026-03-30" },
"completions_eircode": { "X91": { "2023": 560, "2024": 739, "2025": 742, "total": 2041 }, ... },
"completions_county": { "WATERFORD": { "2023": 560, ... }, ... },
"commencements_county": { "WATERFORD": { "2023": 700, ... }, ... },
"completions_lea": { "Dungarvan, Waterford": { "2023": 48, ... }, ... }
}

  1. Download SAPS 2022 CSV from CSO
  2. Download GeoJSON boundaries from OSi
  3. Run fix_coords.py — converts ITM→WGS84, joins SAPS, outputs cso_small_areas_centroids.ndjson
  4. Run build_purchasing_power.py — adds PP fields + Pobal join, outputs cso_small_areas_enriched.ndjson + BQ batch SQL files
  5. Create cso_small_areas_v2 table in BQ (manual — CREATE TABLE DDL)
  6. Load batches via n8n workflow cso-bq-insert (48 batches of 400 rows)
  1. Run data/map/pull_all_data.py — pulls from BQ via worker API into local JSON files
  2. Run data/map/build_growth_data.py — processes CSO NDQ07 + HSM14 CSVs into growth_data.json
  3. Upload JSON files to S3 via n8n workflow map-data-upload (webhook: POST /webhook/map-data-upload)
  4. Upload JSON files to server: scp to admin@52.48.145.217:/var/www/cathaldev3/data/
  5. Run data/map/generate_national_map_s3.py — generates Ireland_Area_Intelligence.html
  6. Deploy HTML: scp to /var/www/cathaldev3/index.html
DataHow to refreshFrequency
Census 2022No refresh needed until Census 2027Static
Pobal IndexRe-download if Pobal publishes update~5 yearly
Valuation propertiesRe-run download_valuation.py, rebuild batchesAnnually
CRO companiesRe-download from CRO, rebuild aggregationsAnnually
New dwelling completions (NDQ07)Re-download CSV from CSO API, run build_growth_data.pyQuarterly
Commencement notices (HSM14)Re-download CSV from CSO API, run build_growth_data.pyMonthly
WorkflowIDWebhookPurpose
CSO Data LoaderygmVyBXSoRQO5yUP/webhook/cso-bq-insertLoad SQL batches into BQ (deactivated, activate for reloads)
Map Data S3 UploadUVpwFXjgLS8TTYR2/webhook/map-data-uploadUpload JSON files to S3 fcrwatcher/roamworkflow/map-data/

  1. Census 2022 is 4 years old. New housing estates built 2023–2026 have zero population in census data. Growth data (NDQ07/HSM14) partially compensates but doesn’t have demographic detail.

  2. Purchasing power score is derived, not official. Our weighting (25/25/20/15/15) is reasonable but arbitrary. Pobal uses factor analysis with different weights. Both use the same underlying census data.

  3. Pobal at ED level, PP at small area level. Pobal assigns one score to ~5-6 small areas. Our PP score varies within an ED. They may appear to contradict — e.g. a small area with PP 40 inside an ED labelled “Marginally Below Average”. This is expected: the PP score is more granular.

  4. CRO data is county-level only. No coordinates for individual companies. Registered address ≠ trading address. Useful for macro density but not for “where exactly are the accountants”.

  5. Growth data eircode→county mapping loses Dublin granularity. All Dublin Eircodes map to one “DUBLIN” entry. Can’t split completions between Dublin City, Fingal, South Dublin, DLR.

  6. Valuation properties may be stale. Tailte Éireann updates periodically but we have a point-in-time snapshot. New builds won’t appear until rated.

  7. Property Price Register not integrated. No public API. Form-based download only (Lotus Domino). Would provide trailing 12-month transaction volumes and median prices by Eircode — valuable for showing where money is being spent.

  8. 3 Electoral Divisions unmatched in Pobal join (66 small areas). CASTLETOWN (NORTH), DUNDALK RURAL (SOUTH), ST. MARY’S (EAST) — naming differences between CSO and Pobal datasets.


Business Planning can verify key numbers using these BQ queries via the worker API:

Terminal window
API_KEY=$(grep VITE_N8N_API_KEY .env.local | cut -d= -f2)
BASE="https://fcr-dashboard-api.cathaldempsey.workers.dev/dashboard-bq-execute"
# Total small areas and population
curl -s -X POST -H "x-api-key: $API_KEY" -H "Content-Type: application/json" "$BASE" \
-d '{"sql": "SELECT COUNT(*) as areas, SUM(total_population) as pop, SUM(total_households) as hh, ROUND(AVG(pp_score),1) as avg_pp FROM `listingmanager-1529856313699.fcr_operations.cso_small_areas_v2`"}'
# Purchasing power by county
curl -s -X POST -H "x-api-key: $API_KEY" -H "Content-Type: application/json" "$BASE" \
-d '{"sql": "SELECT county, COUNT(*) as areas, ROUND(AVG(pp_score),1) as avg_pp, SUM(total_households) as hh FROM `listingmanager-1529856313699.fcr_operations.cso_small_areas_v2` GROUP BY county ORDER BY avg_pp DESC"}'
# Pobal match rate
curl -s -X POST -H "x-api-key: $API_KEY" -H "Content-Type: application/json" "$BASE" \
-d '{"sql": "SELECT COUNTIF(pobal_index IS NOT NULL) as matched, COUNTIF(pobal_index IS NULL) as unmatched FROM `listingmanager-1529856313699.fcr_operations.cso_small_areas_v2`"}'
# Commercial properties by county
curl -s -X POST -H "x-api-key: $API_KEY" -H "Content-Type: application/json" "$BASE" \
-d '{"sql": "SELECT county, COUNT(*) as properties FROM `listingmanager-1529856313699.fcr_operations.valuation_properties` WHERE centroid_lat IS NOT NULL GROUP BY county ORDER BY properties DESC", "limit": 50}'
Ask the docsRAG over this site
Ask anything about the FCR Dashboard platform — architecture, BigQuery, the worker routes, billing rules, the LRC stack, scoring… Answers are grounded in this documentation, with source links.
How does the deal-brief refresh work? Which routes are Worker vs n8n? How is account health scored?