# Flanders Subdivision Permit Monitor (Verkavelingsvergunningen) (`codeclouds/be-verkavelingsvergunningen`) Actor

Structured Flanders subdivision permits (verkavelingsvergunningen) from the official Omgevingsloket open data: project number, type, status, dates, competent authority, applicant companies with KBO number and the parcel polygon. Optional change detection.

- **URL**: https://apify.com/codeclouds/be-verkavelingsvergunningen.md
- **Developed by:** [Dennis](https://apify.com/codeclouds) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 verkaveling results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Flanders Subdivision Permit Monitor (Verkavelingsvergunningen)

Turn the official Flemish **Omgevingsloket** into a clean, structured feed of **verkavelingsvergunningen** (subdivision permits) — the permits that split land into building plots. Every record carries the project number, permit type, current status, submission and decision dates, the competent authority, applicant companies with their KBO numbers, and the parcel location. No manual searching in the Omgevingsloket, no copying from PDFs, no per-municipality workarounds — one dataset for the whole Flemish Region, ready for a spreadsheet, a CRM, or an AI agent.

This Actor reads the **official MercatorNet public download service** (Departement Omgeving / GDI-Vlaanderen, layer `lu:omv_vk_v2`), the machine-readable open-data twin of the Omgevingsloket. It does not scrape the citizen portal, and it never touches personal data: the source already anonymises natural persons, so only company applicants (with KBO number) appear.

### When should an AI agent use this?

- "Which new subdivision permits were applied for in Flanders in the last 30 days?"
- "Give me every approved verkavelingsvergunning in the municipality of Gent."
- "Which companies applied for a subdivision permit in Vlaams-Brabant this year?" (company search + KBO)
- "Monitor all subdivision permits Flanders-wide and alert me when a status changes."
- "How long does a subdivision permit take from application to decision in Antwerpen?"
- "Find the exact parcel boundaries (polygon) of subdivision project 2026024236."
- "Track new building-plot developments near this address for lead generation."

### What is a verkavelingsvergunning?

In Flanders you need an **omgevingsvergunning voor het verkavelen van gronden** (a subdivision permit) to split a piece of land into multiple building plots before selling them. It is a public decision handled by the municipality, the province or the Flemish Department of Environment (`Departement Omgeving`), and it is registered in the **Omgevingsloket**. Each record tells you *who* wants to subdivide *which* parcels, *when* they applied, and *what* the current status is.

Because it signals land that is about to be developed into building plots, this dataset is a leading indicator for real-estate development, construction and lead generation. As of 2026-09-24 the public file contains **36,625 subdivision dossiers**: 23,668 approved (`Vergunning`), 3,456 refused (`Weigering`), 1,074 under review (`In behandeling`), 8,041 discontinued (`Stopgezet`) and 66 with no decision yet.

### Quick start

Paste one of these into the input and run — start small (10 records ≈ $0.20) to explore.

**1. New subdivision activity in the last 30 days (lead feed):**

```json
{ "mode": "full_snapshot", "laatsteNDagen": 30, "geometryMode": "none", "maxResults": 50 }
```

**2. Only approved permits in a municipality, newest first:**

```json
{ "gemeente": "Gent", "statuses": ["Vergunning"], "geometryMode": "centroid", "maxResults": 100 }
```

**3. B2B leads: which companies applied for a subdivision permit (searchable):**

```json
{ "alleenRechtspersonen": true, "aanvragerBevat": "PROJECT", "laatsteNDagen": 180, "geometryMode": "full", "maxResults": 50 }
```

**4. Monitor for changes on a schedule** (delivers only new/changed permits versus the previous run):

```json
{ "mode": "changes_only", "laatsteNDagen": 365, "maxResults": 2000 }
```

### What this Actor does

- Queries the official **Omgevingsloket - Verkavelingen - V2** open-data layer (WFS 2.0.0, GeoJSON) for the entire Flemish Region.
- Returns one structured record per subdivision permit — both **new subdivisions** and **amendments** — with derived fields that do the arithmetic for you: `isGoedgekeurd`, `isGeweigerd`, `isBeslist`, `isLopend`, `doorlooptijdDagen` (application-to-decision time) and `dagenSindsIndiening`.
- Filters server-side by status, by competent authority (municipality or province), by applicant (company name) and by submission date (absolute range or a relative "last N days").
- Extracts applicant companies out of the free-text applicant field, including the **KBO enterprise number**; `alleenRechtspersonen` keeps only B2B dossiers.
- Returns the **newest subdivisions first** (descending source id), so a size-limited run scans the most relevant, most recent dossiers.
- Offers `geometryMode` (`none` / `centroid` / `full`) so you control payload size, from a small flat dataset to full WGS84 parcel polygons with a centre point.
- Offers a **change-detection mode** (`changes_only`) that compares against the previous run through a persistent key-value store, so scheduled runs deliver only new or changed permits.
- Never crashes on source drift: missing fields, missing geometry and unexpected values are handled gracefully.

### Input

| Field | Type | Description |
|---|---|---|
| `mode` | select | `full_snapshot` (default) delivers all matching permits; `changes_only` delivers only new/changed permits versus the previous run. Change detection only compares the permits this run actually fetches (see FAQ). |
| `statuses` | multi-select | Filter on dossier status. Empty = all. Values: `Geen beslissing genomen`, `In behandeling (in eerste aanleg)`, `In behandeling (na beroep)`, `Stopgezet`, `Vergunning`, `Weigering`. |
| `gemeente` | string | Substring filter on the competent authority, e.g. `Gent`. Covers mainly locally-handled dossiers. Cannot be combined with `provincie`. |
| `provincie` | select | Filter on provincially-handled dossiers (`Provincie Antwerpen`, `Limburg`, `Oost-Vlaanderen`, `Vlaams-Brabant`, `West-Vlaanderen`). **Note:** this does not include locally-handled permits within that province. |
| `aanvragerBevat` | string | Substring filter on the applicant field, e.g. a company name (`PROJECT`, `GEOTEC`) — for market/competitor research. |
| `alleenRechtspersonen` | checkbox | Keep only dossiers with at least one company applicant (with KBO number) — the B2B lead-generation mode. |
| `laatsteNDagen` | number | Only permits submitted within the last N days (1–3650), counted from the run date. Relative alternative to `datumIndieningVanaf`. |
| `datumIndieningVanaf` | date | Only permits submitted on or after this date (`YYYY-MM-DD`). Cannot be combined with `laatsteNDagen`. |
| `datumIndieningTot` | date | Only permits submitted on or before this date (`YYYY-MM-DD`). Combine with `datumIndieningVanaf` for a period. |
| `geometryMode` | select | `none` (no geometry, smallest output), `centroid` (centre point only), `full` (default: full WGS84 parcel polygon + centre point). |
| `maxResults` | number | 1–20,000, default 100. Caps how many permits this run delivers (and therefore the cost). Start with 10–50. |
| `includeSamenvatting` | checkbox | Add one extra summary item per run with counts per status and per competent authority. |

#### About the `gemeente` / `provincie` filters

The open-data layer exposes the **competent authority** (`vvo_huidige_toestand`), not a geographic province field. A permit handled by "Stad Gent" shows `Gent`; a permit handled at provincial level shows `Provincie Antwerpen`; large or complex files may show `Departement Omgeving`. Use `gemeente` for the municipality name, or `provincie` for provincially-handled files — they are mutually exclusive because each dossier has exactly one competent authority.

### Output

One JSON record per subdivision permit, in Dutch (the market's language and the source's own terminology):

```json
{
  "bronId": 12112,
  "projectnummer": "2018011592",
  "voorwerpUuid": "H0nCtBT3Sl-mBrBUXVzCgw",
  "projectUrl": "https://omgevingsloket.omgeving.vlaanderen.be?project=2018011592",
  "typeVerkaveling": "bijstelling_verkaveling",
  "projectTypeCode": "OMV2017_VK_BIJSTELLING",
  "omschrijving": "Bijstelling van een bestaande verkaveling",
  "handelingOmschrijving": "Bijstelling van een verkaveling",
  "status": "Vergunning",
  "datumIndiening": "2018-01-31",
  "datumBeslissing": "2018-05-17",
  "fase": "Eerste Aanleg",
  "bevoegdeOverheid": "Gent",
  "aanvragers": [{ "naam": "RECON BOUW", "kboNummer": "0423331853" }],
  "aanvragerRuw": "RECON BOUW (0423331853); Natuurlijk perso(o)n(en)",
  "heeftRechtspersoonAanvrager": true,
  "isGoedgekeurd": true,
  "isGeweigerd": false,
  "isBeslist": true,
  "isLopend": false,
  "doorlooptijdDagen": 106,
  "dagenSindsIndiening": 3143,
  "geometrie": { "type": "MultiPolygon", "coordinates": [[[[3.69, 51.09]]]] },
  "centroidLat": 51.091385,
  "centroidLon": 3.701829,
  "bron": "omgevingsloket-mercatornet-wfs",
  "opgehaaldOp": "2026-09-24T18:21:33.699Z",
  "changeType": "snapshot"
}
```

- `datumBeslissing` is the date of the current status (`datum_huidige_toestand`); for approved/refused dossiers that is the decision date.
- `doorlooptijdDagen` is only set for decided dossiers (`isBeslist`); for pending/discontinued dossiers use `dagenSindsIndiening`.
- `changeType` is `snapshot` in `full_snapshot` mode; in `changes_only` mode it is `nieuw`, `statuswijziging` (the dossier status changed) or `gewijzigd` (e.g. a new status date with the same status).

### Use cases

- **Land & development intelligence** — follow subdivision activity per region to find future building plots before they are advertised.
- **Lead generation for architects, surveyors and contractors** — companies appear with their KBO number at the moment a subdivision is applied for or approved; filter with `alleenRechtspersonen`.
- **Real-estate and notary due diligence** — confirm the permit status and parcel boundaries of a specific subdivision project.
- **Municipal / regional benchmarking** — compare subdivision volumes, approval ratios and application-to-decision throughput (`doorlooptijdDagen`) across authorities.
- **Compliance and monitoring pipelines** — feed a database or map that must reflect new Flemish subdivision permits.

### Pricing

This Actor uses Apify's Pay-Per-Event (PPE) pricing model.

- **Actor Start:** $0.00005 (Apify default)
- **verkaveling-result:** $0.02 per delivered subdivision permit (snapshot mode)
- **verkavelingswijziging:** $0.05 per newly detected or changed permit (change-detection mode)

A default run (`maxResults: 100`) therefore costs about $2; start with `maxResults: 10` (~$0.20) to explore. Use the filters to control spend.

### Legal

- **Source:** official open data from the Flemish Government (Departement Omgeving), served through the MercatorNet Public Download Service (`lu:omv_vk_v2`).
- **Licence:** free open-data licence of the Flemish Government ("Gratis open data licentie Vlaanderen") — reuse, including commercial reuse, is permitted.
- **Personal data:** the source does not publish natural persons; only legal entities (with their public KBO number) appear as applicants. No personal data is collected, processed or republished by this Actor.
- **Independence:** this Actor is not affiliated with or endorsed by the Flemish Government. Data is provided "as is"; always verify against the official Omgevingsloket before making legal or financial decisions.

### FAQ

**Q: Does this include subdivision permits per municipality, or only provincial ones?**
A: Both. Most files are handled locally (the municipality appears as competent authority); larger files are handled at provincial level. The `provincie` filter intentionally selects only the provincially-handled files — use `gemeente` for a specific municipality.

**Q: Why is there no province field for every record?**
A: The official open-data layer does not include a geographic province attribute; it exposes the competent authority instead. A reliable province field would require a spatial join against province boundaries, which this Actor does not claim to do.

**Q: How fresh is the data?**
A: The layer is continuously updated ("Continu geactualiseerd") by Departement Omgeving. Each record carries `opgehaaldOp` for the exact fetch time.

**Q: What does `changes_only` do on the first run?**
A: There is no previous snapshot yet, so everything matches as `nieuw`. From the second run on, only genuinely new or changed permits are delivered.

**Q: Which permits does `changes_only` actually compare?**
A: Only the permits this run fetches, which is `maxResults` records after applying your filters — newest first. A status change on a permit outside that window is not detected until it re-enters the window. For a dependable monitor, use `maxResults` large enough (or a `laatsteNDagen` window plus a large `maxResults`) to cover the dossiers you care about each run.

**Q: What is the difference between `geometryMode` centroid and full?**
A: `centroid` returns only the parcel centre point (a small lat/lon), while `full` also returns the complete WGS84 parcel polygon. Both require fetching the geometry from the source; `none` skips it entirely for the smallest, fastest output.

### Related Actors

- **[NL Vergunningen & Bekendmakingen Leadfeed](https://apify.com/codeclouds/nl-vergunningen-leadfeed)** — the Dutch counterpart for Dutch permit leads, useful if you build permits/leads pipelines for both NL and Flanders.
- **[Flanders Water Extraction Ban Monitor (Captatieverbod)](https://apify.com/codeclouds/be-captatieverbod-monitor)** — another Flemish open-data monitor from the same publisher, for water- and drought-related risk in Flanders.

*Zoekwoorden: verkavelingsvergunning, verkavelingen Vlaanderen, omgevingsloket, Omgevingsloket Vlaanderen, bouwgrond Vlaanderen, verkavelingsaanvraag, MercatorNet, Departement Omgeving, nieuwe verkaveling, bijstelling verkaveling, vastgoedontwikkeling Vlaanderen, bouwgrond monitoring, bedrijven aanvrager KBO.*

### Keywords

verkavelingsvergunning, omgevingsvergunning, omgevingsloket, flanders, vlaanderen, belgium, subdivision permit, land development, building plots, permit monitor, open data, geojson, parcel polygon, kbo, lead generation

### Changelog

#### 0.1.0

- Initial release: full Flemish subdivision-permit feed with status/authority/applicant/date filters, company (KBO) search, derived status and throughput fields, configurable geometry, and cross-run change detection.

# Actor input Schema

## `mode` (type: `string`):

full\_snapshot = lever alle (gefilterde) verkavelingen. changes\_only = lever alleen nieuwe of gewijzigde verkavelingen t.o.v. de vorige run (cross-run-vergelijking in een benoemde key-value store; de allereerste run levert alles als 'nieuw'). Let op: changes\_only vergelijkt alleen de dossiers die deze run ophaalt (nieuwste eerst, afgekapt op maxResults) — kies maxResults dus ruim genoeg of gebruik een datumfilter.

## `statuses` (type: `array`):

Filter op de dossierstatus (`huidige_toestand`). Meerdere keuzes mogelijk. Leeg laten = alle statussen.

## `gemeente` (type: `string`):

Substring-filter op de bevoegde overheid, bv. "Gent" of "Brugge". Dekt hoofdzakelijk lokaal (gemeentelijk) behandelde dossiers. Niet combineerbaar met `provincie`.

## `provincie` (type: `string`):

Filtert op dossiers behandeld door "Provincie <naam>". LET OP: dit dekt NIET de gemeentelijk behandelde verkavelingen binnen die provincie. Niet combineerbaar met `gemeente`.

## `aanvragerBevat` (type: `string`):

Substring-filter op het aanvragerveld, bv. een bedrijfsnaam ("PROJECT", "GEOTEC"). Handig voor markt- of concurrentieonderzoek naar wie welke verkaveling aanvroeg.

## `alleenRechtspersonen` (type: `boolean`):

Als aan: alleen dossiers met minstens één bedrijfsaanvrager (met KBO-nummer). Dit is de B2B-leadgen-modus; natuurlijke personen zijn in de bron toch al anoniem.

## `laatsteNDagen` (type: `number`):

Geheel getal 1-3650: alleen dossiers die in deze periode zijn ingediend (gerekend vanaf de rundatum). Relatief alternatief voor `datumIndieningVanaf`; niet combineerbaar daarmee.

## `datumIndieningVanaf` (type: `string`):

Alleen dossiers met een indieningsdatum op of na deze datum. Laat leeg voor alle jaren. Niet combineerbaar met `laatsteNDagen`.

## `datumIndieningTot` (type: `string`):

Alleen dossiers met een indieningsdatum op of vóór deze datum. Combineerbaar met `datumIndieningVanaf` voor een periode.

## `geometryMode` (type: `string`):

none = geen geometrie (kleinste, snelste output); centroid = alleen het middelpunt (lat/lon); full = volledige perceelcontour (WGS84 GeoJSON MultiPolygon) plus middelpunt.

## `maxResults` (type: `number`):

Geheel getal 1-20.000: maximum aantal verkavelingen dat deze run wordt geleverd. Bepaalt direct de kosten (per record via Pay Per Event). Begin klein, bv. 10.

## `includeSamenvatting` (type: `boolean`):

Als aan: één extra dataset-item per run met tellingen per status en per bevoegde overheid. Gratis, geen extra event.

## Actor input object example

```json
{
  "mode": "full_snapshot",
  "statuses": [],
  "alleenRechtspersonen": false,
  "geometryMode": "full",
  "maxResults": 100,
  "includeSamenvatting": false
}
```

# Actor output Schema

## `results` (type: `string`):

Verkavelingsrecords in de default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("codeclouds/be-verkavelingsvergunningen").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("codeclouds/be-verkavelingsvergunningen").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call codeclouds/be-verkavelingsvergunningen --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codeclouds/be-verkavelingsvergunningen"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/VVFKT30tZrQPpdGAt/builds/vGsK6ZA7INJ7tqeqb/openapi.json
