Skip to content

The free IndexProp SG dataset

Everything on this site is a derived statistic over public sources, and the derivations are free to reuse. The sources are not all under the same licence, so this page states them separately rather than granting one permission over all four.

The current build holds 985,666 HDB resale registrations from January 1990 to August 2026, and 132,768 private sale caveats lodged between September 2021 and September 2026, across 55districts and 4,237 named roads that resolve to one of them by search. Every published figure uses a stated window inside those spans, never the whole of them, and the most recent month of each register is still filling.

Download every district

One CSV, one request: every published planning area with its median rate, its mix-adjusted rate, its median price, its window and its sample, plus the page and JSON address of each. HDB-derived columns only, because URA output reaches this site as derived statistics under terms that permit publication and forbid redistributing the records, and a CSV is the shape most likely to be re-hosted.

The button at the top of this page fetches it. Every area page also exports its own resales, and every private panel its own developments, from the button on the table itself: those are the row-level files, and this is the summary.

The four registers

Figures from different registers are never averaged together. Each records a different event, over a different window, under a different licence.

  • HDB resale registrations: resale flats, 1990 to the present, from Data.gov.sg. Singapore Open Data Licence 1.0.
  • HDB renting-out approvals: approved subletting of whole flats, from Data.gov.sg. Singapore Open Data Licence 1.0.
  • URA private sale caveats: caveats lodged on private residential sales, rolling five years, from the URA Data Service. URA terms.
  • URA private lease contracts: rental contracts for private residential property, from the URA Data Service. URA terms.

The endpoints

Every figure on this site is served from a static JSON file. There is no API service behind them and nothing to sign up for: no key, no rate card, no registration and no per-request compute, because these are files on a CDN, UTF-8, and immutable for the life of a build. dataset_version in the index is what tells you anything changed, so cache on your side rather than polling.

  • /data/index.json: the entry point, and everything else hangs off it. National figures, the region list, every district with its median, the national quarterly series, the flat types, the outlier fence, the stock, the methodology object the methodology page renders itself from, and the coverage of each register.
  • /data/regions-index.json, /data/districts-index.json, /data/neighbourhoods-index.json: one compact row per published place at that level, carrying the rate, the sample, the window, the private figures where the place has them and a sparkline. These are the rows the league tables and the home page rank over, so a ranking of your own starts here rather than with one fetch per area. Every district as one row.
  • /data/regions/{slug}.json, /data/districts/{slug}.json, /data/neighbourhoods/{slug}.json: one place, in full, and the same shape at all three levels. The next section says what is in one. Tampines.
  • /data/rankings/index.json and /data/rankings/{slug}.json: the league tables. Each one is self-describing, carrying its own question, grain, window and the count it ranked before it cut to the rows shown.
  • /data/compare/index.json and /data/compare/areas.json: the published pairs, and the directory of areas that may be compared with each other. There is no per-pair file. A comparison is composed from the two areas’ own payloads, by the same function the browser composes it with, which is why any two same-level areas can be compared and not only the pairs that have a page.
  • /data/home-lists.json: the most expensive and best value lists, HDB and private, each stating the window and the eligibility floor it was ranked under rather than leaving you to infer them.
  • /data/search-index.json: every searchable name as a compact tuple, areas at all three levels plus the named roads and private projects that resolve to one. What the site’s own search box ranks over.
  • /data/quality.json: every check the pipeline ran for this build with its result, and the description of each source register. The build’s own report card, published rather than summarised.
  • /data/districts.csv: the spreadsheet form of the whole published district table, which is the button at the top of this page.

Every prerendered page also links its own JSON in its head, as <link rel="alternate" type="application/json">, so the fastest route to a page’s data is the page itself.

What one area payload holds

All three levels share one shape, so code written against a district works unchanged on a region or a neighbourhood:

  • name, slug, level, path, ancestors, siblings: identity, and where the place sits in the taxonomy.
  • window_months: how many months of resales every HDB figure in the payload covers. Read it before comparing anything with anything.
  • stats: the cross-section. Median rate per square foot and per square metre, median price, the p20 to p80 spread, the 95% interval on the median, median floor area, median remaining lease, and n, the count all of them were computed from.
  • headline and median_psf_mix: the named-flat-type figure the page leads with, and the mix-adjusted rate, which is the only figure areas are ever ranked on.
  • by_type, by_lease_type, by_storey_type: the cross-section cut by flat type, remaining-lease band and storey band, every row carrying its own count.
  • trend and growth: the quarterly series with per-quarter counts and intervals, restated in today’s money as well as cash, and the growth rates with the endpoints they were measured between.
  • rent and private: the HDB renting-out medians with gross yields, and the URA-derived private block. Derived statistics only, per the licence above.
  • transactions: individual HDB resales at HDB’s own published grain, block and street and no unit, capped at 1,000 rows with transactions_total stating the real count.

Conventions

  • Every price-per-area figure is dollars per square foot, rounded once to publication precision so the JSON, the CSV and the page always agree. Multiply by 10.7639 for dollars per square metre.
  • Floor areas are in square metres, as HDB records them.
  • null means withheld or unavailable, never zero, and wherever a figure is withheld the payload carries the reason beside it in the same words the page renders.
  • Counts are per register and are never summed across registers. An HDB resale and a URA caveat record different events, and no figure here averages the two.
  • Slugs in filenames are lowercase and match the page URL, so the JSON address of any page is derivable from the page address.

The source columns, and what this site does with them

The HDB resale register carries eleven columns, and every figure on this site traces to them:

  • month: the registration month. Sets the window every figure states, and the anchor the build is dated by.
  • town: HDB’s administrative town. Used as an alias layer for search; the page geography comes from the Master Plan boundaries instead.
  • flat_type: 1-room to Executive and Multi-generation. The unit of every headline, cut and yield match; figures are never blended across types without saying so.
  • block and street_name: the address grain HDB publishes. Blocks place transactions into the Master Plan polygons; street names resolve a search to the page that publishes the road’s figures.
  • storey_range: the floor band, for example 10 TO 12. The basis of the price-by-floor section.
  • floor_area_sqm: the flat’s area. The denominator of every price per square foot.
  • flat_model: HDB’s design classification. Kept in the data; used for tie-breaking and detail, not for headline cuts.
  • lease_commence_date and remaining_lease: the lease figures. The published remaining lease is used where it exists (2015 onwards); the commencement year covers the rows before it.
  • resale_price: the transacted price as registered. The numerator of everything.

The URA registers reach this site as derived statistics only, so their column detail matters mainly for what it forbids: sale caveats carry exact floor areas (strata) and are the basis of the private rates, while lease contracts report floor area as a band, which is why no rental rate is ever computed here from contract data and URA’s own published rate is quoted instead.

The original sources

If you want the raw HDB transactions rather than these aggregates, go straight to the source: HDB Resale Flat Prices on Data.gov.sg, five datasets covering 1990 to the present, with a bulk CSV download and a REST API. The private data comes from the URA Property Market Information service, which requires a free access key and serves caveats and lease contracts directly.

Licence and attribution

The two HDB registers are published under the Singapore Open Data Licence version 1.0, which permits use, modification and redistribution including commercially, with attribution. What IndexProp SG derives from them carries the same terms.

The two URA registers are different, and the difference is worth reading before you reuse anything. URA’s terms permit publication of derived statistics (medians, counts, rates, ranges), which is what this site publishes and what the JSON endpoints contain. They do not permit redistribution of the underlying caveats and lease contracts, so those records are not published here in any form, and the derived figures should be attributed to the URA Data Service rather than presented as open data.

The geography is a third case. Where a street sits, and where a block sits, is worked out from OpenStreetMap road centrelines and addressed buildings, combined with URA Master Plan 2019 boundaries and HDB building data from Data.gov.sg. OpenStreetMap is published under the Open Database Licence 1.0, which is a share-alike licence.

Two things here are derived from it closely enough that IndexProp SG treats them as derivative databases and offers them under ODbL 1.0 as well, rather than asking anyone to work out whether they qualify: the street-to-area lookup that resolves a road name to the page publishing its figures, and the street rows inside the search index at /data/search-index.json. Reuse either with attribution to OpenStreetMap contributors and share your own derivations on the same terms. The price statistics are not affected by this: they come from the HDB and URA registers, and their licences are the two paragraphs above.

A citation you can paste

Plain text

IndexProp SG, "HDB and private property prices in Singapore", dataset version 2026-08,
https://indexprop.com/sg. Contains information from the HDB Resale Flat Prices and
Renting Out of Flats datasets accessed from Data.gov.sg and made available under
the Singapore Open Data Licence version 1.0, and derived statistics from the
Urban Redevelopment Authority Data Service.