HardshellBuildings

Sources and methodology

What this site is and is not

This site shows public City of Calgary data about residential buildings, explained. Every number links to the dataset it came from, every derived figure states its inputs beside it, and every estimate is labelled as one.

It is not a scoring service. There is no composite score, grade or rating of a building anywhere on the site, and no text is written by a model: every sentence is produced from a registered template over displayed inputs.

Sources

One card per dataset the pipeline reads, with its licence, what the site takes from it, how often it refreshes and its known limits.

Current property assessments

Dataset
4bsw-nn7w
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
roll number, address, community name, property type, year of construction, assessed value, parcel polygon
Refresh
nightly
Last successful run
2026-11-14
Known limits
The current roll only; history comes from the historical dataset. Parcel polygons are the City's roll parcels.

Historical assessments

Dataset
4ur7-wsgc
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
roll number, roll year, address, assessed value
Refresh
nightly
Last successful run
2026-11-14
Known limits
Roll years from 2005. Some years pad roll numbers with a leading zero, so both spellings are matched.

Building permits

Dataset
c2es-76ed
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
permit number and type, issued date, status, class, description, contractor business, estimated cost, housing units
Refresh
nightly
Last successful run
2026-11-14
Known limits
Only permits the City has matched to a building address appear on a building page.

Development permits

Dataset
6933-unw5
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
permit number, issued date, status, class, description
Refresh
nightly
Last successful run
2026-11-14
Known limits
Development permits carry their own status vocabulary, mapped to the same four states as building permits.

Plumbing permits

Dataset
5pvv-k7hn
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
permit number, issued date, completed date, status
Refresh
nightly
Last successful run
2026-11-14
Known limits
Plumbing permits have no City status field: a completed date means completed, otherwise the permit counts as open.

Gas permits

Dataset
tg24-jt7r
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
permit number, issued date, completed date, status
Refresh
nightly
Last successful run
2026-11-14
Known limits
Mapped by completed-date presence, the same as plumbing permits.

Assessment appeals

Dataset
d88m-6ky3
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
roll year, outcome
Refresh
nightly
Last successful run
2026-11-14
Known limits
Outcome spellings are normalized at ingest; three spellings of one outcome become one value.

Short-term rental licences

Dataset
gzkz-5k9a
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
address, licence status
Refresh
nightly
Last successful run
2026-11-14
Known limits
Counts active licences at the address as of the nightly refresh.

City service requests

Dataset
iahh-g8bj
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
community name, service name, requested date, monthly counts
Refresh
nightly
Last successful run
2026-11-14
Known limits
Community-level only: no building ever appears in this data. The series runs to the dataset's latest requested date.

Social disorder calls (City Corporate Security)

Dataset
4evm-wx9a
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
category, community region, report date
Refresh
nightly
Last successful run
2026-11-14
Known limits
Covers only the nine blocks around City Hall and the Municipal Complex. Publication ended 2025-07 and has not continued. Shown only for communities whose boundary intersects that area.

Community regions

Dataset
kxmf-bzkv
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
community name, community code
Refresh
nightly
Last successful run
2026-11-14
Known limits
A name-to-code lookup; boundaries come from the community boundaries dataset. No run of its own: it is read as part of the social disorder refresh, so that run's date is shown.

Community boundaries

Dataset
surr-xmvs
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
community code, name, sector, boundary polygon
Refresh
nightly
Last successful run
2026-11-14
Known limits
Boundaries change rarely; the nightly refresh picks up any revision.

3D building footprints

Dataset
cchr-krqg
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
structure id, ground and rooftop elevations, footprint polygon
Refresh
nightly
Last successful run
2026-11-14
Known limits
LiDAR capture from 2023-01, EPSG:3776 reprojected to 4326. Rows with missing elevation values are discarded. Heights feed the storeys and construction estimates.

Population by community

Dataset
f9wk-wej9
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
community code and name, total population
Refresh
nightly
Last successful run
2026-11-14
Known limits
The 2021 federal census count; the denominator year is shown wherever the rate appears.

Dwellings by community and structure

Dataset
set9-futw
Publisher
City of Calgary, Open Calgary
Licence
Open Government Licence - City of Calgary
What we take
census year, community, dwelling structure, dwelling count
Refresh
nightly
Last successful run
2026-11-14
Known limits
Civic census; 2019 is its last year, so the per-100-dwellings rate is always a 2019 denominator, shown with its year.

National Address Register

Dataset
46-26-0002
Publisher
Statistics Canada, via the Federal Open Data portal
Licence
Statistics Canada Open Licence
What we take
civic address, unit designators per address (Alberta files only)
Refresh
quarterly
Last successful run
no successful run recorded yet
Known limits
A national register read for its Alberta rows only, by a quarterly job. Supplies the unit count of apartment and rental buildings; a count taken from the register says so on the building page.

Building names

Dataset
no dataset id (committed series)
Publisher
OpenStreetMap contributors, via the Overpass API
Licence
Open Database Licence (ODbL), OpenStreetMap contributors
What we take
named buildings within Calgary
Refresh
nightly
Last successful run
2026-11-14
Known limits
Volunteer-edited data. A name matched to a parcel is labelled estimated until a moderator confirms it; the pipeline never overwrites a confirmed name.

Hard-money price series

Dataset
no dataset id (committed series)
Publisher
Blockchain.com and Yahoo Finance
Licence
Committed annual series built from published prices
What we take
annual bitcoin and gold prices in CAD, 2005 on
Refresh
nightly
Last successful run
2026-11-14
Known limits
A committed file, refreshed with the pipeline; no host is fetched at page time. The CAD, BTC and gold toggle converts each roll year at that year's price.

Derived figures

A derived statement is a sentence produced by a fixed template over named inputs, with the inputs displayed beside it. It is arithmetic the reader could repeat. A statement renders only when every input is present; percentages round to whole numbers, dollar figures to the nearest $500, and comparatives use three words only: higher, lower, near.

value_trend

Inputs
value_now, value_2y, value_peak, peak_year, community_change_2y, city_change_2y
Template
"Median unit value {rose/fell} {pct} from {y-2} to {y} ({a} to {b}){, after falling {pct} from its {peak_year} peak}. {Community} condos {rose/fell} {pct}; Calgary condos {rose/fell} {pct}."
Thresholds
percentages: rounded to whole numbers; dollars: rounded to the nearest $500; comparatives: rose/fell only
Example
Median unit value rose 34% from 2023 to 2025 ($322 500 to $432 500), after falling 31% from its 2015 peak. Beltline condos rose 28%; Calgary condos rose 31%.

Compares the building's current median unit assessed value with the value two roll years earlier, and with the highest value on record (its peak). Community and city changes are the same two-year percentage change on the community condo median and the Calgary condo median, computed nightly into community_profiles.value_series and city_profile.value_series. Inputs: value_now, value_2y, value_peak, peak_year, community_change_2y, city_change_2y; the roll year and community name are page context.

value_position

Inputs
value_now, community_median, city_median
Template
"At {value}, this building's median unit sits {above/below/near} the {community} condo median ({m}) and {above/below/near} the Calgary median ({c})."
Thresholds
near: within 5 percent of the reference; comparatives: above, below or near only; dollars: rounded to the nearest $500
Example
At $432 500, this building's median unit sits higher the Beltline condo median ($401 000) and higher the Calgary median ($389 000).

Places the building's current median unit assessed value against the community condo median and the Calgary condo median for the same roll year. A value within 5 percent of a reference is 'near'; otherwise 'above' or 'below'. No other comparative appears. Inputs: value_now, community_median, city_median.

permit_status

Inputs
open_permits, latest_completed
Template
"{n} permit(s) open: {list}. Last completed: {type} {number} ({date}){, described as "{description}"}."
Thresholds
listing: open permits listed by permit number, newest issued first
Example
1 permit open: PP2026-07973. Last completed: building permit BP2023-13589 (21 Aug 2023), described as "Parkade upgrade".

Counts the building's permits in status_state 'open' and names the most recently completed permit. Open permits are listed by permit number; the last completed permit is the latest issued_date among status_state 'completed'. Inputs: open_permits (array of permit objects), latest_completed (permit object).

permit_pre_build

Inputs
year_built, permits_before_build
Template
"{n} permits predate this building (built {year}) and belong to the site."
Thresholds
none
Example
3 permits predate this building (built 2004) and belong to the site.

Counts permits whose issued_date is before the building's year_built. Those permits describe work on the site before the current building existed. Inputs: year_built, permits_before_build (count).

appeals_rate

Inputs
appeals_15y, city_median_appeals_15y
Template
"{n} appeals in 15 years ({outcomes}); the median Calgary {type} building has {m}."
Thresholds
median: city_median_appeals_15y from city_profile.appeals_15y_median, one decimal
Example
3 appeals in 15 years (2 Resolved without hearing, 1 Decreased); the median Calgary condo building has 1.1.

Counts the building's assessment appeals over the last 15 roll years and lists the normalized outcomes with their counts, against the median appeal count for Calgary buildings of the same type over the same window (city_profile.appeals_15y_median). Inputs: appeals_15y (count), appeals_outcomes (array of {outcome, count}), city_median_appeals_15y, building_type.

requests_rate

Inputs
total_12m, population, dwellings, percentile_per_1000, percentile_per_100dw
Template
"{Community} logged {n} service requests in the last 12 months: {r1} per 1,000 residents and {r2} per 100 dwellings, {higher/lower} than {p}% of Calgary communities per 1,000 residents."
Thresholds
rates: one decimal; percentile: among communities with population of at least 1,000
Example
Beltline logged 9 956 service requests in the last 12 months: 396.2 per 1,000 residents and 56.4 per 100 dwellings, higher than 91% of Calgary communities per 1,000 residents.

The community's 12-month City service request total divided by its 2021 population (per 1,000 residents) and its 2019 dwellings (per 100 dwellings), with the community's percentile rank among Calgary communities with population of at least 1,000 on the per-1,000 rate. Inputs: total_12m, population, dwellings, percentile_per_1000, percentile_per_100dw; the community name is page context.

requests_mix

Inputs
top_categories
Template
"The most common requests were {c1} ({p1}%), {c2} ({p2}%) and {c3} ({p3}%)."
Thresholds
share: percent of the 12-month total, rounded to whole numbers; categories: the three largest category groups
Example
The most common requests were Bylaw (34%), Roads (22%) and Parks (11%).

The three largest City service request category groups (the service_name prefix before ' - ') by share of the community's 12-month total. Inputs: top_categories (array of {category, share}, largest first).

requests_trend

Inputs
requests_12m, requests_prior_12m
Template
"Requests {rose/fell} {pct} compared with the previous 12 months."
Thresholds
percentages: rounded to whole numbers
Example
Requests rose 7% compared with the previous 12 months.

The community's City service request total for the latest 12 months against the total for the 12 months before that, as a percentage change. Inputs: requests_12m, requests_prior_12m.

requests_caveat

Inputs
sector
Template
"Downtown communities carry city-wide services (transit, roads, events), which inflates per-resident rates; the per-dwelling figure is the fairer comparison for residential buildings."
Thresholds
downtown_sectors: Centre City, Downtown, Downtown East, Downtown West and Eau Claire; small_population: under 1,000 residents
Example
Downtown communities carry city-wide services (transit, roads, events), which inflates per-resident rates; the per-dwelling figure is the fairer comparison for residential buildings.

A fixed caveat, not arithmetic: communities in the downtown sectors carry city-wide services (transit, roads, events), which inflates per-resident rates, so the per-dwelling figure is the fairer comparison for residential buildings. Communities with a population under 1,000 carry the small-population caveat instead: too few residents for a reliable rate. Normalizing by building units is not possible for community data and is not attempted. Inputs: sector, population (the small-population text wins over the downtown text when both apply).

disorder_coverage

Inputs
intersects_coverage
Template
"City Corporate Security recorded {n} incidents in the 12 months to {end}, within the nine-block area around City Hall that overlaps this community. Publication ended {end}."
Thresholds
shown_only_when: community_profiles.disorder_coverage is true
Example
City Corporate Security recorded 87 incidents in the 12 months to 31 Jul 2025, within the nine-block area around City Hall that overlaps this community. Publication ended 31 Jul 2025.

Shown only when the community's boundary intersects the nine-block City Corporate Security coverage area around City Hall (community_profiles.disorder_coverage, set nightly from pipeline/coverage/city_hall_nine_blocks.geojson). The dataset's publication ended 2025-07 and has not continued; communities outside the coverage area see 'Not available for this community; see methodology.' instead (R13.AC4). Inputs: intersects_coverage (boolean), incidents_12m, publication_end.

units_confidence

Inputs
unit_count_source
Template
"About N units (estimate) | N units (resident correction) | N units | Unit count unknown"
Thresholds
override: unit_count_override always wins and is labelled as a correction
Example
231 units

The unit count's confidence label, from the v1 R5.AC4 wording. A resident correction (unit_count_override) always wins and is labelled as one; otherwise a National Address Register count is hedged as an estimate ('About N units'), an unknown count says so outright, and a city_assessment count is stated plainly: it is the roll count the City itself maintains. Inputs: unit_count, unit_count_source, unit_count_override.

storeys_estimate

Inputs
height_m, storeys_est, method
Template
"About {n} storeys, estimated from a {h} m LiDAR height (2023)."
Thresholds
formula: storeys_est = round(height_m / 3.1), minimum 1
Example
About 44 storeys, estimated from a 136.4 m LiDAR height (2023).

Storeys are estimated from the building's LiDAR height (2023 City 3D buildings dataset): the footprint with the largest intersection with the parcel, height_m = rooftop_elev_z minus grd_elev_min_z, storeys_est = round(height_m / 3.1) with a minimum of 1. Always shown as an estimate. Inputs: height_m, storeys_est, method (height_source).

construction_estimate

Inputs
storeys_est, year_built, class
Template
"Likely {class}: {reason}."
Thresholds
rule_table: 1-4 storeys wood frame likely; 5-6 built 2015 or later wood or concrete; 5-6 before 2015 concrete or steel likely; 7 or more concrete or steel likely; unknown height Unknown
Example
Likely concrete or steel: buildings above 6 storeys are non-combustible construction.

Construction class is estimated from storeys_est and year_built under the Alberta Building Code rule table: low-rise residential (1 to 4 storeys) is typically wood frame; mid-rise wood frame (5 to 6 storeys) has been permitted in Alberta since 2015; buildings above 6 storeys are non-combustible construction. A moderator-confirmed construction_override replaces the class and drops the 'estimated' label (R11). Inputs: storeys_est, year_built, class, override.

Top lists

Each list at Top lists is a saved query refreshed nightly into a materialized table, with its formula, scope and refresh date stated on the page. Lists ranking by a figure some buildings do not have (unit counts, heights, value pairs) leave those buildings out and state how many were left out.

Estimates

Four figures on a building page are estimates rather than City-published facts. Each is labelled as an estimate everywhere it appears.

Unit counts
A National Address Register count is hedged as an estimate; a City assessment roll count is stated plainly; a count nobody has is stated as unknown. A resident correction from a verified representative replaces the City figure and is labelled as a correction.
Storeys
Estimated from the building's LiDAR height in the 2023 City 3D dataset: the footprint with the largest intersection with the parcel, rooftop elevation minus minimum ground elevation, divided by 3.1 m per storey, minimum 1.
Construction type
Estimated from the storey count and the year built under the Alberta Building Code rule table: 1 to 4 storeys likely wood frame; 5 to 6 storeys wood frame or concrete when built 2015 or later, likely concrete or steel before that; 7 or more storeys likely concrete or steel.
Building names
From OpenStreetMap where a named building intersects the parcel. A name is labelled estimated until a moderator confirms it.

Accuracy checks run nightly: buildings whose estimate inputs are missing render Unknown rather than a guessed value, and the counts of buildings without each estimate appear in the pipeline's ops health. To correct an estimate, a verified representative submits a correction through a building page's report link; a moderator confirms it, and the correction is labelled as confirmed from then on.

Comments and moderation

Resident comments are published under the site's moderation rules: logged-in, screened for personal information, and removable on report. A comment is one resident's experience, not a verified fact about the building.

Community statistics

About the community, not this building

City service request totals are normalized per 1,000 residents (2021 federal census) and per 100 dwellings (2019 civic census, its last year), each shown with its denominator year. The percentile rank is computed nightly among communities with 1,000 or more residents. Downtown communities carry city-wide services, which inflates per-resident rates; the per-dwelling figure is the fairer comparison for residential buildings. Normalizing by building units is not possible for community data and is not attempted.

City Hallnine-block coverage area

City Corporate Security incident data (dataset 4evm-wx9a) covers the nine blocks around City Hall and the Municipal Complex, outlined above. Communities whose boundary does not intersect this area show no figure from it. Publication ended 31 Jul 2025.

What we leave out and why

  • Personal information: owner and applicant names never appear, and permit text is screened before it is stored.
  • Unit-level data: values are shown per building, never per unit or roll number.
  • Service requests at building level: the City publishes them per community only, so no building page carries them.
  • Composite scores: none exist on this site and none will (v1 R6.AC8).
  • Photos and imagery: no third-party images of a building appear.

Licences and attribution

  • Contains information licensed under the Open Government Licence – City of Calgary.
  • Contains information licensed under the Statistics Canada Open Licence Agreement.
  • Building name and map data © OpenStreetMap contributors, available under the Open Database Licence (ODbL).
  • Map tiles by OpenFreeMap.

City datasets carry the Open Government Licence - City of Calgary. Building names and map data carry the Open Database Licence (ODbL), OpenStreetMap contributors.

Changelog

  • 2026-11-10: Methodology page first published: one card per source, one entry per derived statement, the estimates and community-statistics sections, and the nine-block coverage map (calgary-buildings-ux v1, R18).
  • 2026-11-08: Derived figures added: storeys and construction estimates from the 2023 LiDAR dataset, OpenStreetMap building names, the four-state permit status model, community rates and percentiles, and the top lists (calgary-buildings-ux v1).
  • 2026-11-01: Assessment history matching handles roll numbers some years pad with a leading zero (calgary-buildings v1).