All notable changes to the homesight API (https://homesight-api.azurewebsites.net) are recorded here. The format is based on Keep a Changelog, and the project adheres to Semantic Versioning.
The deployed version is API_VERSION in api/function_app.py, also the info.version
of the spec; GET /health returns it. A new endpoint or field is a minor version; a fix or a change in what
data is served is a patch. Loading newly extracted annual reports (a new BRF or year, no change to the spec)
is therefore a patch: bump API_VERSION, add a release entry here with the BRFs and years under Data,
deploy the code (README), then provision + flip. Release once per request, not per BRF or per report: finish the whole
request (every BRF and year asked for), let the user verify the complete result, then commit, deploy and flip.
check_failed with a note.tools/brf/allabrf.py also finds Stockholm (Johanneshov) slugs. The BRF README lists estate-agent sources (Bjurfors,
MOHV/Vitec, HusmanHagberg’s document proxy).check_failed with a note.tools/brf/validate.py checks a year whose previous year is not stored when its opening is restated, and skips the debt
identity without a previous year.cash_not_stored in warnings.check_failed (the report’s own
cash flow is 906 kr off its balance sheet).quality (verified,
verified_with_caveats, check_failed, unverified) and warnings ({code, message}) in
GET /brfs/{orgnr}/financials, saying which checks could not run or failed: cash_check_failed,
cash_not_stored (no cash flow statement), no_opening_balance (previous report not held), checked_by_eye,
scanned (values read by OCR), note (a caveat written in the BRF’s profile), unverified. Each of values
also says whether it was checked_by_eye. Listings and /brfs rows carry the latest year’s label as
brf_report_quality and brf_report_warnings.verified: true; only 2016–2025 are verified (profile verified_from).
They are now unverified, and 2004–2011 also cash_check_failed.tools/brf/allabrf.py): Gösen 2021, 2023;
Laken 2022; Soluret 2021, 2023; Trädgården 278 FY2021; Peppargränd 1 2024; Rödingen 2024; Almandinen 2024;
and the new BRFs Solhöjden 2023–2024, Pigghajen 2021, 2024, Tyresö Trädgårdar 2022, Steget FY2021–FY2022,
Kvarteret Skogsbacken 2021–2022 and Sander 2023–2024 (a new build).id and created_at on every listing, as in the Real Estate Data API (missed in the migration): id is
the row’s position in the import, created_at when the row was loaded. Rows with an equal sort value are
now ordered by id descending, as there, instead of by listing_id, so tied rows come in the same order.school_1..5_*) and avg_school_socio_index*, which the
0.9.0 spec left out.tools/cloud/parity.py also reports fields the data API serves that are missing here.schools/): on every listing the five
nearest school units (school_1..5_*: name, type, geodesic distance, index per edition, ineligible share)
and the averages over the nearest 1, 3 and 5 with a 2029 projection (avg_school_socio_index*); on every
område, kommun and city the mean, median, per-edition series, trends and projection, copied down to
listings and /brfs rows. The min_school_index* filters and school_* sorts now work.GET /brfs follows the Real Estate Data API’s contract: one row per BRF with an apartment for
sale (about 3 100), filters (brf_name_search, kommun, omrade, min_brf_units, …), 32 sorts and at
most 10 rows per request, instead of the list of BRFs with extracted reports. Those BRFs are now found with
has_report=true and are listed even when nothing is for sale.GET /brfs/{orgnr} returns the BRF’s /brfs row, with the former summary under report
(null for a BRF without extracted reports). Every BRF in /brfs can be read this way.has_report filter on /brfs (homesight only), and the verified layer (brf_report_*, brf_land_tenure,
brf_stambyte_*) on /brfs rows.area_name
and the benchmarks come from the område with most of its listings (the data repo takes an arbitrary
listing). The first page of every sort is otherwise identical.GET /sales/stats/avg-price-per-sqm (?year=, ?rooms=): average sold kr/m², with the data repo’s
contract. Every year/rooms combination is precomputed, so a request is one point read; identical to the
data API for all 424 combinations.GET /llms.txt: a short Markdown guide for LLM agents (coverage, how to query, caveats).GET /sales/stats/avg-price-per-sqm echoes rooms as a number with a decimal (2.0), as the data API.GET / that shadowed every single-segment endpoint
(/health, /advertisements, /kommuns, /brfs, /openapi.json, …): they answered 404 for a few
minutes until it was removed. GET / discovery is therefore not available.GET /cities, GET /kommuns (with price_stats), GET /areas (?kommun=, ?name_search=), with the
data repo’s contract: listing counts, asking and sold kr/m² per type of home, avgift and loan per m²,
housing-cooperative stock and turnover, per-year sold history with trends and forecasts, and each
parent’s figures copied down./advertisements: the område, kommun and city benchmarks (area_*, kommun_*,
city_*: same-type avg/median kr/m², sold price, avgift and turnover summaries).school_*, *_school_socio_index*) is not migrated: NULL.units_in_scope_br, pct_for_sale_br, turnover_br_*, *_loan_per_m2_br) of their område,
kommun and city./advertisements serves every listing of the Booli snapshot: Stockholm, Nacka, Solna and Tyresö
(11 139 listings), instead of only the listings of the BRFs with extracted reports.street_name has no trailing space or stray digit.GET /brfs/{orgnr}/financials (?include=values): every verified fiscal year of a BRF: income, costs,
interest, loans, cash, per-m² figures and ratios, and with values where each number is printed in the
report.brf_report_* (latest verified year), brf_land_tenure and
the stambyte assessment.land_tenure on BRF summaries (äganderätt, tomträtt, arrende), from the annual report.GET /advertisements, with the data repo’s contract (parameters, 49 sorts, filters, radius search,
errors, rows) for the listings of the BRFs with extracted reports.homesight_blue, homesight_green), switched by tools/cloud/provision.py.GET /health,
GET /openapi.json, GET /brfs, GET /brfs/{orgnr} (BRF summaries from the extracted annual reports).
Paths without the /api prefix.tools/brf/source_gap.py lists
documents on known source pages that are not imported yet; Gösen 2017–2018 and Solhöjden 2017–2020 imported, not extracted.tools/brf/pdfwords.py also ignores the Visma e-signing stamp.tools/brf/pdfwords.py OCRs scans that carry a GetAccept stamp and honours
ocr: force in a document’s metadata.yaml.