MENU navbar-image

Introduction

API for accessing Swiss building registry (GWR) data, electricity tariffs from grid operators (VNB), and related infrastructure information.

This documentation aims to provide all the information you need to work with our API.

<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your API token by logging into your account and navigating to Settings → API Tokens. Use Laravel Sanctum Bearer tokens for authentication.

Buildings

List buildings by municipality (BFS)

requires authentication

Returns a paginated list of GWR buildings for a given municipality (BFS number). Code label resolution is disabled by default for performance; enable with resolve_codes=1.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings?municipality=261&per_page=200&lang=de&resolve_codes=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"per_page\": 17,
    \"lang\": \"de\",
    \"resolve_codes\": true
}"
const url = new URL(
    "https://gwr-datahub.test/api/buildings"
);

const params = {
    "municipality": "261",
    "per_page": "200",
    "lang": "de",
    "resolve_codes": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "per_page": 17,
    "lang": "de",
    "resolve_codes": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   string     

integer BFS municipality number. Example: 261

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 200. Example: 200

lang   string  optional    

Language for code labels when resolve_codes=1. Options: de, fr, it. Default: de. Example: de

resolve_codes   boolean  optional    

Whether to resolve code labels. Default: 0. Example: true

Body Parameters

municipality   number     

Example: 4326.41688

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 17

lang   string  optional    

Example: de

Must be one of:
  • de
  • fr
  • it
resolve_codes   boolean  optional    

Example: true

Get lightweight map data for buildings by municipality

requires authentication

Returns minimal building data optimized for map visualizations. Only includes buildings with valid coordinates (latitude/longitude).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/map-data?municipality=261&per_page=200&page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"per_page\": 17,
    \"page\": 35
}"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/map-data"
);

const params = {
    "municipality": "261",
    "per_page": "200",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "per_page": 17,
    "page": 35
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/map-data

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   string     

integer BFS municipality number. Example: 261

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 200. Example: 200

page   integer  optional    

Page number. Min: 1. Default: 1. Example: 1

Body Parameters

municipality   number     

Example: 4326.41688

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 17

page   integer  optional    

Must be at least 1. Example: 35

Get building information by EGID

requires authentication

Returns detailed information about a building from the GWR (Gebäude- und Wohnungsregister) database. All code fields are automatically resolved to their human-readable labels in the specified language.

If address or solar potential data is missing, it will be automatically synchronized before returning the response.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/1234567890?lang=de&sync=" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/1234567890"
);

const params = {
    "lang": "de",
    "sync": "0",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "egid": "1234567890",
    "gdekt": "ZH",
    "ggdenr": "261",
    "ggdename": "Zürich",
    "egrid": "2680000.0,1240000.0",
    "gbez": "Wohnhaus",
    "gkode": "01",
    "gkode_label": "Wohngebäude",
    "gstat": "01",
    "gstat_label": "Bestehend",
    "gkat": "01",
    "gkat_label": "Einfamilienhaus",
    "gbauj": 1990,
    "garea": 150.5,
    "gvol": 450,
    "address": {
        "street": "Hauptstrasse 45",
        "postal_code": "6260",
        "city": "Reiden"
    },
    "solar_roofs": [
        {
            "attributes": {
                "building_id": "229760",
                "suitability": "high"
            },
            "geometry": {
                "rings": [
                    [
                        [
                            2640325.75,
                            1232914.625
                        ]
                    ]
                ]
            }
        }
    ],
    "solar_facades": [
        {
            "attributes": {
                "building_id": "229760",
                "suitability": "medium"
            },
            "geometry": {
                "rings": [
                    [
                        [
                            2640325.75,
                            1232914.625
                        ]
                    ]
                ]
            }
        }
    ],
    "created_at": "2025-01-01T00:00:00+00:00",
    "updated_at": "2025-01-01T00:00:00+00:00"
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "message": "Building not found"
}
 

Request      

GET api/buildings/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

string The building EGID (Eidgenössische Gebäudeidentifikator). Example: 1234567890

Query Parameters

lang   string  optional    

The language for code labels. Options: de (German), fr (French), it (Italian). Default: de. Example: de

sync   boolean  optional    

Whether to sync missing address/solar data from external APIs (OSB, GeoAdmin). Default: 0 (disabled). Set to 1 to enable on-demand sync. When disabled, returns only locally stored data. Example: false

EVU Tariffs

List all grid operators

requires authentication

Returns a paginated list of all active grid operators (Verteilnetzbetreiber) with their tariff URL status and information about the latest successful tariff submission.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/evu-tariffs/operators?per_page=50&status=found&search=EKZ" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/evu-tariffs/operators"
);

const params = {
    "per_page": "50",
    "status": "found",
    "search": "EKZ",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "ch_uid": "CHE-108.954.688",
            "name": "Elektrizitätswerke des Kantons Zürich (EKZ)",
            "website_url": "www.ekz.ch",
            "tariff_url": "https://ekz.ch/api/tariffs.json",
            "tariff_url_status": "found",
            "tariff_url_verified_at": "2026-01-15T10:00:00+00:00",
            "is_active": true,
            "latest_submission": {
                "fetched_at": "2026-01-15T10:00:00+00:00",
                "tariff_year": 2026,
                "tariff_count": 12
            },
            "elcom_synced_at": "2026-01-01T00:00:00+00:00"
        }
    ],
    "links": {
        "first": "https://example.com/api/evu-tariffs/operators?page=1",
        "last": "https://example.com/api/evu-tariffs/operators?page=10",
        "prev": null,
        "next": "https://example.com/api/evu-tariffs/operators?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 10,
        "per_page": 50,
        "to": 50,
        "total": 500
    }
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Request      

GET api/evu-tariffs/operators

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

per_page   integer  optional    

Number of items per page. Min: 1, Max: 100. Default: 50. Example: 50

status   string  optional    

Filter by tariff URL status. Options: pending, found, not_found, manual, invalid. Example: found

search   string  optional    

Search by operator name or CH UID. Example: EKZ

Get a single grid operator

requires authentication

Returns detailed information about a specific grid operator (Verteilnetzbetreiber) by its CH UID, including the latest submission status and tariff URL information.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "ch_uid": "CHE-108.954.688",
    "name": "Elektrizitätswerke des Kantons Zürich (EKZ)",
    "website_url": "www.ekz.ch",
    "tariff_url": "https://ekz.ch/api/tariffs.json",
    "tariff_url_status": "found",
    "tariff_url_verified_at": "2026-01-15T10:00:00+00:00",
    "is_active": true,
    "latest_submission": {
        "fetched_at": "2026-01-15T10:00:00+00:00",
        "tariff_year": 2026,
        "tariff_count": 12
    },
    "elcom_synced_at": "2026-01-01T00:00:00+00:00"
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "error": "Grid operator not found",
    "code": "operator_not_found"
}
 

Request      

GET api/evu-tariffs/operators/{chUid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

string The CH UID (Unternehmens-Identifikationsnummer) of the grid operator. Example: CHE-108.954.688

Get tariffs for a grid operator

requires authentication

Returns the cached tariffs for a specific grid operator in the standard format according to StromVV Art. 7b. The response includes all tariff types:

Tariff forms can be:

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688/tariffs?year=2026" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688/tariffs"
);

const params = {
    "year": "2026",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "dsoName": "Elektrizitätswerke des Kantons Zürich (EKZ)",
    "dsoNumber": 10895468800,
    "tariffs": [
        {
            "customerVoltageLevel": 7,
            "tariffName": "Haushalt Standard",
            "tariffType": "electricity",
            "tariffForm": "multilevel",
            "startDate": "2026-01-01",
            "endDate": "2026-12-31",
            "comment": null,
            "customerType": "household",
            "prices": {
                "multilevel": {
                    "levels": [
                        {
                            "name": "HT",
                            "price": 0.22,
                            "unit": "CHF/kWh"
                        },
                        {
                            "name": "NT",
                            "price": 0.18,
                            "unit": "CHF/kWh"
                        }
                    ]
                }
            }
        },
        {
            "customerVoltageLevel": 7,
            "tariffName": "Netznutzung Haushalt",
            "tariffType": "grid",
            "tariffForm": "constant",
            "startDate": "2026-01-01",
            "endDate": "2026-12-31",
            "comment": null,
            "customerType": "household",
            "prices": {
                "constant": {
                    "price": 0.08,
                    "unit": "CHF/kWh"
                }
            }
        }
    ],
    "_meta": {
        "ch_uid": "CHE-108.954.688",
        "fetched_at": "2026-01-15T10:00:00+00:00",
        "tariff_year": 2026,
        "source_url": "https://ekz.ch/api/tariffs.json"
    }
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404, Operator not found):


{
    "error": "Grid operator not found",
    "code": "operator_not_found"
}
 

Example response (404, No tariffs available):


{
    "error": "No tariffs found for this operator",
    "code": "tariffs_not_found",
    "operator": "CHE-108.954.688",
    "year": 2026
}
 

Request      

GET api/evu-tariffs/operators/{chUid}/tariffs

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

string The CH UID of the grid operator. Example: CHE-108.954.688

Query Parameters

year   integer  optional    

Filter by tariff year. Default: current year. Example: 2026

Proxy dynamic tariff data

requires authentication

Proxies requests to the dynamic tariff URL of a grid operator to retrieve real-time pricing data. This endpoint is only available for operators that offer dynamic tariffs (tariffForm: "dynamic").

The response format depends on the grid operator's implementation but typically includes current and/or upcoming electricity prices with timestamps.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688/dynamic" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/evu-tariffs/operators/CHE-108.954.688/dynamic"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2026-01-15T14:00:00+01:00",
    "prices": [
        {
            "start": "2026-01-15T14:00:00+01:00",
            "end": "2026-01-15T15:00:00+01:00",
            "price": 0.185,
            "unit": "CHF/kWh"
        },
        {
            "start": "2026-01-15T15:00:00+01:00",
            "end": "2026-01-15T16:00:00+01:00",
            "price": 0.215,
            "unit": "CHF/kWh"
        }
    ]
}
 

Example response (400, No dynamic tariff available):


{
    "error": "Operator does not have a dynamic tariff URL configured",
    "code": "proxy_error"
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "error": "Grid operator not found",
    "code": "operator_not_found"
}
 

Example response (502, Upstream error):


{
    "error": "Failed to fetch dynamic tariff data from operator",
    "code": "proxy_error"
}
 

Request      

GET api/evu-tariffs/operators/{chUid}/dynamic

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

string The CH UID of the grid operator. Example: CHE-108.954.688

BDEW Profiles

List all BDEW profile codes

requires authentication

Returns a list of all available BDEW standard load profile codes (e.g., H0, G0-G6, L0-L2). Each profile code represents a category of electricity consumption patterns.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/bdew-profiles" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/bdew-profiles"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "code": "H0",
            "name": "Household",
            "category": "household",
            "description": "Standard household profile",
            "metadata": {}
        },
        {
            "code": "G25",
            "name": "Commercial",
            "category": "commercial",
            "description": "Commercial profile",
            "metadata": {}
        }
    ]
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Request      

GET api/bdew-profiles

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Get all variations for a BDEW profile code

requires authentication

Returns all 9 variations (3 seasons × 3 day types) for a specific BDEW profile code. Each variation contains 96 normalized values representing 15-minute intervals for a day.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/bdew-profiles/H0" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/bdew-profiles/H0"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "code": "H0",
  "name": "Household",
  "category": "household",
  "variations": [
    {
      "profile_code": "H0",
      "season": "winter",
      "day_type": "weekday",
      "values": [0.0104, 0.0099, ...],
      "is_dynamized": true,
      "description": null,
      "metadata": {}
    },
    {
      "profile_code": "H0",
      "season": "winter",
      "day_type": "saturday",
      "values": [0.0104, 0.0099, ...],
      "is_dynamized": true,
      "description": null,
      "metadata": {}
    }
  ]
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "message": "Profile code not found"
}
 

Request      

GET api/bdew-profiles/{code}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

string The BDEW profile code (e.g., H0, G25, L25). Example: H0

Get daily template for a BDEW profile code by date

requires authentication

Returns the correct BDEW load profile template for a specific date. The season (winter/summer/transition) and day type (weekday/saturday/sunday) are automatically determined from the date.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/bdew-profiles/H0/daily?date=2025-01-15" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"date\": \"2026-07-14\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/bdew-profiles/H0/daily"
);

const params = {
    "date": "2025-01-15",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "date": "2026-07-14"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "code": "H0",
  "date": "2025-01-15",
  "season": "winter",
  "day_type": "wednesday",
  "values": [0.0104, 0.0099, ...],
  "is_dynamized": true,
  "description": null,
  "metadata": {}
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "message": "Profile code not found"
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "date": [
            "The date field is required."
        ]
    }
}
 

Request      

GET api/bdew-profiles/{code}/daily

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

string The BDEW profile code (e.g., H0, G25, L25). Example: H0

Query Parameters

date   string     

string The date in YYYY-MM-DD format. Example: 2025-01-15

Body Parameters

date   string     

Must be a valid date in the format Y-m-d. Example: 2026-07-14

Get yearly profile for a BDEW profile code

requires authentication

Returns a complete year's worth of BDEW load profile data with all 365/366 days. Each day includes 96 quarter-hour values, with dynamization applied where applicable. Holidays are treated as Sundays, and Dec 24/31 use Saturday templates.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/bdew-profiles/H25/year?year=2025" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
const url = new URL(
    "https://gwr-datahub.test/api/bdew-profiles/H25/year"
);

const params = {
    "year": "2025",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "code": "H25",
  "year": 2025,
  "is_dynamized": true,
  "total_kwh": 1000000.00,
  "days": [
    {
      "date": "2025-01-01",
      "day_of_year": 1,
      "month": 1,
      "day_type": "sunday",
      "is_holiday": true,
      "holiday_name": "Neujahr",
      "dynamization_factor": 1.2421,
      "values": [22.15, 20.81, 19.76, ...]
    }
  ],
  "meta": {
    "total_days": 365,
    "is_leap_year": false,
    "generated_at": "2025-01-15T10:30:00Z"
  }
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (404):


{
    "message": "Profile code not found"
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "year": [
            "The year field is required."
        ]
    }
}
 

Request      

GET api/bdew-profiles/{code}/year

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

string The BDEW profile code (e.g., H25, G25, L25). Example: H25

Query Parameters

year   string     

integer The year for the profile (2020-2035). Example: 2025

Body Parameters

year   string  optional    

List available years for a profile code

requires authentication

Returns the years that have pre-generated yearly profiles available.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/bdew-profiles/H25/years" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/bdew-profiles/H25/years"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "code": "H25",
    "available_years": [
        2024,
        2025,
        2026
    ],
    "supported_range": {
        "min": 2020,
        "max": 2035
    }
}
 

Example response (404):


{
    "message": "Profile code not found"
}
 

Request      

GET api/bdew-profiles/{code}/years

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

string The BDEW profile code (e.g., H25, G25). Example: H25

Reference Market Prices

List reference market prices

requires authentication

Returns a paginated list of BFE reference market prices (Art. 15 EnFV). Prices are available for different technologies (photovoltaic, hydropower, biomass, wind, geothermal) and different period types (monthly, quarterly).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-prices?technology=photovoltaic&period_type=monthly&year=2025&per_page=100" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"technology\": \"photovoltaic\",
    \"period_type\": \"monthly\",
    \"year\": 1,
    \"per_page\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-prices"
);

const params = {
    "technology": "photovoltaic",
    "period_type": "monthly",
    "year": "2025",
    "per_page": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "technology": "photovoltaic",
    "period_type": "monthly",
    "year": 1,
    "per_page": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "technology": "photovoltaic",
            "technology_label": "Photovoltaik",
            "period_type": "monthly",
            "period_type_label": "Monatlich",
            "year": 2025,
            "period": 1,
            "period_label": "Januar 2025",
            "price": 85.5,
            "price_unit": "CHF/MWh",
            "volume": 125000,
            "volume_unit": "MWh",
            "created_at": "2025-01-15T12:00:00+00:00",
            "updated_at": "2025-01-15T12:00:00+00:00"
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": "..."
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 5,
        "per_page": 100,
        "to": 100,
        "total": 450
    }
}
 

Request      

GET api/reference-market-prices

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

technology   string  optional    

Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal. Example: photovoltaic

period_type   string  optional    

Filter by period type. Options: monthly, quarterly. Example: monthly

year   integer  optional    

Filter by year. Example: 2025

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 100. Example: 100

Body Parameters

technology   string  optional    

Example: photovoltaic

Must be one of:
  • photovoltaic
  • hydropower
  • biomass
  • wind
  • geothermal
period_type   string  optional    

Example: monthly

Must be one of:
  • monthly
  • quarterly
year   integer  optional    

Must be at least 2007. Must not be greater than 2100. Example: 1

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 22

Get latest prices per technology

requires authentication

Returns the most recent reference market price for each technology, grouped by period type (monthly and quarterly).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-prices/latest" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-prices/latest"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "monthly": {
        "photovoltaic": {
            "id": 1,
            "technology": "photovoltaic",
            "technology_label": "Photovoltaik",
            "period_type": "monthly",
            "period_type_label": "Monatlich",
            "year": 2025,
            "period": 12,
            "period_label": "Dezember 2025",
            "price": 85.5,
            "price_unit": "CHF/MWh",
            "volume": 125000,
            "volume_unit": "MWh",
            "created_at": "2025-01-15T12:00:00+00:00",
            "updated_at": "2025-01-15T12:00:00+00:00"
        }
    },
    "quarterly": {
        "photovoltaic": {
            "id": 2,
            "technology": "photovoltaic",
            "period_type": "quarterly",
            "year": 2025,
            "period": 4,
            "period_label": "Q4 2025",
            "price": 82.3
        }
    }
}
 

Request      

GET api/reference-market-prices/latest

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

List available technologies

requires authentication

Returns a list of all available technologies with their labels.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-prices/technologies" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-prices/technologies"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "technologies": [
        {
            "value": "photovoltaic",
            "label": "Photovoltaik"
        },
        {
            "value": "hydropower",
            "label": "Wasserkraft"
        },
        {
            "value": "biomass",
            "label": "Biomasse"
        },
        {
            "value": "wind",
            "label": "Windenergie"
        },
        {
            "value": "geothermal",
            "label": "Geothermie"
        }
    ],
    "period_types": [
        {
            "value": "monthly",
            "label": "Monatlich"
        },
        {
            "value": "quarterly",
            "label": "Quartal"
        }
    ]
}
 

Request      

GET api/reference-market-prices/technologies

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Reference Market Price Predictions

List reference market price predictions

requires authentication

Returns a paginated list of predicted reference market prices based on EPEX spot prices and ENTSO-E generation profiles (BFE Art. 15 EnFV methodology).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-price-predictions?technology=photovoltaic&period_type=monthly&year=2026&per_page=100" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"technology\": \"geothermal\",
    \"period_type\": \"monthly\",
    \"year\": 1,
    \"per_page\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-price-predictions"
);

const params = {
    "technology": "photovoltaic",
    "period_type": "monthly",
    "year": "2026",
    "per_page": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "technology": "geothermal",
    "period_type": "monthly",
    "year": 1,
    "per_page": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "technology": "photovoltaic",
            "technology_label": "Photovoltaik",
            "period_type": "monthly",
            "period_type_label": "Monatlich",
            "year": 2026,
            "period": 1,
            "period_label": "Januar 2026",
            "price": 72.35,
            "price_unit": "CHF/MWh",
            "volume": 125000,
            "volume_unit": "MWh",
            "calculated_at": "2026-02-10T07:30:00+00:00",
            "data_completeness": 98.5,
            "is_partial": false,
            "created_at": "2026-01-15T12:00:00+00:00",
            "updated_at": "2026-02-10T07:30:00+00:00"
        }
    ],
    "links": {},
    "meta": {}
}
 

Request      

GET api/reference-market-price-predictions

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

technology   string  optional    

Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal. Example: photovoltaic

period_type   string  optional    

Filter by period type. Options: monthly, quarterly. Example: monthly

year   integer  optional    

Filter by year. Example: 2026

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 100. Example: 100

Body Parameters

technology   string  optional    

Example: geothermal

Must be one of:
  • photovoltaic
  • hydropower
  • biomass
  • wind
  • geothermal
period_type   string  optional    

Example: monthly

Must be one of:
  • monthly
  • quarterly
year   integer  optional    

Must be at least 2020. Must not be greater than 2100. Example: 1

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 22

Get latest predictions per technology

requires authentication

Returns the most recent prediction for each technology, grouped by period type (monthly and quarterly).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-price-predictions/latest" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-price-predictions/latest"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "monthly": {
        "photovoltaic": {}
    },
    "quarterly": {
        "photovoltaic": {}
    }
}
 

Request      

GET api/reference-market-price-predictions/latest

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Get current month prediction

requires authentication

Returns the prediction for the current (in-progress) month, including data completeness and partial status.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-price-predictions/current-month" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-price-predictions/current-month"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "year": 2026,
    "month": 2,
    "predictions": {}
}
 

Request      

GET api/reference-market-price-predictions/current-month

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Compare predictions with official BFE values

requires authentication

Returns a side-by-side comparison of predicted values against the official BFE reference market prices where both are available.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/reference-market-price-predictions/compare?technology=photovoltaic&year=2026" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/reference-market-price-predictions/compare"
);

const params = {
    "technology": "photovoltaic",
    "year": "2026",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "comparisons": [
        {
            "technology": "photovoltaic",
            "period_type": "monthly",
            "year": 2026,
            "period": 1,
            "period_label": "Januar 2026",
            "predicted_price": 72.35,
            "official_price": 73.1,
            "deviation": -0.75,
            "deviation_percent": -1.03,
            "data_completeness": 98.5
        }
    ]
}
 

Request      

GET api/reference-market-price-predictions/compare

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

technology   string  optional    

Filter by technology. Example: photovoltaic

year   integer  optional    

Filter by year. Example: 2026

Transformer Stations

List transformer stations

requires authentication

Returns a list of transformer stations (Trafostationen) with various filtering options. You can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates. Coordinates are taken directly from gwr_buildings.GKODE (Easting) and gwr_buildings.GKODN (Northing). The egrid field contains the raw EGRID value from gwr_buildings.EGRID.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/transformer-stations?municipality=261&postal_code=8001&status=confirmed&lat=47.3769&lng=8.5417&radius=1000&east=2680000&north=1240000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"postal_code\": 4326.41688,
    \"lat\": -90,
    \"lng\": -180,
    \"east\": 4326.41688,
    \"north\": 4326.41688,
    \"radius\": 17,
    \"status\": \"confirmed\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/transformer-stations"
);

const params = {
    "municipality": "261",
    "postal_code": "8001",
    "status": "confirmed",
    "lat": "47.3769",
    "lng": "8.5417",
    "radius": "1000",
    "east": "2680000",
    "north": "1240000",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "postal_code": 4326.41688,
    "lat": -90,
    "lng": -180,
    "east": 4326.41688,
    "north": 4326.41688,
    "radius": 17,
    "status": "confirmed"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "egid": "1234567890",
            "status": "confirmed",
            "building": {
                "egid": "1234567890",
                "gbez": "Trafo Station 1",
                "ggdenr": "261",
                "ggdename": "Zürich",
                "egrid": "2680000.0,1240000.0"
            },
            "address": {
                "street": "Hauptstrasse 45",
                "postal_code": "6260",
                "city": "Reiden"
            },
            "solar_roofs": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "high"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "solar_facades": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "medium"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "coordinates": {
                "east": 2680000,
                "north": 1240000
            },
            "coordinates_wgs84": {
                "lat": 47.3769,
                "lng": 8.5417
            },
            "created_at": "2025-01-01T00:00:00+00:00",
            "updated_at": "2025-01-01T00:00:00+00:00"
        }
    ]
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "lat": [
            "The lat field is required when lng is present."
        ]
    }
}
 

Request      

GET api/transformer-stations

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   integer  optional    

Filter by municipality BFS number (Gemeindenummer). Example: 261

postal_code   integer  optional    

Filter by postal code (PLZ). Example: 8001

status   string  optional    

Filter by status. Options: candidate, confirmed. Example: confirmed

lat   number  optional    

Latitude (WGS84) for radius search. Required together with lng and radius. Example: 47.3769

lng   number  optional    

Longitude (WGS84) for radius search. Required together with lat and radius. Example: 8.5417

radius   number  optional    

Search radius in meters (WGS84). Required together with lat and lng. Min: 1, Max: 50000. Example: 1000

east   number  optional    

Easting (CH1903+) for radius search. Required together with north and radius. Example: 2680000

north   number  optional    

Northing (CH1903+) for radius search. Required together with east and radius. Example: 1240000

Body Parameters

municipality   number  optional    

Example: 4326.41688

postal_code   number  optional    

Example: 4326.41688

lat   number  optional    

This field is required when lng or radius is present. Must be between -90 and 90. Example: -90

lng   number  optional    

This field is required when lat or radius is present. Must be between -180 and 180. Example: -180

east   number  optional    

This field is required when north or radius is present. Example: 4326.41688

north   number  optional    

This field is required when east or radius is present. Example: 4326.41688

radius   number  optional    

Must be at least 1. Must not be greater than 50000. Example: 17

status   string  optional    

Example: confirmed

Must be one of:
  • candidate
  • confirmed

Educational Institutions

List educational institutions

requires authentication

Returns a list of educational institutions (Schulhäuser, Kindergärten, etc.) with various filtering options. You can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates. Coordinates are taken directly from gwr_buildings.GKODE (Easting) and gwr_buildings.GKODN (Northing).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/educational-institutions?municipality=261&postal_code=8001&status=confirmed&lat=47.3769&lng=8.5417&radius=1000&east=2680000&north=1240000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"postal_code\": 4326.41688,
    \"lat\": -90,
    \"lng\": -180,
    \"east\": 4326.41688,
    \"north\": 4326.41688,
    \"radius\": 17,
    \"status\": \"confirmed\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/educational-institutions"
);

const params = {
    "municipality": "261",
    "postal_code": "8001",
    "status": "confirmed",
    "lat": "47.3769",
    "lng": "8.5417",
    "radius": "1000",
    "east": "2680000",
    "north": "1240000",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "postal_code": 4326.41688,
    "lat": -90,
    "lng": -180,
    "east": 4326.41688,
    "north": 4326.41688,
    "radius": 17,
    "status": "confirmed"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "egid": "1234567890",
            "status": "confirmed",
            "building": {
                "egid": "1234567890",
                "gbez": "Schulhaus Muster",
                "ggdenr": "261",
                "ggdename": "Zürich",
                "egrid": "2680000.0,1240000.0"
            },
            "address": {
                "street": "Hauptstrasse 45",
                "postal_code": "6260",
                "city": "Reiden"
            },
            "solar_roofs": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "high"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "solar_facades": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "medium"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "coordinates": {
                "east": 2680000,
                "north": 1240000
            },
            "coordinates_wgs84": {
                "lat": 47.3769,
                "lng": 8.5417
            },
            "created_at": "2025-01-01T00:00:00+00:00",
            "updated_at": "2025-01-01T00:00:00+00:00"
        }
    ]
}
 

Request      

GET api/educational-institutions

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   integer  optional    

Filter by municipality BFS number (Gemeindenummer). Example: 261

postal_code   integer  optional    

Filter by postal code (PLZ). Example: 8001

status   string  optional    

Filter by status. Options: candidate, confirmed. Example: confirmed

lat   number  optional    

Latitude (WGS84) for radius search. Required together with lng and radius. Example: 47.3769

lng   number  optional    

Longitude (WGS84) for radius search. Required together with lat and radius. Example: 8.5417

radius   number  optional    

Search radius in meters (WGS84). Required together with lat and lng. Min: 1, Max: 50000. Example: 1000

east   number  optional    

Easting (CH1903+) for radius search. Required together with north and radius. Example: 2680000

north   number  optional    

Northing (CH1903+) for radius search. Required together with east and radius. Example: 1240000

Body Parameters

municipality   number  optional    

Example: 4326.41688

postal_code   number  optional    

Example: 4326.41688

lat   number  optional    

This field is required when lng or radius is present. Must be between -90 and 90. Example: -90

lng   number  optional    

This field is required when lat or radius is present. Must be between -180 and 180. Example: -180

east   number  optional    

This field is required when north or radius is present. Example: 4326.41688

north   number  optional    

This field is required when east or radius is present. Example: 4326.41688

radius   number  optional    

Must be at least 1. Must not be greater than 50000. Example: 17

status   string  optional    

Example: confirmed

Must be one of:
  • candidate
  • confirmed

Municipal Properties

List municipal properties

requires authentication

Returns a list of municipal properties (Werkhöfe, Gemeindeverwaltung, Gemeindehaus, Feuerwehrmagazin, etc.) with various filtering options. You can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates. Coordinates are taken directly from gwr_buildings.GKODE (Easting) and gwr_buildings.GKODN (Northing).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/municipal-properties?municipality=261&postal_code=8001&status=confirmed&lat=47.3769&lng=8.5417&radius=1000&east=2680000&north=1240000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"postal_code\": 4326.41688,
    \"lat\": -90,
    \"lng\": -180,
    \"east\": 4326.41688,
    \"north\": 4326.41688,
    \"radius\": 17,
    \"status\": \"candidate\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/municipal-properties"
);

const params = {
    "municipality": "261",
    "postal_code": "8001",
    "status": "confirmed",
    "lat": "47.3769",
    "lng": "8.5417",
    "radius": "1000",
    "east": "2680000",
    "north": "1240000",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "postal_code": 4326.41688,
    "lat": -90,
    "lng": -180,
    "east": 4326.41688,
    "north": 4326.41688,
    "radius": 17,
    "status": "candidate"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "egid": "1234567890",
            "status": "confirmed",
            "building": {
                "egid": "1234567890",
                "gbez": "Gemeindehaus",
                "ggdenr": "261",
                "ggdename": "Zürich",
                "egrid": "2680000.0,1240000.0"
            },
            "address": {
                "street": "Hauptstrasse 45",
                "postal_code": "6260",
                "city": "Reiden"
            },
            "solar_roofs": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "high"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "solar_facades": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "medium"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "coordinates": {
                "east": 2680000,
                "north": 1240000
            },
            "coordinates_wgs84": {
                "lat": 47.3769,
                "lng": 8.5417
            },
            "created_at": "2025-01-01T00:00:00+00:00",
            "updated_at": "2025-01-01T00:00:00+00:00"
        }
    ]
}
 

Request      

GET api/municipal-properties

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   integer  optional    

Filter by municipality BFS number (Gemeindenummer). Example: 261

postal_code   integer  optional    

Filter by postal code (PLZ). Example: 8001

status   string  optional    

Filter by status. Options: candidate, confirmed. Example: confirmed

lat   number  optional    

Latitude (WGS84) for radius search. Required together with lng and radius. Example: 47.3769

lng   number  optional    

Longitude (WGS84) for radius search. Required together with lat and radius. Example: 8.5417

radius   number  optional    

Search radius in meters (WGS84). Required together with lat and lng. Min: 1, Max: 50000. Example: 1000

east   number  optional    

Easting (CH1903+) for radius search. Required together with north and radius. Example: 2680000

north   number  optional    

Northing (CH1903+) for radius search. Required together with east and radius. Example: 1240000

Body Parameters

municipality   number  optional    

Example: 4326.41688

postal_code   number  optional    

Example: 4326.41688

lat   number  optional    

This field is required when lng or radius is present. Must be between -90 and 90. Example: -90

lng   number  optional    

This field is required when lat or radius is present. Must be between -180 and 180. Example: -180

east   number  optional    

This field is required when north or radius is present. Example: 4326.41688

north   number  optional    

This field is required when east or radius is present. Example: 4326.41688

radius   number  optional    

Must be at least 1. Must not be greater than 50000. Example: 17

status   string  optional    

Example: candidate

Must be one of:
  • candidate
  • confirmed

Water Supply Buildings

List water supply buildings

requires authentication

Returns a list of water supply buildings (Wasserversorgung) with various filtering options. You can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates. Coordinates are taken directly from gwr_buildings.GKODE (Easting) and gwr_buildings.GKODN (Northing).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/water-supply-buildings?municipality=261&postal_code=8001&status=confirmed&lat=47.3769&lng=8.5417&radius=1000&east=2680000&north=1240000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"municipality\": 4326.41688,
    \"postal_code\": 4326.41688,
    \"lat\": -90,
    \"lng\": -180,
    \"east\": 4326.41688,
    \"north\": 4326.41688,
    \"radius\": 17,
    \"status\": \"confirmed\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/water-supply-buildings"
);

const params = {
    "municipality": "261",
    "postal_code": "8001",
    "status": "confirmed",
    "lat": "47.3769",
    "lng": "8.5417",
    "radius": "1000",
    "east": "2680000",
    "north": "1240000",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "municipality": 4326.41688,
    "postal_code": 4326.41688,
    "lat": -90,
    "lng": -180,
    "east": 4326.41688,
    "north": 4326.41688,
    "radius": 17,
    "status": "confirmed"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "egid": "1234567890",
            "status": "confirmed",
            "building": {
                "egid": "1234567890",
                "gbez": "Wasserwerk",
                "ggdenr": "261",
                "ggdename": "Zürich",
                "egrid": "2680000.0,1240000.0"
            },
            "address": {
                "street": "Hauptstrasse 45",
                "postal_code": "6260",
                "city": "Reiden"
            },
            "solar_roofs": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "high"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "solar_facades": [
                {
                    "attributes": {
                        "building_id": "229760",
                        "suitability": "medium"
                    },
                    "geometry": {
                        "rings": [
                            [
                                [
                                    2640325.75,
                                    1232914.625
                                ]
                            ]
                        ]
                    }
                }
            ],
            "coordinates": {
                "east": 2680000,
                "north": 1240000
            },
            "coordinates_wgs84": {
                "lat": 47.3769,
                "lng": 8.5417
            },
            "created_at": "2025-01-01T00:00:00+00:00",
            "updated_at": "2025-01-01T00:00:00+00:00"
        }
    ]
}
 

Request      

GET api/water-supply-buildings

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

municipality   integer  optional    

Filter by municipality BFS number (Gemeindenummer). Example: 261

postal_code   integer  optional    

Filter by postal code (PLZ). Example: 8001

status   string  optional    

Filter by status. Options: candidate, confirmed. Example: confirmed

lat   number  optional    

Latitude (WGS84) for radius search. Required together with lng and radius. Example: 47.3769

lng   number  optional    

Longitude (WGS84) for radius search. Required together with lat and radius. Example: 8.5417

radius   number  optional    

Search radius in meters (WGS84). Required together with lat and lng. Min: 1, Max: 50000. Example: 1000

east   number  optional    

Easting (CH1903+) for radius search. Required together with north and radius. Example: 2680000

north   number  optional    

Northing (CH1903+) for radius search. Required together with east and radius. Example: 1240000

Body Parameters

municipality   number  optional    

Example: 4326.41688

postal_code   number  optional    

Example: 4326.41688

lat   number  optional    

This field is required when lng or radius is present. Must be between -90 and 90. Example: -90

lng   number  optional    

This field is required when lat or radius is present. Must be between -180 and 180. Example: -180

east   number  optional    

This field is required when north or radius is present. Example: 4326.41688

north   number  optional    

This field is required when east or radius is present. Example: 4326.41688

radius   number  optional    

Must be at least 1. Must not be greater than 50000. Example: 17

status   string  optional    

Example: confirmed

Must be one of:
  • candidate
  • confirmed

EIC Codes

List EIC codes

requires authentication

Returns a paginated list of Energy Identification Codes (EIC) published by Swissgrid (Swiss EIC Issuing Office, code 12). Covers all code types: A (substation), T (tieline), V (location), W (resource object), X (party / energy community), Y (area), Z (metering point).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/eic-codes?type=X&source_list=x-codes-energycommunity&function=LEG&search=Musterhausen&zip=3011&include_removed=&per_page=100" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"type\": \"w\",
    \"source_list\": \"z-codes\",
    \"function\": \"b\",
    \"search\": \"n\",
    \"zip\": \"gzmiyvdljnikhway\",
    \"include_removed\": false,
    \"per_page\": 18
}"
const url = new URL(
    "https://gwr-datahub.test/api/eic-codes"
);

const params = {
    "type": "X",
    "source_list": "x-codes-energycommunity",
    "function": "LEG",
    "search": "Musterhausen",
    "zip": "3011",
    "include_removed": "0",
    "per_page": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": "w",
    "source_list": "z-codes",
    "function": "b",
    "search": "n",
    "zip": "gzmiyvdljnikhway",
    "include_removed": false,
    "per_page": 18
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "eic": "12X-0000002029-F",
            "code_type": "X",
            "source_list": "x-codes-energycommunity",
            "display_name": "ENERGO-CO",
            "functions": [
                "Consumer"
            ],
            "company": "energo",
            "zip": "6331",
            "city": "Hünenberg",
            "registered_at": "2019-06-27",
            "media": null,
            "comment": null,
            "is_active": true,
            "removed_at": null,
            "first_seen_at": "2026-07-14T03:30:00+02:00",
            "last_seen_at": "2026-07-14T03:30:00+02:00"
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": "..."
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 4,
        "per_page": 100,
        "to": 100,
        "total": 385
    }
}
 

Request      

GET api/eic-codes

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

type   string  optional    

Filter by code type. Options: A, T, V, W, X, Y, Z. Example: X

source_list   string  optional    

Filter by Swissgrid source list. Options: a-codes, t-codes, v-codes, w-codes, x-codes, x-codes-energycommunity, y-codes, z-codes. Example: x-codes-energycommunity

function   string  optional    

Filter by function (exact match, e.g. LEG, vZEV, ZEV, Consumer). Example: LEG

search   string  optional    

Search in EIC, display name, company and city. Example: Musterhausen

zip   string  optional    

Filter by ZIP code. Example: 3011

include_removed   boolean  optional    

Include codes no longer present in the current Swissgrid list. Default: false. Example: false

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 100. Example: 100

Body Parameters

type   string  optional    

Example: w

Must be one of:
  • A
  • T
  • V
  • W
  • X
  • Y
  • Z
  • a
  • t
  • v
  • w
  • x
  • y
  • z
source_list   string  optional    

Example: z-codes

Must be one of:
  • a-codes
  • t-codes
  • v-codes
  • w-codes
  • x-codes
  • x-codes-energycommunity
  • y-codes
  • z-codes
function   string  optional    

Must not be greater than 100 characters. Example: b

search   string  optional    

Must not be greater than 100 characters. Example: n

zip   string  optional    

Must not be greater than 16 characters. Example: gzmiyvdljnikhway

include_removed   boolean  optional    

Example: false

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 18

Get sync metadata

requires authentication

Returns the available code types with counts and the last successful synchronisation per Swissgrid source list.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/eic-codes/meta" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/eic-codes/meta"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "types": [
        {
            "code_type": "X",
            "total": 2100,
            "active": 2050
        }
    ],
    "lists": [
        {
            "source_list": "x-codes-energycommunity",
            "code_type": "X",
            "last_synced_at": "2026-07-14T03:30:12+02:00",
            "rows_total": 384
        }
    ]
}
 

Request      

GET api/eic-codes/meta

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Get a single EIC code

requires authentication

Returns a single Energy Identification Code by its EIC identifier.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/eic-codes/12X-0000002029-F" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/eic-codes/12X-0000002029-F"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "eic": "12X-0000002029-F",
    "code_type": "X",
    "source_list": "x-codes-energycommunity",
    "display_name": "ENERGO-CO",
    "functions": [
        "Consumer"
    ],
    "company": "energo",
    "zip": "6331",
    "city": "Hünenberg",
    "registered_at": "2019-06-27",
    "media": null,
    "comment": null,
    "is_active": true,
    "removed_at": null,
    "first_seen_at": "2026-07-14T03:30:00+02:00",
    "last_seen_at": "2026-07-14T03:30:00+02:00"
}
 

Example response (404):


{
    "message": "EIC-Code nicht gefunden."
}
 

Request      

GET api/eic-codes/{eic}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

eic   string     

The EIC identifier. Example: 12X-0000002029-F

Endpoints

GET api/user

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/user" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/user"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/user

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

GET api/health

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/health" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/health"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 600
x-ratelimit-remaining: 599
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "status": "ok",
    "time": "2026-07-14T02:24:19+00:00"
}
 

Request      

GET api/health

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

GET api/buildings/{egid}/consumption

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/architecto/consumption" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/architecto/consumption"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/consumption

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Example: architecto

POST api/buildings/{egid}/consumption

requires authentication

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/buildings/architecto/consumption" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"heating_system\": \"non_electric\",
    \"hot_water_system\": \"from_heating\",
    \"age_tier\": \"mid\",
    \"effective_area\": 1
}"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/architecto/consumption"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "heating_system": "non_electric",
    "hot_water_system": "from_heating",
    "age_tier": "mid",
    "effective_area": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/buildings/{egid}/consumption

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Example: architecto

Body Parameters

heating_system   string  optional    

Example: non_electric

Must be one of:
  • luft_wp
  • sole_wp
  • direct_electric
  • non_electric
hot_water_system   string  optional    

Example: from_heating

Must be one of:
  • luft_wp
  • sole_wp
  • direct_electric
  • from_heating
  • other
age_tier   string  optional    

Example: mid

Must be one of:
  • old
  • mid
  • new
effective_area   number  optional    

Must be at least 10. Must not be greater than 50000. Example: 1

GET api/network-topology/coverage-data

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/coverage-data" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"view_mode\": \"ne6\",
    \"vk_id\": 16,
    \"ne6_id\": 16,
    \"bfs_number\": 4326.41688,
    \"show_ne4\": false,
    \"show_ne6\": false,
    \"show_vk\": false,
    \"show_buildings\": true,
    \"building_limit\": 17,
    \"include_epa\": true
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/coverage-data"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "view_mode": "ne6",
    "vk_id": 16,
    "ne6_id": 16,
    "bfs_number": 4326.41688,
    "show_ne4": false,
    "show_ne6": false,
    "show_vk": false,
    "show_buildings": true,
    "building_limit": 17,
    "include_epa": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/coverage-data

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

view_mode   string     

Example: ne6

Must be one of:
  • vk
  • ne6
  • municipality
vk_id   integer  optional    

Must match an existing stored value. Example: 16

ne6_id   integer  optional    

Must match an existing stored value. Example: 16

bfs_number   number  optional    

Example: 4326.41688

show_ne4   boolean  optional    

Example: false

show_ne6   boolean  optional    

Example: false

show_vk   boolean  optional    

Example: false

show_buildings   boolean  optional    

Example: true

building_limit   integer  optional    

Must be at least 10. Must not be greater than 5000. Example: 17

include_epa   boolean  optional    

Example: true

GET api/network-topology/data-version

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/data-version" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/data-version"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/data-version

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create a new node (NE4, NE6 or VK).

requires authentication

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/network-topology/nodes" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"node_type\": \"vk\",
    \"identifier\": \"b\",
    \"parent_node_id\": 16,
    \"grid_operator_id\": 16,
    \"latitude\": -89,
    \"longitude\": -180,
    \"address\": \"z\",
    \"trafo_egid\": \"m\",
    \"is_active\": false,
    \"metadata\": {
        \"custom_label\": \"i\",
        \"bfs_number\": 8,
        \"network_level\": \"v\",
        \"capacity_kva\": 42,
        \"egrid\": \"l\"
    }
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/nodes"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "node_type": "vk",
    "identifier": "b",
    "parent_node_id": 16,
    "grid_operator_id": 16,
    "latitude": -89,
    "longitude": -180,
    "address": "z",
    "trafo_egid": "m",
    "is_active": false,
    "metadata": {
        "custom_label": "i",
        "bfs_number": 8,
        "network_level": "v",
        "capacity_kva": 42,
        "egrid": "l"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/network-topology/nodes

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

node_type   string     

Example: vk

Must be one of:
  • ne4
  • ne6
  • vk
identifier   string     

Must not be greater than 255 characters. Example: b

parent_node_id   integer  optional    

Must match an existing stored value. Example: 16

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

latitude   number  optional    

Must be between -90 and 90. Example: -89

longitude   number  optional    

Must be between -180 and 180. Example: -180

address   string  optional    

Must not be greater than 255 characters. Example: z

trafo_egid   string  optional    

Must not be greater than 32 characters. Example: m

is_active   boolean  optional    

Example: false

metadata   object  optional    
custom_label   string  optional    

Must not be greater than 255 characters. Example: i

bfs_number   integer  optional    

Must be at least 1. Must not be greater than 9999. Example: 8

network_level   string  optional    

Must not be greater than 32 characters. Example: v

capacity_kva   number  optional    

Must be at least 0. Example: 42

egrid   string  optional    

Must not be greater than 32 characters. Example: l

Show a single node.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/nodes/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/nodes/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/nodes/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the node. Example: 564

Update an existing node (e.g. rename, change parent, edit label).

requires authentication

Example request:
curl --request PUT \
    "https://gwr-datahub.test/api/network-topology/nodes/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"node_type\": \"ne6\",
    \"identifier\": \"b\",
    \"parent_node_id\": 16,
    \"grid_operator_id\": 16,
    \"latitude\": -89,
    \"longitude\": -180,
    \"address\": \"z\",
    \"trafo_egid\": \"m\",
    \"is_active\": true,
    \"metadata\": {
        \"custom_label\": \"i\",
        \"bfs_number\": 8,
        \"network_level\": \"v\",
        \"capacity_kva\": 42,
        \"egrid\": \"l\"
    }
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/nodes/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "node_type": "ne6",
    "identifier": "b",
    "parent_node_id": 16,
    "grid_operator_id": 16,
    "latitude": -89,
    "longitude": -180,
    "address": "z",
    "trafo_egid": "m",
    "is_active": true,
    "metadata": {
        "custom_label": "i",
        "bfs_number": 8,
        "network_level": "v",
        "capacity_kva": 42,
        "egrid": "l"
    }
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/network-topology/nodes/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the node. Example: 564

Body Parameters

node_type   string  optional    

Example: ne6

Must be one of:
  • ne4
  • ne6
  • vk
identifier   string  optional    

Must not be greater than 255 characters. Example: b

parent_node_id   integer  optional    

Must match an existing stored value. Example: 16

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

latitude   number  optional    

Must be between -90 and 90. Example: -89

longitude   number  optional    

Must be between -180 and 180. Example: -180

address   string  optional    

Must not be greater than 255 characters. Example: z

trafo_egid   string  optional    

Must not be greater than 32 characters. Example: m

is_active   boolean  optional    

Example: true

metadata   object  optional    
custom_label   string  optional    

Must not be greater than 255 characters. Example: i

bfs_number   integer  optional    

Must be at least 1. Must not be greater than 9999. Example: 8

network_level   string  optional    

Must not be greater than 32 characters. Example: v

capacity_kva   number  optional    

Must be at least 0. Example: 42

egrid   string  optional    

Must not be greater than 32 characters. Example: l

Delete a node. Refuses if the node still has children or topology references.

requires authentication

Example request:
curl --request DELETE \
    "https://gwr-datahub.test/api/network-topology/nodes/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/nodes/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/network-topology/nodes/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the node. Example: 564

Create an EGID -> node assignment. Fails if a row for the EGID already exists; use PUT in that case.

requires authentication

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/network-topology/assignments" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"egid\": \"b\",
    \"ne4_node_id\": 16,
    \"ne6_node_id\": 16,
    \"vk_node_id\": 16,
    \"grid_operator_id\": 16,
    \"is_muffennetz\": false,
    \"autopopulate_parents\": false
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/assignments"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "egid": "b",
    "ne4_node_id": 16,
    "ne6_node_id": 16,
    "vk_node_id": 16,
    "grid_operator_id": 16,
    "is_muffennetz": false,
    "autopopulate_parents": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/network-topology/assignments

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

egid   string     

Must match an existing stored value. Must not be greater than 32 characters. Example: b

ne4_node_id   integer  optional    

Must match an existing stored value. Example: 16

ne6_node_id   integer  optional    

Must match an existing stored value. Example: 16

vk_node_id   integer  optional    

Must match an existing stored value. Example: 16

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

is_muffennetz   boolean  optional    

Example: false

autopopulate_parents   boolean  optional    

Example: false

GET api/network-topology/assignments/{id}

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/assignments/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/assignments/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/assignments/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the assignment. Example: 564

Update an existing assignment (move a building to another transformer, etc.).

requires authentication

Example request:
curl --request PUT \
    "https://gwr-datahub.test/api/network-topology/assignments/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"ne4_node_id\": 16,
    \"ne6_node_id\": 16,
    \"vk_node_id\": 16,
    \"grid_operator_id\": 16,
    \"is_muffennetz\": false,
    \"autopopulate_parents\": false
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/assignments/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ne4_node_id": 16,
    "ne6_node_id": 16,
    "vk_node_id": 16,
    "grid_operator_id": 16,
    "is_muffennetz": false,
    "autopopulate_parents": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/network-topology/assignments/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the assignment. Example: 564

Body Parameters

ne4_node_id   integer  optional    

Must match an existing stored value. Example: 16

ne6_node_id   integer  optional    

Must match an existing stored value. Example: 16

vk_node_id   integer  optional    

Must match an existing stored value. Example: 16

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

is_muffennetz   boolean  optional    

Example: false

autopopulate_parents   boolean  optional    

Example: false

DELETE api/network-topology/assignments/{id}

requires authentication

Example request:
curl --request DELETE \
    "https://gwr-datahub.test/api/network-topology/assignments/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/assignments/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/network-topology/assignments/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   string     

The ID of the assignment. Example: 564

Proxy all requests to OSB API.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/osb/|{+-0p" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/osb/|{+-0p"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/osb/{path?}

POST api/osb/{path?}

PUT api/osb/{path?}

PATCH api/osb/{path?}

DELETE api/osb/{path?}

OPTIONS api/osb/{path?}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

path   string  optional    

Example: |{+-0p

Proxy all requests to OSB API.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/osb-v2/|{+-0p" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/osb-v2/|{+-0p"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/osb-v2/{path?}

POST api/osb-v2/{path?}

PUT api/osb-v2/{path?}

PATCH api/osb-v2/{path?}

DELETE api/osb-v2/{path?}

OPTIONS api/osb-v2/{path?}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

path   string  optional    

Example: |{+-0p

BFE Stromkennzeichnung

Endpoints for the Swiss Lieferantenmix (electricity-label) data published yearly by Pronovo / BFE.

List operators with their latest electricity label.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/operators" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/operators"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/operators

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Show all years of labels for a single operator (resolved via ch_uid).

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/operators/architecto" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/operators/architecto"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/operators/{chUid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Example: architecto

One label (Lieferantenmix) for an operator + delivery year.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/operators/architecto/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/operators/architecto/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/operators/{chUid}/{year}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Example: architecto

year   string     

Example: 564

Single product mix for an operator/year/product (phase 2 placeholder).

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/operators/architecto/564/products/architecto" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/operators/architecto/564/products/architecto"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/operators/{chUid}/{year}/products/{product}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Example: architecto

year   string     

Example: 564

product   string     

The product. Example: architecto

Look up the label for the building's default supplier (= VNB).

requires authentication

Resolves EGID -> NetworkTopology -> grid_operator_id -> latest label. Returns a disclaimer that this is the default supplier; customers with free choice (> 100 MWh/year) may use a different supplier.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/by-egid/architecto" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/by-egid/architecto"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/by-egid/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Example: architecto

Aggregate by municipality (BFS number) - returns labels for all suppliers whose service area touches this municipality (resolved via network_topology).

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/by-municipality/564" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/by-municipality/564"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/by-municipality/{bfsNumber}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfsNumber   string     

Example: 564

Weighted CH-wide or filtered aggregate.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-labels/aggregate" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-labels/aggregate"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-labels/aggregate

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Economic Catalog

List catalog products.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/economic-catalog/products?supplier=solarmarkt&kind=battery_module&manufacturer=BYD&search=HVS&min_kwh=5&max_kwh=20&include_discontinued=&per_page=200&page=1&lang=de" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"supplier\": \"bng-zmi_y\",
    \"kind\": \"dummy\",
    \"manufacturer\": \"v\",
    \"search\": \"d\",
    \"min_kwh\": 37,
    \"max_kwh\": 9,
    \"include_discontinued\": true,
    \"per_page\": 17,
    \"lang\": \"de\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/economic-catalog/products"
);

const params = {
    "supplier": "solarmarkt",
    "kind": "battery_module",
    "manufacturer": "BYD",
    "search": "HVS",
    "min_kwh": "5",
    "max_kwh": "20",
    "include_discontinued": "0",
    "per_page": "200",
    "page": "1",
    "lang": "de",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "supplier": "bng-zmi_y",
    "kind": "dummy",
    "manufacturer": "v",
    "search": "d",
    "min_kwh": 37,
    "max_kwh": 9,
    "include_discontinued": true,
    "per_page": 17,
    "lang": "de"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/economic-catalog/products

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

supplier   string  optional    

Filter by supplier slug. Example: solarmarkt

kind   string  optional    

Filter by battery kind. Options: battery_module, bcu, inverter, accessory, dummy, unknown. Example: battery_module

manufacturer   string  optional    

Filter by manufacturer name (exact match). Example: BYD

search   string  optional    

Search name or article number (LIKE). Example: HVS

min_kwh   number  optional    

Minimum total kWh. Example: 5

max_kwh   number  optional    

Maximum total kWh. Must be >= min_kwh. Example: 20

include_discontinued   boolean  optional    

Include discontinued products. Default: false. Example: false

per_page   integer  optional    

Number of items per page. Min: 1, Max: 1000. Default: 200. Example: 200

page   integer  optional    

Page number. Default: 1. Example: 1

lang   string  optional    

Language for code labels. Options: de, fr, it. Default: de. Example: de

Body Parameters

supplier   string  optional    

Must contain only letters, numbers, dashes and underscores. Example: bng-zmi_y

kind   string  optional    

Example: dummy

Must be one of:
  • battery_module
  • bcu
  • inverter
  • accessory
  • dummy
  • unknown
manufacturer   string  optional    

Must not be greater than 120 characters. Example: v

search   string  optional    

Must not be greater than 120 characters. Example: d

min_kwh   number  optional    

Must be at least 0. Example: 37

max_kwh   number  optional    

Must be at least 0. Example: 9

include_discontinued   boolean  optional    

Example: true

per_page   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 17

lang   string  optional    

Example: de

Must be one of:
  • de
  • fr
  • it

Show a single catalog product with its full snapshot history.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/economic-catalog/products/16?lang=de" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"lang\": \"fr\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/economic-catalog/products/16"
);

const params = {
    "lang": "de",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "lang": "fr"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/economic-catalog/products/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product. Example: 16

product   string     

integer The product ID. Example: 42

Query Parameters

lang   string  optional    

Language for code labels. Options: de, fr, it. Default: de. Example: de

Body Parameters

lang   string  optional    

Example: fr

Must be one of:
  • de
  • fr
  • it

List distinct manufacturers, optionally scoped by supplier.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/economic-catalog/manufacturers?supplier=solarmarkt&lang=de" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/economic-catalog/manufacturers"
);

const params = {
    "supplier": "solarmarkt",
    "lang": "de",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/economic-catalog/manufacturers

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

supplier   string  optional    

Filter by supplier slug. Example: solarmarkt

lang   string  optional    

Language. Default: de. Example: de

List catalog suppliers.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/economic-catalog/suppliers?lang=de" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/economic-catalog/suppliers"
);

const params = {
    "lang": "de",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/economic-catalog/suppliers

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

lang   string  optional    

Language. Default: de. Example: de

Electricity Production Plants

Get combined building and electricity production plants data

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/123456/electricity-plants?plant_type=photovoltaic" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/electricity-plants"
);

const params = {
    "plant_type": "photovoltaic",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/electricity-plants

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string  optional    

Building EGID. Example: 123456

Query Parameters

plant_type   string  optional    

Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.). Example: photovoltaic

Get electricity production plants for a building by EGID

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-plants?egid=123456&plant_type=photovoltaic" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-plants"
);

const params = {
    "egid": "123456",
    "plant_type": "photovoltaic",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-plants

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

egid   string  optional    

Building EGID. Example: 123456

plant_type   string  optional    

Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.). Example: photovoltaic

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-plants/search?municipality=Z%C3%BCrich&post_code=8001&bfs_number=261&plant_type=photovoltaic" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-plants/search"
);

const params = {
    "municipality": "Zürich",
    "post_code": "8001",
    "bfs_number": "261",
    "plant_type": "photovoltaic",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

List all electricity production plants of a municipality with coordinates.

requires authentication

Designed for map rendering: returns every plant of a municipality together with CH1903+ and WGS84 coordinates (reconstructed from gwr_buildings via EGID when the BFE source is incomplete).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-plants/by-municipality?bfs_number=2827&plant_type=photovoltaic&only_with_coordinates=1&min_power_kw=0" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-plants/by-municipality"
);

const params = {
    "bfs_number": "2827",
    "plant_type": "photovoltaic",
    "only_with_coordinates": "1",
    "min_power_kw": "0",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-plants/by-municipality

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

bfs_number   string  optional    

Municipality BFS number. Required. Example: 2827

plant_type   string  optional    

Optional filter by plant type (photovoltaic, hydro, wind, biomass). Example: photovoltaic

only_with_coordinates   boolean  optional    

If true (default) only plants with WGS84 coordinates are returned. Example: true

min_power_kw   number  optional    

Optional minimum total power in kW. Example: 0

Get specific electricity production plant by XTF-ID

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/electricity-plants/ch.bfe.epa.123456" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/electricity-plants/ch.bfe.epa.123456"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/electricity-plants/{xtf_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

xtf_id   string  optional    

XTF-ID of the plant. Example: ch.bfe.epa.123456

Get electricity production plant statistics for a municipality

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/municipalities/261/electricity-plant-statistics?plant_type=photovoltaic" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/municipalities/261/electricity-plant-statistics"
);

const params = {
    "plant_type": "photovoltaic",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/municipalities/{bfs_number}/electricity-plant-statistics

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfs_number   string  optional    

BFS municipality number. Example: 261

Query Parameters

plant_type   string  optional    

Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.). Example: photovoltaic

HKN Compensation Rates

List HKN compensation rates for a grid operator

requires authentication

Returns the manually maintained HKN compensation rates for a single grid operator, filtered by validity period (default: rates valid today). Use include_history=true to retrieve all historical entries.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688?valid_at=2026-01-01&energy_source=photovoltaik&plant_size=up_to_30_kva&include_history=" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"valid_at\": \"2026-07-14T02:24:19\",
    \"energy_source\": \"wind\",
    \"plant_size\": \"alle\",
    \"include_history\": true
}"
const url = new URL(
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688"
);

const params = {
    "valid_at": "2026-01-01",
    "energy_source": "photovoltaik",
    "plant_size": "up_to_30_kva",
    "include_history": "0",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "valid_at": "2026-07-14T02:24:19",
    "energy_source": "wind",
    "plant_size": "alle",
    "include_history": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/hkn-rates/operators/{chUid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Swiss UID of the grid operator. Example: CHE-108.954.688

Query Parameters

valid_at   string  optional    

date Filter rates valid on this date (ISO 8601). Default: today. Example: 2026-01-01

energy_source   string  optional    

Filter by energy source. Options: photovoltaik, wasserkraft, wind, biomasse, bhkw, sonstige. Example: photovoltaik

plant_size   string  optional    

Filter by plant size class. Options: alle, up_to_30_kva, from_30_to_100_kva, from_100_to_1000_kva, above_1000_kva. Example: up_to_30_kva

include_history   boolean  optional    

If true, returns all rates regardless of validity. Default: false. Example: false

Body Parameters

valid_at   string  optional    

Must be a valid date. Example: 2026-07-14T02:24:19

energy_source   string  optional    

Example: wind

Must be one of:
  • photovoltaik
  • wasserkraft
  • wind
  • biomasse
  • bhkw
  • sonstige
plant_size   string  optional    

Example: alle

Must be one of:
  • alle
  • up_to_30_kva
  • from_30_to_100_kva
  • from_100_to_1000_kva
  • above_1000_kva
include_history   boolean  optional    

Example: true

Create an HKN compensation rate for a grid operator

requires authentication

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"energy_source\": \"photovoltaik\",
    \"plant_size\": \"up_to_30_kva\",
    \"rate_rappen_per_kwh\": 4.5,
    \"valid_from\": \"2026-01-01\",
    \"valid_to\": \"2026-12-31\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "energy_source": "photovoltaik",
    "plant_size": "up_to_30_kva",
    "rate_rappen_per_kwh": 4.5,
    "valid_from": "2026-01-01",
    "valid_to": "2026-12-31"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/hkn-rates/operators/{chUid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Swiss UID of the grid operator. Example: CHE-108.954.688

Body Parameters

energy_source   string     

Energy source. Options: photovoltaik, wasserkraft, wind, biomasse, bhkw, sonstige. Example: photovoltaik

plant_size   string     

Plant size class. Options: alle, up_to_30_kva, from_30_to_100_kva, from_100_to_1000_kva, above_1000_kva. Example: up_to_30_kva

rate_rappen_per_kwh   number     

Compensation in Rp/kWh. Example: 4.5

valid_from   date     

Start of validity (ISO 8601). Example: 2026-01-01

valid_to   date  optional    

End of validity, null = open-ended. Example: 2026-12-31

Update an HKN compensation rate

requires authentication

Example request:
curl --request PUT \
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688/rates/1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"energy_source\": \"biomasse\",
    \"plant_size\": \"up_to_30_kva\",
    \"rate_rappen_per_kwh\": 1,
    \"valid_from\": \"2026-07-14T02:24:19\",
    \"valid_to\": \"2026-07-14T02:24:19\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688/rates/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "energy_source": "biomasse",
    "plant_size": "up_to_30_kva",
    "rate_rappen_per_kwh": 1,
    "valid_from": "2026-07-14T02:24:19",
    "valid_to": "2026-07-14T02:24:19"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/hkn-rates/operators/{chUid}/rates/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Swiss UID of the grid operator. Example: CHE-108.954.688

id   integer     

ID of the HKN rate. Example: 1

Body Parameters

energy_source   string  optional    

Example: biomasse

Must be one of:
  • photovoltaik
  • wasserkraft
  • wind
  • biomasse
  • bhkw
  • sonstige
plant_size   string  optional    

Example: up_to_30_kva

Must be one of:
  • alle
  • up_to_30_kva
  • from_30_to_100_kva
  • from_100_to_1000_kva
  • above_1000_kva
rate_rappen_per_kwh   number  optional    

Must be at least 0. Must not be greater than 9999.9999. Example: 1

valid_from   string  optional    

Must be a valid date. Example: 2026-07-14T02:24:19

valid_to   string  optional    

Must be a valid date. Example: 2026-07-14T02:24:19

Delete an HKN compensation rate

requires authentication

Example request:
curl --request DELETE \
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688/rates/1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/hkn-rates/operators/CHE-108.954.688/rates/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/hkn-rates/operators/{chUid}/rates/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

chUid   string     

Swiss UID of the grid operator. Example: CHE-108.954.688

id   integer     

ID of the HKN rate. Example: 1

Municipality Enrichment

Enrich all buildings in a municipality.

requires authentication

Triggers a background job that enriches building data including:

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/municipalities/261/enrich" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"force\": false
}"
const url = new URL(
    "https://gwr-datahub.test/api/municipalities/261/enrich"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "force": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/municipalities/{bfs_number}/enrich

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfs_number   integer     

Municipality BFS number. Example: 261

Body Parameters

force   boolean  optional    

Force re-enrichment even if already enriched. Default: false. Example: false

Get the status of a municipality enrichment batch.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/municipalities/261/enrichment-status/9d4f8a3c-1b2e-4f5a-8c3d-9a7b6e4f2c1d" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/municipalities/261/enrichment-status/9d4f8a3c-1b2e-4f5a-8c3d-9a7b6e4f2c1d"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/municipalities/{bfs_number}/enrichment-status/{batch_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfs_number   integer     

Municipality BFS number. Example: 261

batch_id   string     

Batch ID from enrich response. Example: 9d4f8a3c-1b2e-4f5a-8c3d-9a7b6e4f2c1d

Network Topology

Get network topology hierarchy for a municipality.

requires authentication

Returns the full NE4 → NE6 → VK hierarchy with optional building data. Designed for simulation seeder and external API consumers.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/hierarchy/4241?include=buildings&ne4_id=1&ne6_id=5&cursor=eyJlZ2lkIjoiMTIzNDU2In0%3D&limit=100" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"include\": \"buildings\",
    \"node_type\": \"ne6\",
    \"ne4_id\": 16,
    \"ne6_id\": 16,
    \"cursor\": \"architecto\",
    \"limit\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/hierarchy/4241"
);

const params = {
    "include": "buildings",
    "ne4_id": "1",
    "ne6_id": "5",
    "cursor": "eyJlZ2lkIjoiMTIzNDU2In0=",
    "limit": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "include": "buildings",
    "node_type": "ne6",
    "ne4_id": 16,
    "ne6_id": 16,
    "cursor": "architecto",
    "limit": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/hierarchy/{bfs_number}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfs_number   integer     

int The municipality BFS number. Example: 4241

Query Parameters

include   string  optional    

Include additional data. Currently only "buildings" is supported. Example: buildings

ne4_id   integer  optional    

Filter to a specific NE4 (substation) subtree. Example: 1

ne6_id   integer  optional    

Filter to a specific NE6 (transformer) subtree. Example: 5

cursor   string  optional    

Pagination cursor for buildings (base64 encoded). Example: eyJlZ2lkIjoiMTIzNDU2In0=

limit   integer  optional    

Number of buildings per page (1-500, default 100). Example: 100

Body Parameters

include   string  optional    

Example: buildings

Must be one of:
  • buildings
node_type   string  optional    

Example: ne6

Must be one of:
  • ne4
  • ne6
  • vk
ne4_id   integer  optional    

Must match an existing stored value. Example: 16

ne6_id   integer  optional    

Must match an existing stored value. Example: 16

cursor   string  optional    

Example: architecto

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 22

Generate a coverage map image (SVG).

requires authentication

Returns an SVG image of the network topology coverage map. Supports three view modes: VK-centered (vZEV), NE6-centered (LEG 40%), or municipality.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/coverage-map?view_mode=vk&vk_id=25&ne6_id=5&bfs_number=4241&width=1200&height=800&show_ne4=1&show_ne6=1&show_vk=1&show_buildings=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"view_mode\": \"municipality\",
    \"vk_id\": 16,
    \"ne6_id\": 16,
    \"bfs_number\": 4326.41688,
    \"width\": 17,
    \"height\": 15,
    \"show_ne4\": true,
    \"show_ne6\": true,
    \"show_vk\": false,
    \"show_buildings\": false
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/coverage-map"
);

const params = {
    "view_mode": "vk",
    "vk_id": "25",
    "ne6_id": "5",
    "bfs_number": "4241",
    "width": "1200",
    "height": "800",
    "show_ne4": "1",
    "show_ne6": "1",
    "show_vk": "1",
    "show_buildings": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "view_mode": "municipality",
    "vk_id": 16,
    "ne6_id": 16,
    "bfs_number": 4326.41688,
    "width": 17,
    "height": 15,
    "show_ne4": true,
    "show_ne6": true,
    "show_vk": false,
    "show_buildings": false
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


SVG image data
 

Example response (404):


{
    "message": "Node not found"
}
 

Request      

GET api/network-topology/coverage-map

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

view_mode   string     

string View mode: "vk", "ne6", or "municipality". Example: vk

vk_id   integer  optional    

Required when view_mode is "vk". The VK node ID. Example: 25

ne6_id   integer  optional    

Required when view_mode is "ne6". The NE6 node ID. Example: 5

bfs_number   integer  optional    

Required when view_mode is "municipality". The BFS number. Example: 4241

width   integer  optional    

Image width in pixels (400-4000, default 1200). Example: 1200

height   integer  optional    

Image height in pixels (300-3000, default 800). Example: 800

show_ne4   boolean  optional    

Show NE4 polygons (default true). Example: true

show_ne6   boolean  optional    

Show NE6 polygons (default true). Example: true

show_vk   boolean  optional    

Show VK polygons (default true). Example: true

show_buildings   boolean  optional    

Show building markers (default true). Example: true

Body Parameters

view_mode   string     

Example: municipality

Must be one of:
  • vk
  • ne6
  • municipality
vk_id   integer  optional    

Must match an existing stored value. Example: 16

ne6_id   integer  optional    

Must match an existing stored value. Example: 16

bfs_number   number  optional    

Example: 4326.41688

width   integer  optional    

Must be at least 400. Must not be greater than 4000. Example: 17

height   integer  optional    

Must be at least 300. Must not be greater than 3000. Example: 15

show_ne4   boolean  optional    

Example: true

show_ne6   boolean  optional    

Example: true

show_vk   boolean  optional    

Example: false

show_buildings   boolean  optional    

Example: false

Look up topology data for a building by EGID.

requires authentication

Returns grid level, transformer info, power data, and LEG eligibility. Supports hybrid caching: checks local DB first, fetches from external API on miss.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/lookup?egid=421158&vnb=ebl" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"egid\": \"bngzmiyvdljnikhw\",
    \"vnb\": \"a\"
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/lookup"
);

const params = {
    "egid": "421158",
    "vnb": "ebl",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "egid": "bngzmiyvdljnikhw",
    "vnb": "a"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/lookup

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

egid   string     

string The building EGID. Example: 421158

vnb   string  optional    

Optional VNB identifier (name or CH UID). Example: ebl

Body Parameters

egid   string     

Must not be greater than 20 characters. Example: bngzmiyvdljnikhw

vnb   string  optional    

Must not be greater than 100 characters. Example: a

Get all buildings connected to the same transformer as the given EGID.

requires authentication

Returns buildings eligible for LEG 40% (same Trafokreis, no transformation needed). Results are filtered to the same municipality and limited for performance.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/transformer-peers/421158?vnb=ebl&limit=16" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"vnb\": \"b\",
    \"limit\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/transformer-peers/421158"
);

const params = {
    "vnb": "ebl",
    "limit": "16",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "vnb": "b",
    "limit": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/transformer-peers/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

string The building EGID. Example: 421158

Query Parameters

vnb   string  optional    

Optional VNB identifier. Example: ebl

limit   integer  optional    

Max buildings to return (1-500, default 100). building_count remains the true total. Example: 16

Body Parameters

vnb   string  optional    

Must not be greater than 100 characters. Example: b

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 22

Get all buildings in the same LEG area as the given EGID.

requires authentication

Returns buildings eligible for LEG 20% (same substation area, with transformation). Results are filtered to the same municipality (Gemeinde-LEG scope) and limited.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/leg-area-peers/421158?vnb=ebl&limit=16" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"vnb\": \"b\",
    \"limit\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/leg-area-peers/421158"
);

const params = {
    "vnb": "ebl",
    "limit": "16",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "vnb": "b",
    "limit": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/leg-area-peers/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

string The building EGID. Example: 421158

Query Parameters

vnb   string  optional    

Optional VNB identifier. Example: ebl

limit   integer  optional    

Max buildings to return (1-500, default 100). building_count remains the true total. Example: 16

Body Parameters

vnb   string  optional    

Must not be greater than 100 characters. Example: b

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 22

Combined LEG-20 / LEG-40 / vZEV peer lookup for a single building.

requires authentication

Returns all three peer blocks in a single response so a client can scan a building with one HTTP roundtrip instead of three. The shape mirrors the individual endpoints; each block carries an explicit leg_type discriminator (leg_20 / leg_40 / vzev).

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/leg-peers/421158?vnb=ebl&limit=16" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"vnb\": \"b\",
    \"limit\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/leg-peers/421158"
);

const params = {
    "vnb": "ebl",
    "limit": "16",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "vnb": "b",
    "limit": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/leg-peers/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

string The building EGID. Example: 421158

Query Parameters

vnb   string  optional    

Optional VNB identifier. Example: ebl

limit   integer  optional    

Max buildings per block to return (1-500, default 100). Example: 16

Body Parameters

vnb   string  optional    

Must not be greater than 100 characters. Example: b

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 22

Look up vZEV peers for a building by EGID.

requires authentication

Returns buildings sharing the same distribution cabinet (Verteilkasten), eligible for a virtual ZEV. Uses Cubera API (mode=vzev) for Cubera-based VNBs or DB-cached VK node data for Stromgemeinschaft VNBs.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/vzev-lookup/421158?vnb=primeo&limit=16" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"vnb\": \"b\",
    \"limit\": 22
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/vzev-lookup/421158"
);

const params = {
    "vnb": "primeo",
    "limit": "16",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "vnb": "b",
    "limit": 22
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/vzev-lookup/{egid}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

string The building EGID. Example: 421158

Query Parameters

vnb   string  optional    

Optional VNB identifier. Example: primeo

limit   integer  optional    

Max peers to return (1-500, default 100). Example: 16

Body Parameters

vnb   string  optional    

Must not be greater than 100 characters. Example: b

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 22

Get aggregated Quartier-LEG groups (NE6) for a municipality.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/quarter-legs/by-municipality/2822?limit=100" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"limit\": 1
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/quarter-legs/by-municipality/2822"
);

const params = {
    "limit": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "limit": 1
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/quarter-legs/by-municipality/{bfs_number}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

bfs_number   integer     

int The municipality BFS number. Example: 2822

Query Parameters

limit   integer  optional    

Max groups to return (1-500, default 100). Example: 100

Body Parameters

limit   integer  optional    

Must be at least 1. Must not be greater than 500. Example: 1

Search address candidates for topology fallback flows.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/address-lookup?query=Hauptstrasse+12&bfs_number=2822&limit=10" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"query\": \"b\",
    \"bfs_number\": 22,
    \"limit\": 7
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/address-lookup"
);

const params = {
    "query": "Hauptstrasse 12",
    "bfs_number": "2822",
    "limit": "10",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "query": "b",
    "bfs_number": 22,
    "limit": 7
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/address-lookup

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

query   string     

string Search term (street, house number, zip, city, EGID). Example: Hauptstrasse 12

bfs_number   integer  optional    

Optional municipality BFS filter. Example: 2822

limit   integer  optional    

Max candidates to return (1-25, default 10). Example: 10

Body Parameters

query   string     

Must be at least 3 characters. Must not be greater than 255 characters. Example: b

bfs_number   integer  optional    

Must be at least 1. Must not be greater than 9999. Example: 22

limit   integer  optional    

Must be at least 1. Must not be greater than 25. Example: 7

Import legacy vZEV check records from the LEG App.

requires authentication

Bulk imports historical vzev_site_checks data into the GWR DataHub network_topology table. Used for one-time migration from LEG App.

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/network-topology/import-legacy-checks" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"records\": [
        {
            \"egid\": \"bngzmiyvdljnikhw\",
            \"status\": \"unknown\",
            \"provider\": \"a\",
            \"vk_identifier\": \"y\",
            \"trafo_identifier\": \"k\"
        }
    ]
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/import-legacy-checks"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "records": [
        {
            "egid": "bngzmiyvdljnikhw",
            "status": "unknown",
            "provider": "a",
            "vk_identifier": "y",
            "trafo_identifier": "k"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/network-topology/import-legacy-checks

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

records   object[]     

Must have at least 1 items.

egid   string     

Must not be greater than 20 characters. Example: bngzmiyvdljnikhw

status   string     

Example: unknown

Must be one of:
  • verteilkasten
  • trafo
  • muffennetz
  • unknown
provider   string     

Must not be greater than 50 characters. Example: a

vk_identifier   string  optional    

Must not be greater than 255 characters. Example: y

trafo_identifier   string  optional    

Must not be greater than 255 characters. Example: k

raw_response   object  optional    

List nodes, optionally filtered by grid operator, type and free-text search.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/nodes?grid_operator_id=12&node_type=ne6&bfs_number=4241&q=TS-Hauptstrasse&per_page=50" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"grid_operator_id\": 16,
    \"node_type\": \"vk\",
    \"bfs_number\": 22,
    \"q\": \"g\",
    \"per_page\": 16
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/nodes"
);

const params = {
    "grid_operator_id": "12",
    "node_type": "ne6",
    "bfs_number": "4241",
    "q": "TS-Hauptstrasse",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "grid_operator_id": 16,
    "node_type": "vk",
    "bfs_number": 22,
    "q": "g",
    "per_page": 16
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/nodes

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

grid_operator_id   integer  optional    

Filter to a specific VNB. Required for non-admin users. Example: 12

node_type   string  optional    

Filter by node type (ne4, ne6, vk). Example: ne6

bfs_number   integer  optional    

Filter by BFS municipality number stored in metadata.bfs_number. Example: 4241

q   string  optional    

Search in identifier and metadata.custom_label. Example: TS-Hauptstrasse

per_page   integer  optional    

Page size (1-200, default 50). Example: 50

Body Parameters

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

node_type   string  optional    

Example: vk

Must be one of:
  • ne4
  • ne6
  • vk
bfs_number   integer  optional    

Must be at least 1. Must not be greater than 9999. Example: 22

q   string  optional    

Must not be greater than 255 characters. Example: g

per_page   integer  optional    

Must be at least 1. Must not be greater than 200. Example: 16

List assignments scoped to one or more grid operators.

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/network-topology/assignments?grid_operator_id=12&egid=421158&ne6_node_id=87&per_page=16" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"grid_operator_id\": 16,
    \"egid\": \"n\",
    \"ne6_node_id\": 16,
    \"bfs_number\": 22,
    \"per_page\": 7
}"
const url = new URL(
    "https://gwr-datahub.test/api/network-topology/assignments"
);

const params = {
    "grid_operator_id": "12",
    "egid": "421158",
    "ne6_node_id": "87",
    "per_page": "16",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "grid_operator_id": 16,
    "egid": "n",
    "ne6_node_id": 16,
    "bfs_number": 22,
    "per_page": 7
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/network-topology/assignments

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

grid_operator_id   integer  optional    

Filter by VNB. Required for non-admin users. Example: 12

egid   string  optional    

Filter by exact EGID. Example: 421158

ne6_node_id   integer  optional    

Filter by transformer node. Example: 87

per_page   integer  optional    

Page size (1-200, default 50). Example: 16

Body Parameters

grid_operator_id   integer  optional    

Must match an existing stored value. Example: 16

egid   string  optional    

Must not be greater than 32 characters. Example: n

ne6_node_id   integer  optional    

Must match an existing stored value. Example: 16

bfs_number   integer  optional    

Must be at least 1. Must not be greater than 9999. Example: 22

per_page   integer  optional    

Must be at least 1. Must not be greater than 200. Example: 7

PV Multi-Roof Configuration

List available PV roof and facade surfaces for a building

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/123456/pv-roofs" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/pv-roofs"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/pv-roofs

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Building EGID. Example: 123456

List all PV multi-roof configurations for a building

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations?status=architecto&per_page=20" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations"
);

const params = {
    "status": "architecto",
    "per_page": "20",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/pv-multi-roof-configurations

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Building EGID. Example: 123456

Query Parameters

status   string  optional    

Filter by status (draft, calculating, completed, failed) Example: architecto

per_page   integer  optional    

Number of items per page. Example: 20

Create or update a PV multi-roof configuration

requires authentication

Example request:
curl --request POST \
    "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"id\": 1,
    \"name\": \"Main PV System\",
    \"description\": \"Eius et animi quos velit et.\",
    \"status\": \"draft\",
    \"surfaces\": [
        \"architecto\"
    ]
}"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id": 1,
    "name": "Main PV System",
    "description": "Eius et animi quos velit et.",
    "status": "draft",
    "surfaces": [
        "architecto"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/buildings/{egid}/pv-multi-roof-configurations

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Building EGID. Example: 123456

Body Parameters

id   integer  optional    

Configuration ID (for updates). Example: 1

name   string  optional    

Configuration name. Example: Main PV System

description   string  optional    

Configuration description Example: Eius et animi quos velit et.

status   string  optional    

Status (draft, calculating, completed, failed). Example: draft

surfaces   string[]     

Array of surface configurations

surface_id   string     

Example: architecto

enabled   boolean     

Example: true

type   string     

Example: facade

Must be one of:
  • roof
  • facade
tilt_deg   number     

Must be at least 0. Must not be greater than 90. Example: 22

azimuth_deg   number     

Must be at least -180. Must not be greater than 180. Example: 7

area_m2   number     

Must be at least 0.01. Example: 12

peak_power_kwp   number     

Must be at least 0. Example: 77

capacity_kwp_estimate   number     

Must be at least 0. Example: 8

suitability   integer     

Must be at least 1. Must not be greater than 5. Example: 3

technology   string     

Example: pv

Must be one of:
  • pv
annual_yield_kwh   integer  optional    

Must be at least 0. Example: 60

objektid   integer  optional    

Example: 16

building_id   string  optional    

Get a specific PV multi-roof configuration

requires authentication

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations/1?lang=de" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations/1"
);

const params = {
    "lang": "de",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/pv-multi-roof-configurations/{configId}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Building EGID. Example: 123456

configId   string     

Configuration ID. Example: 1

Query Parameters

lang   string  optional    

Language code (de, fr, it). Example: de

Get production profile for a specific configuration and year

requires authentication

Supports both TMY (Typical Meteorological Year) profiles and year-specific profiles. For TMY profiles, the data is mapped to the requested year's calendar.

Example request:
curl --request GET \
    --get "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations/1/profiles/2025" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://gwr-datahub.test/api/buildings/123456/pv-multi-roof-configurations/1/profiles/2025"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(self)
strict-transport-security: max-age=31536000; includeSubDomains
access-control-allow-origin: https://gwr-datahub.ecolabor.ch
access-control-expose-headers: X-Datahub-Proxy, X-Datahub-Proxy-Version
 

{
    "message": "Unauthenticated.",
    "code": "unauthenticated"
}
 

Request      

GET api/buildings/{egid}/pv-multi-roof-configurations/{configId}/profiles/{year}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

egid   string     

Building EGID. Example: 123456

configId   string     

Configuration ID. Example: 1

year   string     

Year. Example: 2025