NL New-Build Housing Permits Monitor (CBS)
Pricing
from $3.00 / 1,000 gemeente-periode-records
NL New-Build Housing Permits Monitor (CBS)
Officiele CBS-cijfers over vergunde nieuwbouwwoningen per Nederlandse gemeente en kwartaal, met filters op opdrachtgever en eigendomsvorm.
Pricing
from $3.00 / 1,000 gemeente-periode-records
Rating
0.0
(0)
Developer
Dennis
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
NL New-Build Housing Permits Monitor (CBS) ποΈ
Official CBS (Statistics Netherlands) figures on newly permitted homes per Dutch municipality and quarter β straight from CBS StatLine table 83671NED. No login, no API key, no scraping: this is a direct government OData feed.
Why this actor?
Every quarter, CBS publishes how many new-build homes received a building permit, broken down by municipality, client type (government/housing corporation, market developer, private) and tenure (rental/owner-occupied). It's public, free, and goes back to 2012 β but it's only exposed as a raw OData API with quirky filter behavior (its own $filter on the period dimension silently ignores range operators β this actor works around that internally) and cryptic dimension codes (T001209, A028184, ...) instead of readable labels.
This actor does that translation for you:
- ποΈ Real building-permit counts per municipality/quarter β homes, housing units, and holiday homes, going back to 2012KW01
- π·οΈ Human-readable names, not CBS dimension codes β resolves municipality names, client type and tenure live from CBS itself
- π― Flexible breakdowns β a single combined figure per municipality/quarter by default, or split by client type and/or tenure on request
- π Zero configuration β leave the input empty and get the latest available quarter for all ~341 municipalities in one run
- π« No personal data β this is purely aggregated permit-count statistics per municipality, not individual project or applicant data (see "What this Actor does NOT do" below)
When should an AI agent use this?
- "How many new homes were permitted in Amsterdam last quarter?"
- "Compare new-build permit volumes between Utrecht, Rotterdam and The Hague over the last 2 years."
- "Which municipalities show the strongest growth in market-developer-led new-build permits?"
- "Get the historical trend of rental vs. owner-occupied new-build permits nationwide."
- "Is new-build housing supply increasing or slowing down in [municipality]?"
What this Actor does
- Fetches building-permit records from CBS StatLine table
83671NEDvia its OData API - Resolves municipality names and dimension codes (client type, tenure, quarter) to readable labels
- Lets you filter by municipality (name or GM-code), quarter range, client-type breakdown and tenure breakdown
- Caps output per run so you control dataset size and cost
What this Actor does NOT do
- No individual project names, developers, or addresses. CBS
83671NEDis aggregated at municipality level β it tells you how many homes were permitted, not which project. If you need project-level detail, this actor is a complementary, low-risk data source, not a replacement for platforms like Funda Nieuwbouw or Nieuwbouw-nederland.nl. - No "opgeleverd" (completed/delivered) figures β this table covers permits granted, an earlier pipeline stage than completion.
Input
| Field | Type | Description |
|---|---|---|
gemeenten | string[] | Municipality names (e.g. "Amsterdam") or GM-codes (e.g. "GM0363"). Leave empty for all ~341 municipalities. |
periodeVanaf | string | Start quarter, format "2025KW04". Leave empty together with periodeTot to use only the latest available quarter. |
periodeTot | string | End quarter, format "2025KW04". Leave empty to reuse periodeVanaf (a single quarter). |
opdrachtgeverFilter | string | "totaal" (default, one combined row), "overheid-corporatie", "markt", "particulier", or "alle" (separate row per category). |
eigendomFilter | string | "totaal" (default, one combined row), "huur", "koop", or "alle" (separate row per tenure). |
maxResults | integer | Cap on output records per run (default 5000, max 20000). |
berekenTrends | boolean | Add quarter-on-quarter/year-on-year growth fields, calculated from the already-fetched period range. Default false. |
provincieAggregatie | boolean | Add extra summary records per province/quarter/breakdown, summed across all municipalities in that province. Default false. |
Output
{"gemeente": "Amsterdam","gemeenteCode": "GM0363","periode": "2025KW04","periodeLabel": "2025 4e kwartaal","opdrachtgeverType": "Totaal opdrachtgevers","eigendomsvorm": "Totaal","aantalWoningen": 277,"aantalWooneenheden": 0,"aantalRecreatiewoningen": 0,"bouwkostenDuizendEuro": 44452,"bouwkostenPerWoning": 160476.9,"bouwkostenBetrouwbaar": true,"bron": "CBS StatLine 83671NED","aantalWoningenVorigKwartaal": null,"deltaQoQ": null,"deltaQoQPercentage": null,"aantalWoningenVorigJaar": null,"deltaYoY": null,"deltaYoYPercentage": null,"trendBeschikbaar": false}
bouwkostenDuizendEuro is frequently null β CBS withholds building-cost figures when they'd be derived from fewer than 3 underlying permits, to avoid indirectly revealing individual permit values. bouwkostenPerWoning (bouwkostenDuizendEuro Γ 1000 / aantalWoningen) and bouwkostenBetrouwbaar are derived β the latter is false (not just null) whenever the calculation couldn't be made, so you can tell "not calculable" apart from "calculated as zero".
Trend fields (berekenTrends, optional, separately charged)
With berekenTrends: true, each record is compared against other records in the same fetched period range (same
municipality/client-type/tenure): aantalWoningenVorigKwartaal, deltaQoQ, deltaQoQPercentage (vs. the
previous quarter) and aantalWoningenVorigJaar, deltaYoY, deltaYoYPercentage (vs. the same quarter last
year). trendBeschikbaar is true only when at least one of those comparisons was actually possible β e.g.
the very first quarter in your fetched range has nothing to compare against, so it stays false rather than a
guessed zero. Only records with trendBeschikbaar: true are charged the extra trend-signaal-record event.
To make this actually work out of the box, the actor automatically fetches 1 extra quarter (for QoQ) and 1
extra year (for YoY) before the start of your requested period range whenever berekenTrends is enabled β
purely as comparison material, never pushed to the dataset or charged. Without this, a plain
berekenTrends: truetrendBeschikbaar: false for every record. The extra periods actually fetched are listed in
RUN_SUMMARY.extraPeriodesVoorTrendVergelijking.
Province aggregation (provincieAggregatie, optional, separately charged)
With provincieAggregatie: true, extra records are added at the end of the run β one per
province/quarter/client-type/tenure combination, summing aantalWoningen/aantalWooneenheden/
aantalRecreatiewoningen across every municipality in that province (via CBS StatLine 84721NED, the official
municipality-to-province mapping):
{"type": "provincie-periode","provincie": "Noord-Holland","provincieCode": "PV27","periode": "2025KW04","periodeLabel": "2025 4e kwartaal","opdrachtgeverType": "Totaal opdrachtgevers","eigendomsvorm": "Totaal","aantalWoningen": 1830,"aantalWooneenheden": 12,"aantalRecreatiewoningen": 0,"aantalGemeenten": 47,"bron": "CBS StatLine 83671NED + 84721NED (gemeente-provincie-indeling)"}
Each such record is charged as provincie-periode-record. The province totals are always based on the full
fetched set (before any maxResults cap is applied to the pushed municipality-level records), so a large,
broad query never silently undercounts a province just because the cap fell inside it. If maxResults did cut
off some municipality-level records, RUN_SUMMARY.maxResultsAfgekapt/afgekapteRecords reflects that.
Use cases
- Real estate analysts / investors β track which municipalities have the strongest new-build pipeline before it reaches project-listing platforms
- Construction companies β spot municipalities with growing market-developer activity
- Municipal policy makers β benchmark local new-build volume against comparable municipalities
- AI agents & MCP tools β flat JSON, small input schema, resolved names instead of dimension codes
- Combine with NL Permits & Public Notices Leadfeed (see Related Actors) β that actor surfaces individual spatial-plan publications (an earlier pipeline stage than a building permit); use this actor to validate the market-level trend a specific municipality is showing
Pricing
This Actor uses Apify's Pay-Per-Event (PPE) pricing model.
- Actor Start: $0.00005 (Apify default)
- gemeente-periode-record: $0.003 per output record
- trend-signaal-record: $0.008 extra, only with
berekenTrendsenabled and only when a previous-period comparison was actually found - provincie-periode-record: $0.006 per province-level summary record, only with
provincieAggregatieenabled
Legal
- Source: CBS StatLine (
opendata.cbs.nl), the official statistics office of the Dutch government. Table83671NEDis open data, explicitly published for reuse. - No authentication, no scraping β this is a direct, public OData API.
- Data is aggregated per municipality/quarter/client-type/tenure. No addresses, project names, or personal data of any kind.
FAQ
Q: Why does the default run only return one quarter instead of the full 2012-present history?
A: To keep the zero-configuration default fast and cheap. Set periodeVanaf/periodeTot to fetch a wider range β CBS has data back to 2012KW01.
Q: I set a municipality name and got zero results β why?
A: CBS disambiguates municipalities that share a name with their province by adding a suffix, e.g. the province is "Utrecht" but the municipality is "Utrecht (gemeente)". Use the exact CBS name, or a GM-code (e.g. "GM0344") to avoid ambiguity.
Q: What does opdrachtgeverFilter: "alle" actually return?
A: One row per client-type category (government/housing corporation, market developer, private) instead of one combined row β useful when you need the breakdown, not just the total.
Q: How often is the data updated? A: CBS publishes this table quarterly, with a lag of roughly one quarter. A monthly scheduled run is more than sufficient.
Related Actors
Also by this developer:
- NL Permits & Public Notices Leadfeed β surfaces individual spatial-plan/permit publications, an earlier pipeline stage than the building permits aggregated here. Use both together for a full "new-build pipeline" view: spatial plan (leadfeed) β building permit volume (this actor).
Keywords: cbs bouwvergunningen, nieuwbouw per gemeente, statline 83671ned, dutch new-build housing permits, woningmarkt nederland, bouwvergunning statistieken.
Keywords
netherlands, real-estate, housing, construction, cbs, statline, open-data, government-data, mcp-tool
Changelog
0.3.2 - Bugfix
- Fixed
berekenTrendsalmost always returningtrendBeschikbaar: falsewith the default input: the actor now automatically fetches 1 extra quarter/year of comparison-only data before the requested range starts wheneverberekenTrendsis enabled, so the trend feature actually works out of the box. No pricing change β correctness fix on the already-approvedtrend-signaal-recordevent. - Fixed
provincieAggregatiesilently undercounting a province whenmaxResultscut the municipality-level set inside that province's records: province totals are now based on the full fetched set, not the capped one.RUN_SUMMARYnow also reportsmaxResultsAfgekapt/afgekapteRecords. No pricing change.
0.3.0
- Added
berekenTrends: quarter-on-quarter/year-on-year growth fields, calculated purely from the fetched period range. New charged eventtrend-signaal-record($0.008), only when a comparison was actually found. - Added
provincieAggregatie: extra province-level summary records via CBS StatLine84721NED(the official municipality-to-province mapping). New charged eventprovincie-periode-record($0.006). - Both confirmed by the user (2026-07-14, see docs/actor-verbeteringen/PRIJSBESLISSINGEN.md).
0.2.0
- Added
bouwkostenPerWoningandbouwkostenBetrouwbaarβ a derived building-cost-per-home figure, with an explicit boolean instead of a silentnullwhen it can't be calculated. No pricing change.
0.1.0 - Initial release
- Fetch building-permit records from CBS StatLine table 83671NED, filterable by municipality, quarter range, client type and tenure.
- Live-resolved municipality names and dimension labels instead of raw CBS codes.
- Client-type and tenure breakdown modes (combined total vs. separate rows per category).