---
title: "Dwelling (Wohnung) records for one or more buildings, by EGID or by parcel EGRID"
description: "Every row of the federal dwelling register (`gwr_dwelling`, loaded monthly by the AV enrichment run's `load_gwr_dwellings.sh`) for the requested buildings, grouped per EGID. This is the only public source of per-dwelling floor/area/room data: geo.admin's GWR layer stops at the building, and housing-stat.ch forbids automated use.\n\nPass EXACTLY ONE of `egid` (1..25 comma-separated building ids - preferred, callers that already read the building register have them) or `egrid` (every EXISTING building on the parcel via `gwr_register`, which holds `GSTAT = 1004` only, so a demolished building is reachable by EGID but not by EGRID). Rows are ordered `egid, floor ASC NULLS LAST, ewid`; a requested building with no dwellings still gets an entry with `count: 0`.\n\n**Caps → `truncated`.** One 2,000-row cap across the whole answer (the largest building carries 460 dwellings), and 25 buildings per `egrid` (718 parcels carry more; the largest 586). Either cut sets `truncated: true`; never sum a truncated answer and present it as the parcel total. Every dwelling state is returned; filter `wstat = 3004` for existing dwellings only.\n\n**Caching.** Redis `gwr:/res_api/gwr/dwellings?<sorted query>` for 6 h with an `X-Cache: HIT|MISS` header. Unlike the other `/gwr` routes this key is NOT flushed by the loader (a shell script with no Redis client), so a monthly reload becomes visible within 6 h.\n\nAuth: `token` header or `?token=` (router-wide, before every `/gwr` route); real status codes, no `X-RES-API-Version` needed. CORS `*`."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.aireon.ch/llms.txt
> Use this file to discover all available pages before exploring further.

Path: RES API (public) › GWR

`GET /res_api/gwr/dwellings`

Every row of the federal dwelling register (`gwr_dwelling`, loaded monthly by the AV enrichment run's `load_gwr_dwellings.sh`) for the requested buildings, grouped per EGID. This is the only public source of per-dwelling floor/area/room data: geo.admin's GWR layer stops at the building, and housing-stat.ch forbids automated use.

Pass EXACTLY ONE of `egid` (1..25 comma-separated building ids - preferred, callers that already read the building register have them) or `egrid` (every EXISTING building on the parcel via `gwr_register`, which holds `GSTAT = 1004` only, so a demolished building is reachable by EGID but not by EGRID). Rows are ordered `egid, floor ASC NULLS LAST, ewid`; a requested building with no dwellings still gets an entry with `count: 0`.

**Caps → `truncated`.** One 2,000-row cap across the whole answer (the largest building carries 460 dwellings), and 25 buildings per `egrid` (718 parcels carry more; the largest 586). Either cut sets `truncated: true`; never sum a truncated answer and present it as the parcel total. Every dwelling state is returned; filter `wstat = 3004` for existing dwellings only.

**Caching.** Redis `gwr:/res_api/gwr/dwellings?<sorted query>` for 6 h with an `X-Cache: HIT|MISS` header. Unlike the other `/gwr` routes this key is NOT flushed by the loader (a shell script with no Redis client), so a monthly reload becomes visible within 6 h.

Auth: `token` header or `?token=` (router-wide, before every `/gwr` route); real status codes, no `X-RES-API-Version` needed. CORS `*`.

## Authentication

Requires one of the following:

- `ResApiToken`, apiKey, in header, header `token`
- `ResApiTokenQuery`, apiKey, in query

## Query parameters

- `egid` (`getGwrDwellings.query.egid`; string, optional): Comma-separated integer EGIDs, 1..25, de-duplicated. Mutually exclusive with `egrid`.
  - pattern `^[0-9]+(,[0-9]+)*$`
- `egrid` (`getGwrDwellings.query.egrid`; string, optional): Parcel EGRID `CH` + 12 digits (case-insensitive). Mutually exclusive with `egid`.
  - pattern `^[Cc][Hh][0-9]{12}$`

## Code samples

### cURL

```bash
curl --request GET \
  --url https://res.aireon.ch/res_api/gwr/dwellings \
  --header 'token: <token>'
```

### TypeScript

```typescript
const url = 'https://res.aireon.ch/res_api/gwr/dwellings';
const options = {method: 'GET', headers: {token: '<token>'}};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://res.aireon.ch/res_api/gwr/dwellings"

headers = {"token": "<token>"}

response = requests.get(url, headers=headers)

print(response.text)
```

## Responses

### 200

Dwellings grouped by building.

#### Example

```json
{
  "egrid": "CH513579227784",
  "vintage": "2026-08-01",
  "count": 3,
  "truncated": false,
  "buildings": [
    {
      "egid": 2158133,
      "count": 3,
      "dwellings": [
        {
          "ewid": 1,
          "edid": 0,
          "whgnr": null,
          "weinr": null,
          "wstwk": 3100,
          "floor": 0,
          "wbez": null,
          "wmehrg": 3200,
          "wbauj": 1962,
          "wabbj": null,
          "wstat": 3004,
          "warea": 84,
          "wazim": 3.5,
          "wkche": 3130
        },
        {
          "ewid": 2,
          "edid": 0,
          "whgnr": null,
          "weinr": null,
          "wstwk": 3101,
          "floor": 1,
          "wbez": null,
          "wmehrg": 3200,
          "wbauj": 1962,
          "wabbj": null,
          "wstat": 3004,
          "warea": 84,
          "wazim": 3.5,
          "wkche": 3130
        },
        {
          "ewid": 3,
          "edid": 0,
          "whgnr": null,
          "weinr": null,
          "wstwk": 3102,
          "floor": 2,
          "wbez": null,
          "wmehrg": 3200,
          "wbauj": 1962,
          "wabbj": null,
          "wstat": 3004,
          "warea": 62,
          "wazim": 2.5,
          "wkche": 3130
        }
      ]
    }
  ]
}
```

- `egrid` (`getGwrDwellings.response.200.egrid`; string | null, required): The requested EGRID, or null on the `egid` path.
- `vintage` (`getGwrDwellings.response.200.vintage`; string | null, required): Latest `wexpdat` (register export date) across the returned rows; null when no row.
  - format `date`
- `count` (`getGwrDwellings.response.200.count`; integer, required): Dwelling rows returned (≤ 2000).
- `truncated` (`getGwrDwellings.response.200.truncated`; boolean, required): True when THIS ANSWER IS SHORT: the 2000-row cap cut the list, or the `egrid` parcel carries more than 25 buildings. Never present a truncated total as the parcel's.
- `buildings` (`getGwrDwellings.response.200.buildings`; array<object>, required): One entry per requested (or resolved) EGID, in request/`ORDER BY egid` order - including buildings with zero dwellings.
  - `egid` (`getGwrDwellings.response.200.buildings.egid`; integer, optional)
  - `count` (`getGwrDwellings.response.200.buildings.count`; integer, optional)
  - `dwellings` (`getGwrDwellings.response.200.buildings.dwellings`; array<object>, optional)
    - `ewid` (`getGwrDwellings.response.200.buildings.dwellings.ewid`; integer, optional): Eidgenössischer Wohnungsidentifikator.
    - `edid` (`getGwrDwellings.response.200.buildings.dwellings.edid`; integer | null, optional): Entrance id (Eingangsidentifikator).
    - `whgnr` (`getGwrDwellings.response.200.buildings.dwellings.whgnr`; string | null, optional): Administrative dwelling number.
    - `weinr` (`getGwrDwellings.response.200.buildings.dwellings.weinr`; string | null, optional): Physical dwelling number.
    - `wstwk` (`getGwrDwellings.response.200.buildings.dwellings.wstwk`; integer | null, optional): Storey CODE (3100 ground floor, 3101.. upper floors, 3401.. basements).
    - `floor` (`getGwrDwellings.response.200.buildings.dwellings.floor`; integer | null, optional): Storey NUMBER derived from `wstwk` at load time: 0 ground, 1..99 up, -1..-19 down.
    - `wbez` (`getGwrDwellings.response.200.buildings.dwellings.wbez`; string | null, optional): Location on the floor.
    - `wmehrg` (`getGwrDwellings.response.200.buildings.dwellings.wmehrg`; integer | null, optional): Multi-storey dwelling flag code.
    - `wbauj` (`getGwrDwellings.response.200.buildings.dwellings.wbauj`; integer | null, optional): Year of construction.
    - `wabbj` (`getGwrDwellings.response.200.buildings.dwellings.wabbj`; integer | null, optional): Year of demolition.
    - `wstat` (`getGwrDwellings.response.200.buildings.dwellings.wstat`; integer | null, optional): Dwelling status code (3004 = existing, 3007 = demolished).
    - `warea` (`getGwrDwellings.response.200.buildings.dwellings.warea`; number | null, optional): Living area, m².
    - `wazim` (`getGwrDwellings.response.200.buildings.dwellings.wazim`; number | null, optional): Number of rooms.
    - `wkche` (`getGwrDwellings.response.200.buildings.dwellings.wkche`; integer | null, optional): Kitchen flag code.

### 400

Both or neither of `egid`/`egrid`; a non-integer or unsafe EGID; more than 25 EGIDs; an EGRID that does not look like `CH123456789012`.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getGwrDwellings.response.400.error`; string, required): Human-readable error description.
- `message` (`getGwrDwellings.response.400.message`; string, optional): Optional underlying error message.

### 401

Missing token.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getGwrDwellings.response.401.error`; string, required): Human-readable error description.
- `message` (`getGwrDwellings.response.401.message`; string, optional): Optional underlying error message.

### 403

Wrong token.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getGwrDwellings.response.403.error`; string, required): Human-readable error description.
- `message` (`getGwrDwellings.response.403.message`; string, optional): Optional underlying error message.

### 500

`{"error":"Internal Server Error"}`.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getGwrDwellings.response.500.error`; string, required): Human-readable error description.
- `message` (`getGwrDwellings.response.500.message`; string, optional): Optional underlying error message.

### 503

`gwr_dwelling` table not loaded yet (Postgres 42P01) - `{"error":"Dwelling register not loaded yet"}`. Run `load_gwr_dwellings.sh`.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getGwrDwellings.response.503.error`; string, required): Human-readable error description.
- `message` (`getGwrDwellings.response.503.message`; string, optional): Optional underlying error message.


Source: https://docs.aireon.ch/res/get-gwr-dwellings/index.md
