openapi: 3.0.3
info:
title: 'gwr-datahub API Documentation'
description: 'API for accessing Swiss building registry (GWR) data, electricity tariffs from grid operators (VNB), and related infrastructure information.'
version: 1.0.0
servers:
-
url: 'https://gwr-datahub.ecolabor.ch'
tags:
-
name: Buildings
description: ''
-
name: 'EVU Tariffs'
description: ''
-
name: 'BDEW Profiles'
description: ''
-
name: 'Reference Market Prices'
description: ''
-
name: 'Reference Market Price Predictions'
description: ''
-
name: 'Transformer Stations'
description: ''
-
name: 'Educational Institutions'
description: ''
-
name: 'Municipal Properties'
description: ''
-
name: 'Water Supply Buildings'
description: ''
-
name: 'EIC Codes'
description: ''
-
name: Endpoints
description: ''
-
name: 'BFE Stromkennzeichnung'
description: "\nEndpoints for the Swiss Lieferantenmix (electricity-label) data\npublished yearly by Pronovo / BFE."
-
name: 'Economic Catalog'
description: ''
-
name: 'Electricity Production Plants'
description: ''
-
name: 'HKN Compensation Rates'
description: ''
-
name: 'Municipality Enrichment'
description: ''
-
name: 'Network Topology'
description: ''
-
name: 'PV Multi-Roof Configuration'
description: ''
components:
securitySchemes:
default:
type: http
scheme: bearer
description: 'You can retrieve your API token by logging into your account and navigating to Settings → API Tokens. Use Laravel Sanctum Bearer tokens for authentication.'
security:
-
default: []
paths:
/api/buildings:
get:
summary: 'List buildings by municipality (BFS)'
operationId: listBuildingsByMunicipalityBFS
description: "Returns a paginated list of GWR buildings for a given municipality (BFS number).\nCode label resolution is disabled by default for performance; enable with resolve_codes=1."
parameters:
-
in: query
name: municipality
description: 'integer BFS municipality number.'
example: '261'
required: true
schema:
type: string
description: 'integer BFS municipality number.'
example: '261'
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
-
in: query
name: lang
description: 'Language for code labels when resolve_codes=1. Options: de, fr, it. Default: de.'
example: de
required: false
schema:
type: string
description: 'Language for code labels when resolve_codes=1. Options: de, fr, it. Default: de.'
example: de
-
in: query
name: resolve_codes
description: 'Whether to resolve code labels. Default: 0.'
example: true
required: false
schema:
type: boolean
description: 'Whether to resolve code labels. Default: 0.'
example: true
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Buildings
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 17
nullable: true
lang:
type: string
description: ''
example: fr
enum:
- de
- fr
- it
nullable: true
resolve_codes:
type: boolean
description: ''
example: true
nullable: true
required:
- municipality
/api/buildings/map-data:
get:
summary: 'Get lightweight map data for buildings by municipality'
operationId: getLightweightMapDataForBuildingsByMunicipality
description: "Returns minimal building data optimized for map visualizations.\nOnly includes buildings with valid coordinates (latitude/longitude)."
parameters:
-
in: query
name: municipality
description: 'integer BFS municipality number.'
example: '261'
required: true
schema:
type: string
description: 'integer BFS municipality number.'
example: '261'
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
-
in: query
name: page
description: 'Page number. Min: 1. Default: 1.'
example: 1
required: false
schema:
type: integer
description: 'Page number. Min: 1. Default: 1.'
example: 1
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Buildings
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 17
nullable: true
page:
type: integer
description: 'Must be at least 1.'
example: 35
nullable: true
required:
- municipality
'/api/buildings/{egid}':
get:
summary: 'Get building information by EGID'
operationId: getBuildingInformationByEGID
description: "Returns detailed information about a building from the GWR (Gebäude- und Wohnungsregister) database.\nAll code fields are automatically resolved to their human-readable labels in the specified language.\n\nIf address or solar potential data is missing, it will be automatically synchronized before returning the response."
parameters:
-
in: query
name: lang
description: 'The language for code labels. Options: `de` (German), `fr` (French), `it` (Italian). Default: `de`.'
example: de
required: false
schema:
type: string
description: 'The language for code labels. Options: `de` (German), `fr` (French), `it` (Italian). Default: `de`.'
example: de
-
in: query
name: sync
description: '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
required: false
schema:
type: boolean
description: '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
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.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
created_at: '2025-01-01T00:00:00+00:00'
updated_at: '2025-01-01T00:00:00+00:00'
properties:
egid:
type: string
example: '1234567890'
gdekt:
type: string
example: ZH
ggdenr:
type: string
example: '261'
ggdename:
type: string
example: Zürich
egrid:
type: string
example: '2680000.0,1240000.0'
gbez:
type: string
example: Wohnhaus
gkode:
type: string
example: '01'
gkode_label:
type: string
example: Wohngebäude
gstat:
type: string
example: '01'
gstat_label:
type: string
example: Bestehend
gkat:
type: string
example: '01'
gkat_label:
type: string
example: Einfamilienhaus
gbauj:
type: integer
example: 1990
garea:
type: number
example: 150.5
gvol:
type: number
example: 450.0
address:
type: object
properties:
street:
type: string
example: 'Hauptstrasse 45'
postal_code:
type: string
example: '6260'
city:
type: string
example: Reiden
solar_roofs:
type: array
example:
-
attributes:
building_id: '229760'
suitability: high
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: high
geometry:
type: object
properties:
rings:
type: array
example:
-
-
- 2640325.75
- 1232914.625
items:
type: array
solar_facades:
type: array
example:
-
attributes:
building_id: '229760'
suitability: medium
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: medium
geometry:
type: object
properties:
rings:
type: array
example:
-
-
- 2640325.75
- 1232914.625
items:
type: array
created_at:
type: string
example: '2025-01-01T00:00:00+00:00'
updated_at:
type: string
example: '2025-01-01T00:00:00+00:00'
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Building not found'
properties:
message:
type: string
example: 'Building not found'
tags:
- Buildings
parameters:
-
in: path
name: egid
description: 'string The building EGID (Eidgenössische Gebäudeidentifikator).'
example: '1234567890'
required: true
schema:
type: string
/api/evu-tariffs/operators:
get:
summary: 'List all grid operators'
operationId: listAllGridOperators
description: "Returns a paginated list of all active grid operators (Verteilnetzbetreiber) with their tariff URL status\nand information about the latest successful tariff submission."
parameters:
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 100. Default: 50.'
example: 50
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 100. Default: 50.'
example: 50
-
in: query
name: status
description: 'Filter by tariff URL status. Options: pending, found, not_found, manual, invalid.'
example: found
required: false
schema:
type: string
description: 'Filter by tariff URL status. Options: pending, found, not_found, manual, invalid.'
example: found
-
in: query
name: search
description: 'Search by operator name or CH UID.'
example: EKZ
required: false
schema:
type: string
description: 'Search by operator name or CH UID.'
example: EKZ
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
ch_uid:
type: string
example: CHE-108.954.688
name:
type: string
example: 'Elektrizitätswerke des Kantons Zürich (EKZ)'
website_url:
type: string
example: www.ekz.ch
tariff_url:
type: string
example: 'https://ekz.ch/api/tariffs.json'
tariff_url_status:
type: string
example: found
tariff_url_verified_at:
type: string
example: '2026-01-15T10:00:00+00:00'
is_active:
type: boolean
example: true
latest_submission:
type: object
properties:
fetched_at:
type: string
example: '2026-01-15T10:00:00+00:00'
tariff_year:
type: integer
example: 2026
tariff_count:
type: integer
example: 12
elcom_synced_at:
type: string
example: '2026-01-01T00:00:00+00:00'
links:
type: object
properties:
first:
type: string
example: 'https://example.com/api/evu-tariffs/operators?page=1'
last:
type: string
example: 'https://example.com/api/evu-tariffs/operators?page=10'
prev:
type: string
example: null
nullable: true
next:
type: string
example: 'https://example.com/api/evu-tariffs/operators?page=2'
meta:
type: object
properties:
current_page:
type: integer
example: 1
from:
type: integer
example: 1
last_page:
type: integer
example: 10
per_page:
type: integer
example: 50
to:
type: integer
example: 50
total:
type: integer
example: 500
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'EVU Tariffs'
'/api/evu-tariffs/operators/{chUid}':
get:
summary: 'Get a single grid operator'
operationId: getASingleGridOperator
description: "Returns detailed information about a specific grid operator (Verteilnetzbetreiber) by its CH UID,\nincluding the latest submission status and tariff URL information."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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'
properties:
ch_uid:
type: string
example: CHE-108.954.688
name:
type: string
example: 'Elektrizitätswerke des Kantons Zürich (EKZ)'
website_url:
type: string
example: www.ekz.ch
tariff_url:
type: string
example: 'https://ekz.ch/api/tariffs.json'
tariff_url_status:
type: string
example: found
tariff_url_verified_at:
type: string
example: '2026-01-15T10:00:00+00:00'
is_active:
type: boolean
example: true
latest_submission:
type: object
properties:
fetched_at:
type: string
example: '2026-01-15T10:00:00+00:00'
tariff_year:
type: integer
example: 2026
tariff_count:
type: integer
example: 12
elcom_synced_at:
type: string
example: '2026-01-01T00:00:00+00:00'
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
error: 'Grid operator not found'
code: operator_not_found
properties:
error:
type: string
example: 'Grid operator not found'
code:
type: string
example: operator_not_found
tags:
- 'EVU Tariffs'
parameters:
-
in: path
name: chUid
description: 'string The CH UID (Unternehmens-Identifikationsnummer) of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/evu-tariffs/operators/{chUid}/tariffs':
get:
summary: 'Get tariffs for a grid operator'
operationId: getTariffsForAGridOperator
description: "Returns the cached tariffs for a specific grid operator in the standard format\naccording to StromVV Art. 7b. The response includes all tariff types:\n- `electricity`: Elektrizitätstarif (energy costs)\n- `grid`: Netznutzungstarif (grid usage fees)\n- `metering`: Messtarif (metering costs)\n- `regional_fees`: Abgaben an Gemeinwesen (taxes and levies)\n\nTariff forms can be:\n- `constant`: Single price (Einheitstarif)\n- `multilevel`: Time-of-use pricing with HT/NT (Mehrstufentarif)\n- `dynamic`: Real-time pricing (Dynamischer Tarif) - use the dynamic endpoint for current prices"
parameters:
-
in: query
name: year
description: 'Filter by tariff year. Default: current year.'
example: 2026
required: false
schema:
type: integer
description: 'Filter by tariff year. Default: current year.'
example: 2026
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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'
properties:
dsoName:
type: string
example: 'Elektrizitätswerke des Kantons Zürich (EKZ)'
dsoNumber:
type: integer
example: 10895468800
tariffs:
type: array
example:
-
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
items:
type: object
properties:
customerVoltageLevel:
type: integer
example: 7
tariffName:
type: string
example: 'Haushalt Standard'
tariffType:
type: string
example: electricity
tariffForm:
type: string
example: multilevel
startDate:
type: string
example: '2026-01-01'
endDate:
type: string
example: '2026-12-31'
comment:
type: string
example: null
nullable: true
customerType:
type: string
example: household
prices:
type: object
properties:
multilevel:
type: object
properties:
levels:
type: array
example:
-
name: HT
price: 0.22
unit: CHF/kWh
-
name: NT
price: 0.18
unit: CHF/kWh
items:
type: object
properties:
name: { type: string, example: HT }
price: { type: number, example: 0.22 }
unit: { type: string, example: CHF/kWh }
_meta:
type: object
properties:
ch_uid:
type: string
example: CHE-108.954.688
fetched_at:
type: string
example: '2026-01-15T10:00:00+00:00'
tariff_year:
type: integer
example: 2026
source_url:
type: string
example: 'https://ekz.ch/api/tariffs.json'
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
oneOf:
-
description: 'Operator not found'
type: object
example:
error: 'Grid operator not found'
code: operator_not_found
properties:
error:
type: string
example: 'Grid operator not found'
code:
type: string
example: operator_not_found
-
description: 'No tariffs available'
type: object
example:
error: 'No tariffs found for this operator'
code: tariffs_not_found
operator: CHE-108.954.688
year: 2026
properties:
error:
type: string
example: 'No tariffs found for this operator'
code:
type: string
example: tariffs_not_found
operator:
type: string
example: CHE-108.954.688
year:
type: integer
example: 2026
tags:
- 'EVU Tariffs'
parameters:
-
in: path
name: chUid
description: 'string The CH UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/evu-tariffs/operators/{chUid}/dynamic':
get:
summary: 'Proxy dynamic tariff data'
operationId: proxyDynamicTariffData
description: "Proxies requests to the dynamic tariff URL of a grid operator to retrieve real-time pricing data.\nThis endpoint is only available for operators that offer dynamic tariffs (tariffForm: \"dynamic\").\n\nThe response format depends on the grid operator's implementation but typically includes\ncurrent and/or upcoming electricity prices with timestamps."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
timestamp:
type: string
example: '2026-01-15T14:00:00+01:00'
prices:
type: array
example:
-
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
items:
type: object
properties:
start:
type: string
example: '2026-01-15T14:00:00+01:00'
end:
type: string
example: '2026-01-15T15:00:00+01:00'
price:
type: number
example: 0.185
unit:
type: string
example: CHF/kWh
400:
description: 'No dynamic tariff available'
content:
application/json:
schema:
type: object
example:
error: 'Operator does not have a dynamic tariff URL configured'
code: proxy_error
properties:
error:
type: string
example: 'Operator does not have a dynamic tariff URL configured'
code:
type: string
example: proxy_error
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
error: 'Grid operator not found'
code: operator_not_found
properties:
error:
type: string
example: 'Grid operator not found'
code:
type: string
example: operator_not_found
502:
description: 'Upstream error'
content:
application/json:
schema:
type: object
example:
error: 'Failed to fetch dynamic tariff data from operator'
code: proxy_error
properties:
error:
type: string
example: 'Failed to fetch dynamic tariff data from operator'
code:
type: string
example: proxy_error
tags:
- 'EVU Tariffs'
parameters:
-
in: path
name: chUid
description: 'string The CH UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/evu-tariffs/operators/{chUid}/tariff-url':
put:
summary: 'Set the machine-readable tariff URL for a grid operator'
operationId: setTheMachineReadableTariffURLForAGridOperator
description: "Sets the URL of the operator's machine-readable tariff JSON (StromVV Art. 7b)\nwith status `manual` and dispatches a fetch job so the tariffs become\navailable shortly afterwards. Pass `fetch: false` to skip the fetch job."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
ch_uid: CHE-108.954.688
tariff_url: 'https://ekz.ch/api/tariffs.json'
tariff_url_status: manual
properties:
data:
type: object
properties:
ch_uid:
type: string
example: CHE-108.954.688
tariff_url:
type: string
example: 'https://ekz.ch/api/tariffs.json'
tariff_url_status:
type: string
example: manual
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
403:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Not authorized for this grid operator'
code: forbidden_grid_operator
properties:
message:
type: string
example: 'Not authorized for this grid operator'
code:
type: string
example: forbidden_grid_operator
404:
description: ''
content:
application/json:
schema:
type: object
example:
error: 'Grid operator not found'
code: operator_not_found
properties:
error:
type: string
example: 'Grid operator not found'
code:
type: string
example: operator_not_found
tags:
- 'EVU Tariffs'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
tariff_url:
type: string
description: 'Direct download URL of the tariff JSON file.'
example: 'https://ekz.ch/api/tariffs.json'
fetch:
type: boolean
description: 'Whether to dispatch a fetch job immediately. Default: true.'
example: true
nullable: true
required:
- tariff_url
parameters:
-
in: path
name: chUid
description: 'string The CH UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/evu-tariffs/operators/{chUid}/tariffs/import':
post:
summary: 'Import a machine-readable tariff JSON for a grid operator'
operationId: importAMachineReadableTariffJSONForAGridOperator
description: "Imports a tariff JSON document (StromVV Art. 7b / VSE OpenAPI 3.0.3 format)\ndirectly, e.g. a file provided by the operator before it is published online.\nThe request body must be the raw tariff JSON document itself\n(with `dsoName`, `dsoNumber` and `tariffs`). Uses the same validation,\nchecksum deduplication and storage as URL-based fetching."
parameters: []
responses:
201:
description: ''
content:
application/json:
schema:
type: object
example:
data:
submission_id: 123
tariff_count: 12
properties:
data:
type: object
properties:
submission_id:
type: integer
example: 123
tariff_count:
type: integer
example: 12
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
403:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Not authorized for this grid operator'
code: forbidden_grid_operator
properties:
message:
type: string
example: 'Not authorized for this grid operator'
code:
type: string
example: forbidden_grid_operator
404:
description: ''
content:
application/json:
schema:
type: object
example:
error: 'Grid operator not found'
code: operator_not_found
properties:
error:
type: string
example: 'Grid operator not found'
code:
type: string
example: operator_not_found
422:
description: ''
content:
application/json:
schema:
type: object
example:
error: 'Missing or invalid "tariffs" array'
code: tariff_validation_error
properties:
error:
type: string
example: 'Missing or invalid "tariffs" array'
code:
type: string
example: tariff_validation_error
tags:
- 'EVU Tariffs'
parameters:
-
in: path
name: chUid
description: 'string The CH UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
/api/bdew-profiles:
get:
summary: 'List all BDEW profile codes'
operationId: listAllBDEWProfileCodes
description: "Returns a list of all available BDEW standard load profile codes (e.g., H0, G0-G6, L0-L2).\nEach profile code represents a category of electricity consumption patterns."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
code: H0
name: Household
category: household
description: 'Standard household profile'
metadata: { }
-
code: G25
name: Commercial
category: commercial
description: 'Commercial profile'
metadata: { }
properties:
data:
type: array
example:
-
code: H0
name: Household
category: household
description: 'Standard household profile'
metadata: []
-
code: G25
name: Commercial
category: commercial
description: 'Commercial profile'
metadata: []
items:
type: object
properties:
code:
type: string
example: H0
name:
type: string
example: Household
category:
type: string
example: household
description:
type: string
example: 'Standard household profile'
metadata:
type: object
properties: { }
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'BDEW Profiles'
'/api/bdew-profiles/{code}':
get:
summary: 'Get all variations for a BDEW profile code'
operationId: getAllVariationsForABDEWProfileCode
description: "Returns all 9 variations (3 seasons × 3 day types) for a specific BDEW profile code.\nEach variation contains 96 normalized values representing 15-minute intervals for a day."
parameters: []
responses:
200:
description: ''
content:
text/plain:
schema:
type: string
example: "{\n \"code\": \"H0\",\n \"name\": \"Household\",\n \"category\": \"household\",\n \"variations\": [\n {\n \"profile_code\": \"H0\",\n \"season\": \"winter\",\n \"day_type\": \"weekday\",\n \"values\": [0.0104, 0.0099, ...],\n \"is_dynamized\": true,\n \"description\": null,\n \"metadata\": {}\n },\n {\n \"profile_code\": \"H0\",\n \"season\": \"winter\",\n \"day_type\": \"saturday\",\n \"values\": [0.0104, 0.0099, ...],\n \"is_dynamized\": true,\n \"description\": null,\n \"metadata\": {}\n }\n ]\n}"
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Profile code not found'
properties:
message:
type: string
example: 'Profile code not found'
tags:
- 'BDEW Profiles'
parameters:
-
in: path
name: code
description: 'string The BDEW profile code (e.g., H0, G25, L25).'
example: H0
required: true
schema:
type: string
'/api/bdew-profiles/{code}/daily':
get:
summary: 'Get daily template for a BDEW profile code by date'
operationId: getDailyTemplateForABDEWProfileCodeByDate
description: "Returns the correct BDEW load profile template for a specific date.\nThe season (winter/summer/transition) and day type (weekday/saturday/sunday) are automatically determined from the date."
parameters:
-
in: query
name: date
description: 'string The date in YYYY-MM-DD format.'
example: '2025-01-15'
required: true
schema:
type: string
description: 'string The date in YYYY-MM-DD format.'
example: '2025-01-15'
responses:
200:
description: ''
content:
text/plain:
schema:
type: string
example: "{\n \"code\": \"H0\",\n \"date\": \"2025-01-15\",\n \"season\": \"winter\",\n \"day_type\": \"wednesday\",\n \"values\": [0.0104, 0.0099, ...],\n \"is_dynamized\": true,\n \"description\": null,\n \"metadata\": {}\n}"
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Profile code not found'
properties:
message:
type: string
example: 'Profile code not found'
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'The given data was invalid.'
errors:
date:
- 'The date field is required.'
properties:
message:
type: string
example: 'The given data was invalid.'
errors:
type: object
properties:
date:
type: array
example:
- 'The date field is required.'
items:
type: string
tags:
- 'BDEW Profiles'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
date:
type: string
description: 'Must be a valid date in the format Y-m-d.'
example: '2026-08-21'
required:
- date
parameters:
-
in: path
name: code
description: 'string The BDEW profile code (e.g., H0, G25, L25).'
example: H0
required: true
schema:
type: string
'/api/bdew-profiles/{code}/year':
get:
summary: 'Get yearly profile for a BDEW profile code'
operationId: getYearlyProfileForABDEWProfileCode
description: "Returns a complete year's worth of BDEW load profile data with all 365/366 days.\nEach day includes 96 quarter-hour values, with dynamization applied where applicable.\nHolidays are treated as Sundays, and Dec 24/31 use Saturday templates."
parameters:
-
in: query
name: year
description: 'integer The year for the profile (2020-2035).'
example: '2025'
required: true
schema:
type: string
description: 'integer The year for the profile (2020-2035).'
example: '2025'
responses:
200:
description: ''
content:
text/plain:
schema:
type: string
example: "{\n \"code\": \"H25\",\n \"year\": 2025,\n \"is_dynamized\": true,\n \"total_kwh\": 1000000.00,\n \"days\": [\n {\n \"date\": \"2025-01-01\",\n \"day_of_year\": 1,\n \"month\": 1,\n \"day_type\": \"sunday\",\n \"is_holiday\": true,\n \"holiday_name\": \"Neujahr\",\n \"dynamization_factor\": 1.2421,\n \"values\": [22.15, 20.81, 19.76, ...]\n }\n ],\n \"meta\": {\n \"total_days\": 365,\n \"is_leap_year\": false,\n \"generated_at\": \"2025-01-15T10:30:00Z\"\n }\n}"
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Profile code not found'
properties:
message:
type: string
example: 'Profile code not found'
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'The given data was invalid.'
errors:
year:
- 'The year field is required.'
properties:
message:
type: string
example: 'The given data was invalid.'
errors:
type: object
properties:
year:
type: array
example:
- 'The year field is required.'
items:
type: string
tags:
- 'BDEW Profiles'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
year:
type: string
description: ''
example: null
parameters:
-
in: path
name: code
description: 'string The BDEW profile code (e.g., H25, G25, L25).'
example: H25
required: true
schema:
type: string
'/api/bdew-profiles/{code}/years':
get:
summary: 'List available years for a profile code'
operationId: listAvailableYearsForAProfileCode
description: 'Returns the years that have pre-generated yearly profiles available.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
code: H25
available_years:
- 2024
- 2025
- 2026
supported_range:
min: 2020
max: 2035
properties:
code:
type: string
example: H25
available_years:
type: array
example:
- 2024
- 2025
- 2026
items:
type: integer
supported_range:
type: object
properties:
min:
type: integer
example: 2020
max:
type: integer
example: 2035
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Profile code not found'
properties:
message:
type: string
example: 'Profile code not found'
tags:
- 'BDEW Profiles'
parameters:
-
in: path
name: code
description: 'string The BDEW profile code (e.g., H25, G25).'
example: H25
required: true
schema:
type: string
/api/reference-market-prices:
get:
summary: 'List reference market prices'
operationId: listReferenceMarketPrices
description: "Returns a paginated list of BFE reference market prices (Art. 15 EnFV).\nPrices are available for different technologies (photovoltaic, hydropower, biomass, wind, geothermal)\nand different period types (monthly, quarterly)."
parameters:
-
in: query
name: technology
description: 'Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal.'
example: photovoltaic
required: false
schema:
type: string
description: 'Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal.'
example: photovoltaic
-
in: query
name: period_type
description: 'Filter by period type. Options: monthly, quarterly.'
example: monthly
required: false
schema:
type: string
description: 'Filter by period type. Options: monthly, quarterly.'
example: monthly
-
in: query
name: year
description: 'Filter by year.'
example: 2025
required: false
schema:
type: integer
description: 'Filter by year.'
example: 2025
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
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
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
technology:
type: string
example: photovoltaic
technology_label:
type: string
example: Photovoltaik
period_type:
type: string
example: monthly
period_type_label:
type: string
example: Monatlich
year:
type: integer
example: 2025
period:
type: integer
example: 1
period_label:
type: string
example: 'Januar 2025'
price:
type: number
example: 85.5
price_unit:
type: string
example: CHF/MWh
volume:
type: number
example: 125000.0
volume_unit:
type: string
example: MWh
created_at:
type: string
example: '2025-01-15T12:00:00+00:00'
updated_at:
type: string
example: '2025-01-15T12:00:00+00:00'
links:
type: object
properties:
first:
type: string
example: ...
last:
type: string
example: ...
prev:
type: string
example: null
nullable: true
next:
type: string
example: ...
meta:
type: object
properties:
current_page:
type: integer
example: 1
from:
type: integer
example: 1
last_page:
type: integer
example: 5
per_page:
type: integer
example: 100
to:
type: integer
example: 100
total:
type: integer
example: 450
tags:
- 'Reference Market Prices'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
technology:
type: string
description: ''
example: photovoltaic
enum:
- photovoltaic
- hydropower
- biomass
- wind
- geothermal
nullable: true
period_type:
type: string
description: ''
example: monthly
enum:
- monthly
- quarterly
nullable: true
year:
type: integer
description: 'Must be at least 2007. Must not be greater than 2100.'
example: 1
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 22
nullable: true
/api/reference-market-prices/latest:
get:
summary: 'Get latest prices per technology'
operationId: getLatestPricesPerTechnology
description: "Returns the most recent reference market price for each technology,\ngrouped by period type (monthly and quarterly)."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
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
properties:
monthly:
type: object
properties:
photovoltaic:
type: object
properties:
id:
type: integer
example: 1
technology:
type: string
example: photovoltaic
technology_label:
type: string
example: Photovoltaik
period_type:
type: string
example: monthly
period_type_label:
type: string
example: Monatlich
year:
type: integer
example: 2025
period:
type: integer
example: 12
period_label:
type: string
example: 'Dezember 2025'
price:
type: number
example: 85.5
price_unit:
type: string
example: CHF/MWh
volume:
type: number
example: 125000.0
volume_unit:
type: string
example: MWh
created_at:
type: string
example: '2025-01-15T12:00:00+00:00'
updated_at:
type: string
example: '2025-01-15T12:00:00+00:00'
quarterly:
type: object
properties:
photovoltaic:
type: object
properties:
id:
type: integer
example: 2
technology:
type: string
example: photovoltaic
period_type:
type: string
example: quarterly
year:
type: integer
example: 2025
period:
type: integer
example: 4
period_label:
type: string
example: 'Q4 2025'
price:
type: number
example: 82.3
tags:
- 'Reference Market Prices'
/api/reference-market-prices/technologies:
get:
summary: 'List available technologies'
operationId: listAvailableTechnologies
description: 'Returns a list of all available technologies with their labels.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
technologies:
type: array
example:
-
value: photovoltaic
label: Photovoltaik
-
value: hydropower
label: Wasserkraft
-
value: biomass
label: Biomasse
-
value: wind
label: Windenergie
-
value: geothermal
label: Geothermie
items:
type: object
properties:
value:
type: string
example: photovoltaic
label:
type: string
example: Photovoltaik
period_types:
type: array
example:
-
value: monthly
label: Monatlich
-
value: quarterly
label: Quartal
items:
type: object
properties:
value:
type: string
example: monthly
label:
type: string
example: Monatlich
tags:
- 'Reference Market Prices'
/api/reference-market-price-predictions:
get:
summary: 'List reference market price predictions'
operationId: listReferenceMarketPricePredictions
description: "Returns a paginated list of predicted reference market prices based on EPEX spot prices\nand ENTSO-E generation profiles (BFE Art. 15 EnFV methodology)."
parameters:
-
in: query
name: technology
description: 'Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal.'
example: photovoltaic
required: false
schema:
type: string
description: 'Filter by technology. Options: photovoltaic, hydropower, biomass, wind, geothermal.'
example: photovoltaic
-
in: query
name: period_type
description: 'Filter by period type. Options: monthly, quarterly.'
example: monthly
required: false
schema:
type: string
description: 'Filter by period type. Options: monthly, quarterly.'
example: monthly
-
in: query
name: year
description: 'Filter by year.'
example: 2026
required: false
schema:
type: integer
description: 'Filter by year.'
example: 2026
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
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: { }
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
technology:
type: string
example: photovoltaic
technology_label:
type: string
example: Photovoltaik
period_type:
type: string
example: monthly
period_type_label:
type: string
example: Monatlich
year:
type: integer
example: 2026
period:
type: integer
example: 1
period_label:
type: string
example: 'Januar 2026'
price:
type: number
example: 72.35
price_unit:
type: string
example: CHF/MWh
volume:
type: number
example: 125000.0
volume_unit:
type: string
example: MWh
calculated_at:
type: string
example: '2026-02-10T07:30:00+00:00'
data_completeness:
type: number
example: 98.5
is_partial:
type: boolean
example: false
created_at:
type: string
example: '2026-01-15T12:00:00+00:00'
updated_at:
type: string
example: '2026-02-10T07:30:00+00:00'
links:
type: object
properties: { }
meta:
type: object
properties: { }
tags:
- 'Reference Market Price Predictions'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
technology:
type: string
description: ''
example: photovoltaic
enum:
- photovoltaic
- hydropower
- biomass
- wind
- geothermal
nullable: true
period_type:
type: string
description: ''
example: monthly
enum:
- monthly
- quarterly
nullable: true
year:
type: integer
description: 'Must be at least 2020. Must not be greater than 2100.'
example: 1
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 22
nullable: true
/api/reference-market-price-predictions/latest:
get:
summary: 'Get latest predictions per technology'
operationId: getLatestPredictionsPerTechnology
description: "Returns the most recent prediction for each technology,\ngrouped by period type (monthly and quarterly)."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
monthly:
photovoltaic: { }
quarterly:
photovoltaic: { }
properties:
monthly:
type: object
properties:
photovoltaic:
type: object
properties: { }
quarterly:
type: object
properties:
photovoltaic:
type: object
properties: { }
tags:
- 'Reference Market Price Predictions'
/api/reference-market-price-predictions/current-month:
get:
summary: 'Get current month prediction'
operationId: getCurrentMonthPrediction
description: "Returns the prediction for the current (in-progress) month,\nincluding data completeness and partial status."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
year: 2026
month: 2
predictions: { }
properties:
year:
type: integer
example: 2026
month:
type: integer
example: 2
predictions:
type: object
properties: { }
tags:
- 'Reference Market Price Predictions'
/api/reference-market-price-predictions/compare:
get:
summary: 'Compare predictions with official BFE values'
operationId: comparePredictionsWithOfficialBFEValues
description: "Returns a side-by-side comparison of predicted values against\nthe official BFE reference market prices where both are available."
parameters:
-
in: query
name: technology
description: 'Filter by technology.'
example: photovoltaic
required: false
schema:
type: string
description: 'Filter by technology.'
example: photovoltaic
-
in: query
name: year
description: 'Filter by year.'
example: 2026
required: false
schema:
type: integer
description: 'Filter by year.'
example: 2026
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
comparisons:
type: array
example:
-
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
items:
type: object
properties:
technology:
type: string
example: photovoltaic
period_type:
type: string
example: monthly
year:
type: integer
example: 2026
period:
type: integer
example: 1
period_label:
type: string
example: 'Januar 2026'
predicted_price:
type: number
example: 72.35
official_price:
type: number
example: 73.1
deviation:
type: number
example: -0.75
deviation_percent:
type: number
example: -1.03
data_completeness:
type: number
example: 98.5
tags:
- 'Reference Market Price Predictions'
/api/transformer-stations:
get:
summary: 'List transformer stations'
operationId: listTransformerStations
description: "Returns a list of transformer stations (Trafostationen) with various filtering options.\nYou can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates.\nCoordinates are taken directly from `gwr_buildings.GKODE` (Easting) and `gwr_buildings.GKODN` (Northing).\nThe `egrid` field contains the raw EGRID value from `gwr_buildings.EGRID`."
parameters:
-
in: query
name: municipality
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
required: false
schema:
type: integer
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
-
in: query
name: postal_code
description: 'Filter by postal code (PLZ).'
example: 8001
required: false
schema:
type: integer
description: 'Filter by postal code (PLZ).'
example: 8001
-
in: query
name: status
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
required: false
schema:
type: string
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
-
in: query
name: lat
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
required: false
schema:
type: number
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
-
in: query
name: lng
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
required: false
schema:
type: number
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
-
in: query
name: radius
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
required: false
schema:
type: number
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
-
in: query
name: east
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
required: false
schema:
type: number
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
-
in: query
name: north
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
required: false
schema:
type: number
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
north: 1240000.0
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'
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
egid:
type: string
example: '1234567890'
status:
type: string
example: confirmed
building:
type: object
properties:
egid:
type: string
example: '1234567890'
gbez:
type: string
example: 'Trafo Station 1'
ggdenr:
type: string
example: '261'
ggdename:
type: string
example: Zürich
egrid:
type: string
example: '2680000.0,1240000.0'
address:
type: object
properties:
street:
type: string
example: 'Hauptstrasse 45'
postal_code:
type: string
example: '6260'
city:
type: string
example: Reiden
solar_roofs:
type: array
example:
-
attributes:
building_id: '229760'
suitability: high
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: high
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
solar_facades:
type: array
example:
-
attributes:
building_id: '229760'
suitability: medium
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: medium
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
coordinates:
type: object
properties:
east:
type: number
example: 2680000.0
north:
type: number
example: 1240000.0
coordinates_wgs84:
type: object
properties:
lat:
type: number
example: 47.3769
lng:
type: number
example: 8.5417
created_at:
type: string
example: '2025-01-01T00:00:00+00:00'
updated_at:
type: string
example: '2025-01-01T00:00:00+00:00'
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'The given data was invalid.'
errors:
lat:
- 'The lat field is required when lng is present.'
properties:
message:
type: string
example: 'The given data was invalid.'
errors:
type: object
properties:
lat:
type: array
example:
- 'The lat field is required when lng is present.'
items:
type: string
tags:
- 'Transformer Stations'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
nullable: true
postal_code:
type: number
description: ''
example: 4326.41688
nullable: true
lat:
type: number
description: 'This field is required when lng or radius is present. Must be between -90 and 90.'
example: -90
nullable: true
lng:
type: number
description: 'This field is required when lat or radius is present. Must be between -180 and 180.'
example: -180
nullable: true
east:
type: number
description: 'This field is required when north or radius is present.'
example: 4326.41688
nullable: true
north:
type: number
description: 'This field is required when east or radius is present.'
example: 4326.41688
nullable: true
radius:
type: number
description: 'Must be at least 1. Must not be greater than 50000.'
example: 17
nullable: true
status:
type: string
description: ''
example: confirmed
enum:
- candidate
- confirmed
nullable: true
/api/educational-institutions:
get:
summary: 'List educational institutions'
operationId: listEducationalInstitutions
description: "Returns a list of educational institutions (Schulhäuser, Kindergärten, etc.) with various filtering options.\nYou can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates.\nCoordinates are taken directly from `gwr_buildings.GKODE` (Easting) and `gwr_buildings.GKODN` (Northing)."
parameters:
-
in: query
name: municipality
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
required: false
schema:
type: integer
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
-
in: query
name: postal_code
description: 'Filter by postal code (PLZ).'
example: 8001
required: false
schema:
type: integer
description: 'Filter by postal code (PLZ).'
example: 8001
-
in: query
name: status
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
required: false
schema:
type: string
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
-
in: query
name: lat
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
required: false
schema:
type: number
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
-
in: query
name: lng
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
required: false
schema:
type: number
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
-
in: query
name: radius
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
required: false
schema:
type: number
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
-
in: query
name: east
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
required: false
schema:
type: number
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
-
in: query
name: north
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
required: false
schema:
type: number
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
north: 1240000.0
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'
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
egid:
type: string
example: '1234567890'
status:
type: string
example: confirmed
building:
type: object
properties:
egid:
type: string
example: '1234567890'
gbez:
type: string
example: 'Schulhaus Muster'
ggdenr:
type: string
example: '261'
ggdename:
type: string
example: Zürich
egrid:
type: string
example: '2680000.0,1240000.0'
address:
type: object
properties:
street:
type: string
example: 'Hauptstrasse 45'
postal_code:
type: string
example: '6260'
city:
type: string
example: Reiden
solar_roofs:
type: array
example:
-
attributes:
building_id: '229760'
suitability: high
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: high
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
solar_facades:
type: array
example:
-
attributes:
building_id: '229760'
suitability: medium
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: medium
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
coordinates:
type: object
properties:
east:
type: number
example: 2680000.0
north:
type: number
example: 1240000.0
coordinates_wgs84:
type: object
properties:
lat:
type: number
example: 47.3769
lng:
type: number
example: 8.5417
created_at:
type: string
example: '2025-01-01T00:00:00+00:00'
updated_at:
type: string
example: '2025-01-01T00:00:00+00:00'
tags:
- 'Educational Institutions'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
nullable: true
postal_code:
type: number
description: ''
example: 4326.41688
nullable: true
lat:
type: number
description: 'This field is required when lng or radius is present. Must be between -90 and 90.'
example: -90
nullable: true
lng:
type: number
description: 'This field is required when lat or radius is present. Must be between -180 and 180.'
example: -180
nullable: true
east:
type: number
description: 'This field is required when north or radius is present.'
example: 4326.41688
nullable: true
north:
type: number
description: 'This field is required when east or radius is present.'
example: 4326.41688
nullable: true
radius:
type: number
description: 'Must be at least 1. Must not be greater than 50000.'
example: 17
nullable: true
status:
type: string
description: ''
example: confirmed
enum:
- candidate
- confirmed
nullable: true
/api/municipal-properties:
get:
summary: 'List municipal properties'
operationId: listMunicipalProperties
description: "Returns a list of municipal properties (Werkhöfe, Gemeindeverwaltung, Gemeindehaus, Feuerwehrmagazin, etc.) with various filtering options.\nYou can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates.\nCoordinates are taken directly from `gwr_buildings.GKODE` (Easting) and `gwr_buildings.GKODN` (Northing)."
parameters:
-
in: query
name: municipality
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
required: false
schema:
type: integer
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
-
in: query
name: postal_code
description: 'Filter by postal code (PLZ).'
example: 8001
required: false
schema:
type: integer
description: 'Filter by postal code (PLZ).'
example: 8001
-
in: query
name: status
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
required: false
schema:
type: string
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
-
in: query
name: lat
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
required: false
schema:
type: number
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
-
in: query
name: lng
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
required: false
schema:
type: number
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
-
in: query
name: radius
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
required: false
schema:
type: number
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
-
in: query
name: east
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
required: false
schema:
type: number
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
-
in: query
name: north
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
required: false
schema:
type: number
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
north: 1240000.0
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'
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
egid:
type: string
example: '1234567890'
status:
type: string
example: confirmed
building:
type: object
properties:
egid:
type: string
example: '1234567890'
gbez:
type: string
example: Gemeindehaus
ggdenr:
type: string
example: '261'
ggdename:
type: string
example: Zürich
egrid:
type: string
example: '2680000.0,1240000.0'
address:
type: object
properties:
street:
type: string
example: 'Hauptstrasse 45'
postal_code:
type: string
example: '6260'
city:
type: string
example: Reiden
solar_roofs:
type: array
example:
-
attributes:
building_id: '229760'
suitability: high
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: high
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
solar_facades:
type: array
example:
-
attributes:
building_id: '229760'
suitability: medium
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: medium
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
coordinates:
type: object
properties:
east:
type: number
example: 2680000.0
north:
type: number
example: 1240000.0
coordinates_wgs84:
type: object
properties:
lat:
type: number
example: 47.3769
lng:
type: number
example: 8.5417
created_at:
type: string
example: '2025-01-01T00:00:00+00:00'
updated_at:
type: string
example: '2025-01-01T00:00:00+00:00'
tags:
- 'Municipal Properties'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
nullable: true
postal_code:
type: number
description: ''
example: 4326.41688
nullable: true
lat:
type: number
description: 'This field is required when lng or radius is present. Must be between -90 and 90.'
example: -90
nullable: true
lng:
type: number
description: 'This field is required when lat or radius is present. Must be between -180 and 180.'
example: -180
nullable: true
east:
type: number
description: 'This field is required when north or radius is present.'
example: 4326.41688
nullable: true
north:
type: number
description: 'This field is required when east or radius is present.'
example: 4326.41688
nullable: true
radius:
type: number
description: 'Must be at least 1. Must not be greater than 50000.'
example: 17
nullable: true
status:
type: string
description: ''
example: confirmed
enum:
- candidate
- confirmed
nullable: true
/api/water-supply-buildings:
get:
summary: 'List water supply buildings'
operationId: listWaterSupplyBuildings
description: "Returns a list of water supply buildings (Wasserversorgung) with various filtering options.\nYou can filter by municipality (BFS number), postal code, status, or search within a radius using coordinates.\nCoordinates are taken directly from `gwr_buildings.GKODE` (Easting) and `gwr_buildings.GKODN` (Northing)."
parameters:
-
in: query
name: municipality
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
required: false
schema:
type: integer
description: 'Filter by municipality BFS number (Gemeindenummer).'
example: 261
-
in: query
name: postal_code
description: 'Filter by postal code (PLZ).'
example: 8001
required: false
schema:
type: integer
description: 'Filter by postal code (PLZ).'
example: 8001
-
in: query
name: status
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
required: false
schema:
type: string
description: 'Filter by status. Options: `candidate`, `confirmed`.'
example: confirmed
-
in: query
name: lat
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
required: false
schema:
type: number
description: 'Latitude (WGS84) for radius search. Required together with `lng` and `radius`.'
example: 47.3769
-
in: query
name: lng
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
required: false
schema:
type: number
description: 'Longitude (WGS84) for radius search. Required together with `lat` and `radius`.'
example: 8.5417
-
in: query
name: radius
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
required: false
schema:
type: number
description: 'Search radius in meters (WGS84). Required together with `lat` and `lng`. Min: 1, Max: 50000.'
example: 1000.0
-
in: query
name: east
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
required: false
schema:
type: number
description: 'Easting (CH1903+) for radius search. Required together with `north` and `radius`.'
example: 2680000.0
-
in: query
name: north
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
required: false
schema:
type: number
description: 'Northing (CH1903+) for radius search. Required together with `east` and `radius`.'
example: 1240000.0
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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.0
north: 1240000.0
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'
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
id:
type: integer
example: 1
egid:
type: string
example: '1234567890'
status:
type: string
example: confirmed
building:
type: object
properties:
egid:
type: string
example: '1234567890'
gbez:
type: string
example: Wasserwerk
ggdenr:
type: string
example: '261'
ggdename:
type: string
example: Zürich
egrid:
type: string
example: '2680000.0,1240000.0'
address:
type: object
properties:
street:
type: string
example: 'Hauptstrasse 45'
postal_code:
type: string
example: '6260'
city:
type: string
example: Reiden
solar_roofs:
type: array
example:
-
attributes:
building_id: '229760'
suitability: high
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: high
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
solar_facades:
type: array
example:
-
attributes:
building_id: '229760'
suitability: medium
geometry:
rings:
-
-
- 2640325.75
- 1232914.625
items:
type: object
properties:
attributes:
type: object
properties:
building_id:
type: string
example: '229760'
suitability:
type: string
example: medium
geometry:
type: object
properties:
rings:
type: array
example:
- [[2640325.75, 1232914.625]]
items:
type: array
coordinates:
type: object
properties:
east:
type: number
example: 2680000.0
north:
type: number
example: 1240000.0
coordinates_wgs84:
type: object
properties:
lat:
type: number
example: 47.3769
lng:
type: number
example: 8.5417
created_at:
type: string
example: '2025-01-01T00:00:00+00:00'
updated_at:
type: string
example: '2025-01-01T00:00:00+00:00'
tags:
- 'Water Supply Buildings'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
municipality:
type: number
description: ''
example: 4326.41688
nullable: true
postal_code:
type: number
description: ''
example: 4326.41688
nullable: true
lat:
type: number
description: 'This field is required when lng or radius is present. Must be between -90 and 90.'
example: -90
nullable: true
lng:
type: number
description: 'This field is required when lat or radius is present. Must be between -180 and 180.'
example: -180
nullable: true
east:
type: number
description: 'This field is required when north or radius is present.'
example: 4326.41688
nullable: true
north:
type: number
description: 'This field is required when east or radius is present.'
example: 4326.41688
nullable: true
radius:
type: number
description: 'Must be at least 1. Must not be greater than 50000.'
example: 17
nullable: true
status:
type: string
description: ''
example: confirmed
enum:
- candidate
- confirmed
nullable: true
/api/eic-codes:
get:
summary: 'List EIC codes'
operationId: listEICCodes
description: "Returns a paginated list of Energy Identification Codes (EIC) published\nby Swissgrid (Swiss EIC Issuing Office, code 12). Covers all code types:\nA (substation), T (tieline), V (location), W (resource object),\nX (party / energy community), Y (area), Z (metering point)."
parameters:
-
in: query
name: type
description: 'Filter by code type. Options: A, T, V, W, X, Y, Z.'
example: X
required: false
schema:
type: string
description: 'Filter by code type. Options: A, T, V, W, X, Y, Z.'
example: X
-
in: query
name: source_list
description: '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
required: false
schema:
type: string
description: '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
-
in: query
name: function
description: 'Filter by function (exact match, e.g. LEG, vZEV, ZEV, Consumer).'
example: LEG
required: false
schema:
type: string
description: 'Filter by function (exact match, e.g. LEG, vZEV, ZEV, Consumer).'
example: LEG
-
in: query
name: search
description: 'Search in EIC, display name, company and city.'
example: Musterhausen
required: false
schema:
type: string
description: 'Search in EIC, display name, company and city.'
example: Musterhausen
-
in: query
name: zip
description: 'Filter by ZIP code.'
example: '3011'
required: false
schema:
type: string
description: 'Filter by ZIP code.'
example: '3011'
-
in: query
name: include_removed
description: 'Include codes no longer present in the current Swissgrid list. Default: false.'
example: false
required: false
schema:
type: boolean
description: 'Include codes no longer present in the current Swissgrid list. Default: false.'
example: false
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 100.'
example: 100
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
data:
type: array
example:
-
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'
items:
type: object
properties:
eic:
type: string
example: 12X-0000002029-F
code_type:
type: string
example: X
source_list:
type: string
example: x-codes-energycommunity
display_name:
type: string
example: ENERGO-CO
functions:
type: array
example:
- Consumer
items:
type: string
company:
type: string
example: energo
zip:
type: string
example: '6331'
city:
type: string
example: Hünenberg
registered_at:
type: string
example: '2019-06-27'
media:
type: string
example: null
nullable: true
comment:
type: string
example: null
nullable: true
is_active:
type: boolean
example: true
removed_at:
type: string
example: null
nullable: true
first_seen_at:
type: string
example: '2026-07-14T03:30:00+02:00'
last_seen_at:
type: string
example: '2026-07-14T03:30:00+02:00'
links:
type: object
properties:
first:
type: string
example: ...
last:
type: string
example: ...
prev:
type: string
example: null
nullable: true
next:
type: string
example: ...
meta:
type: object
properties:
current_page:
type: integer
example: 1
from:
type: integer
example: 1
last_page:
type: integer
example: 4
per_page:
type: integer
example: 100
to:
type: integer
example: 100
total:
type: integer
example: 385
tags:
- 'EIC Codes'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
type:
type: string
description: ''
example: t
enum:
- A
- T
- V
- W
- X
- 'Y'
- Z
- a
- t
- v
- w
- x
- 'y'
- z
nullable: true
source_list:
type: string
description: ''
example: w-codes
enum:
- a-codes
- t-codes
- v-codes
- w-codes
- x-codes
- x-codes-energycommunity
- y-codes
- z-codes
nullable: true
function:
type: string
description: 'Must not be greater than 100 characters.'
example: b
nullable: true
search:
type: string
description: 'Must not be greater than 100 characters.'
example: 'n'
nullable: true
zip:
type: string
description: 'Must not be greater than 16 characters.'
example: gzmiyvdljnikhway
nullable: true
include_removed:
type: boolean
description: ''
example: true
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 18
nullable: true
/api/eic-codes/meta:
get:
summary: 'Get sync metadata'
operationId: getSyncMetadata
description: "Returns the available code types with counts and the last successful\nsynchronisation per Swissgrid source list."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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
properties:
types:
type: array
example:
-
code_type: X
total: 2100
active: 2050
items:
type: object
properties:
code_type:
type: string
example: X
total:
type: integer
example: 2100
active:
type: integer
example: 2050
lists:
type: array
example:
-
source_list: x-codes-energycommunity
code_type: X
last_synced_at: '2026-07-14T03:30:12+02:00'
rows_total: 384
items:
type: object
properties:
source_list:
type: string
example: x-codes-energycommunity
code_type:
type: string
example: X
last_synced_at:
type: string
example: '2026-07-14T03:30:12+02:00'
rows_total:
type: integer
example: 384
tags:
- 'EIC Codes'
'/api/eic-codes/{eic}':
get:
summary: 'Get a single EIC code'
operationId: getASingleEICCode
description: 'Returns a single Energy Identification Code by its EIC identifier.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
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'
properties:
eic:
type: string
example: 12X-0000002029-F
code_type:
type: string
example: X
source_list:
type: string
example: x-codes-energycommunity
display_name:
type: string
example: ENERGO-CO
functions:
type: array
example:
- Consumer
items:
type: string
company:
type: string
example: energo
zip:
type: string
example: '6331'
city:
type: string
example: Hünenberg
registered_at:
type: string
example: '2019-06-27'
media:
type: string
example: null
nullable: true
comment:
type: string
example: null
nullable: true
is_active:
type: boolean
example: true
removed_at:
type: string
example: null
nullable: true
first_seen_at:
type: string
example: '2026-07-14T03:30:00+02:00'
last_seen_at:
type: string
example: '2026-07-14T03:30:00+02:00'
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'EIC-Code nicht gefunden.'
properties:
message:
type: string
example: 'EIC-Code nicht gefunden.'
tags:
- 'EIC Codes'
parameters:
-
in: path
name: eic
description: 'The EIC identifier.'
example: 12X-0000002029-F
required: true
schema:
type: string
/api/user:
get:
summary: ''
operationId: getApiUser
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
/api/health:
get:
summary: ''
operationId: getApiHealth
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: ok
time: '2026-08-21T12:50:52+00:00'
properties:
status:
type: string
example: ok
time:
type: string
example: '2026-08-21T12:50:52+00:00'
tags:
- Endpoints
'/api/buildings/{egid}/consumption':
get:
summary: ''
operationId: getApiBuildingsEgidConsumption
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
post:
summary: ''
operationId: postApiBuildingsEgidConsumption
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
heating_system:
type: string
description: ''
example: direct_electric
enum:
- luft_wp
- sole_wp
- direct_electric
- non_electric
nullable: true
hot_water_system:
type: string
description: ''
example: other
enum:
- luft_wp
- sole_wp
- direct_electric
- from_heating
- other
nullable: true
age_tier:
type: string
description: ''
example: old
enum:
- old
- mid
- new
nullable: true
effective_area:
type: number
description: 'Must be at least 10. Must not be greater than 50000.'
example: 1
nullable: true
parameters:
-
in: path
name: egid
description: ''
example: architecto
required: true
schema:
type: string
/api/network-topology/coverage-data:
get:
summary: ''
operationId: getApiNetworkTopologyCoverageData
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
view_mode:
type: string
description: ''
example: vk
enum:
- vk
- ne6
- ne4
- municipality
vk_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne6_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne4_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
bfs_number:
type: number
description: ''
example: 4326.41688
nullable: true
show_ne4:
type: boolean
description: ''
example: false
nullable: true
show_ne6:
type: boolean
description: ''
example: true
nullable: true
show_vk:
type: boolean
description: ''
example: true
nullable: true
show_buildings:
type: boolean
description: ''
example: true
nullable: true
building_limit:
type: integer
description: 'Must be at least 10. Must not be greater than 5000.'
example: 17
nullable: true
include_epa:
type: boolean
description: ''
example: false
nullable: true
required:
- view_mode
/api/network-topology/data-version:
get:
summary: ''
operationId: getApiNetworkTopologyDataVersion
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
/api/network-topology/nodes:
post:
summary: 'Create a new node (NE4, NE6 or VK).'
operationId: createANewNodeNE4NE6OrVK
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
node_type:
type: string
description: ''
example: ne6
enum:
- ne4
- ne6
- vk
identifier:
type: string
description: 'Must not be greater than 255 characters.'
example: b
parent_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
latitude:
type: number
description: 'Must be between -90 and 90.'
example: -89
nullable: true
longitude:
type: number
description: 'Must be between -180 and 180.'
example: -180
nullable: true
address:
type: string
description: 'Must not be greater than 255 characters.'
example: z
nullable: true
trafo_egid:
type: string
description: 'Must not be greater than 32 characters.'
example: m
nullable: true
is_active:
type: boolean
description: ''
example: false
nullable: true
metadata:
type: object
description: ''
example: null
properties:
custom_label:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
bfs_number:
type: integer
description: 'Must be at least 1. Must not be greater than 9999.'
example: 8
nullable: true
network_level:
type: string
description: 'Must not be greater than 32 characters.'
example: v
nullable: true
capacity_kva:
type: number
description: 'Must be at least 0.'
example: 42
nullable: true
egrid:
type: string
description: 'Must not be greater than 32 characters.'
example: l
nullable: true
nullable: true
required:
- node_type
- identifier
get:
summary: 'List nodes, optionally filtered by grid operator, type and free-text search.'
operationId: listNodesOptionallyFilteredByGridOperatorTypeAndFreeTextSearch
description: ''
parameters:
-
in: query
name: grid_operator_id
description: 'Filter to a specific VNB. Required for non-admin users.'
example: 12
required: false
schema:
type: integer
description: 'Filter to a specific VNB. Required for non-admin users.'
example: 12
-
in: query
name: node_type
description: 'Filter by node type (ne4, ne6, vk).'
example: ne6
required: false
schema:
type: string
description: 'Filter by node type (ne4, ne6, vk).'
example: ne6
-
in: query
name: bfs_number
description: 'Filter by BFS municipality number stored in metadata.bfs_number.'
example: 4241
required: false
schema:
type: integer
description: 'Filter by BFS municipality number stored in metadata.bfs_number.'
example: 4241
-
in: query
name: q
description: 'Search in identifier and metadata.custom_label.'
example: TS-Hauptstrasse
required: false
schema:
type: string
description: 'Search in identifier and metadata.custom_label.'
example: TS-Hauptstrasse
-
in: query
name: per_page
description: 'Page size (1-200, default 50).'
example: 50
required: false
schema:
type: integer
description: 'Page size (1-200, default 50).'
example: 50
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
node_type:
type: string
description: ''
example: vk
enum:
- ne4
- ne6
- vk
nullable: true
bfs_number:
type: integer
description: 'Must be at least 1. Must not be greater than 9999.'
example: 22
nullable: true
q:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 200.'
example: 16
nullable: true
'/api/network-topology/nodes/{id}':
get:
summary: 'Show a single node.'
operationId: showASingleNode
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
put:
summary: 'Update an existing node (e.g. rename, change parent, edit label).'
operationId: updateAnExistingNodeegRenameChangeParentEditLabel
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
node_type:
type: string
description: ''
example: ne4
enum:
- ne4
- ne6
- vk
identifier:
type: string
description: 'Must not be greater than 255 characters.'
example: b
parent_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
latitude:
type: number
description: 'Must be between -90 and 90.'
example: -89
nullable: true
longitude:
type: number
description: 'Must be between -180 and 180.'
example: -180
nullable: true
address:
type: string
description: 'Must not be greater than 255 characters.'
example: z
nullable: true
trafo_egid:
type: string
description: 'Must not be greater than 32 characters.'
example: m
nullable: true
is_active:
type: boolean
description: ''
example: true
metadata:
type: object
description: ''
example: null
properties:
custom_label:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
bfs_number:
type: integer
description: 'Must be at least 1. Must not be greater than 9999.'
example: 8
nullable: true
network_level:
type: string
description: 'Must not be greater than 32 characters.'
example: v
nullable: true
capacity_kva:
type: number
description: 'Must be at least 0.'
example: 42
nullable: true
egrid:
type: string
description: 'Must not be greater than 32 characters.'
example: l
nullable: true
nullable: true
delete:
summary: 'Delete a node. Refuses if the node still has children or topology references.'
operationId: deleteANodeRefusesIfTheNodeStillHasChildrenOrTopologyReferences
description: ''
parameters: []
responses: { }
tags:
- Endpoints
parameters:
-
in: path
name: id
description: 'The ID of the node.'
example: '564'
required: true
schema:
type: string
/api/network-topology/assignments:
post:
summary: "Create an EGID -> node assignment. Fails if a row for the EGID already\nexists; use PUT in that case."
operationId: createAnEGIDNodeAssignmentFailsIfARowForTheEGIDAlreadyExistsUsePUTInThatCase
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
egid:
type: string
description: 'Must match an existing stored value. Must not be greater than 32 characters.'
example: b
ne4_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne6_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
vk_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
is_muffennetz:
type: boolean
description: ''
example: false
nullable: true
autopopulate_parents:
type: boolean
description: ''
example: false
nullable: true
required:
- egid
get:
summary: 'List assignments scoped to one or more grid operators.'
operationId: listAssignmentsScopedToOneOrMoreGridOperators
description: ''
parameters:
-
in: query
name: grid_operator_id
description: 'Filter by VNB. Required for non-admin users.'
example: 12
required: false
schema:
type: integer
description: 'Filter by VNB. Required for non-admin users.'
example: 12
-
in: query
name: egid
description: 'Filter by exact EGID.'
example: '421158'
required: false
schema:
type: string
description: 'Filter by exact EGID.'
example: '421158'
-
in: query
name: ne6_node_id
description: 'Filter by transformer node.'
example: 87
required: false
schema:
type: integer
description: 'Filter by transformer node.'
example: 87
-
in: query
name: per_page
description: 'Page size (1-200, default 50).'
example: 16
required: false
schema:
type: integer
description: 'Page size (1-200, default 50).'
example: 16
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
egid:
type: string
description: 'Must not be greater than 32 characters.'
example: 'n'
nullable: true
ne6_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
bfs_number:
type: integer
description: 'Must be at least 1. Must not be greater than 9999.'
example: 22
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 200.'
example: 7
nullable: true
'/api/network-topology/assignments/{id}':
get:
summary: ''
operationId: getApiNetworkTopologyAssignmentsId
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
put:
summary: 'Update an existing assignment (move a building to another transformer, etc.).'
operationId: updateAnExistingAssignmentmoveABuildingToAnotherTransformerEtc
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
ne4_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne6_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
vk_node_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
grid_operator_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
is_muffennetz:
type: boolean
description: ''
example: true
autopopulate_parents:
type: boolean
description: ''
example: true
delete:
summary: ''
operationId: deleteApiNetworkTopologyAssignmentsId
description: ''
parameters: []
responses: { }
tags:
- Endpoints
parameters:
-
in: path
name: id
description: 'The ID of the assignment.'
example: '564'
required: true
schema:
type: string
'/api/osb/{path}':
get:
summary: 'Proxy all requests to OSB API.'
operationId: proxyAllRequestsToOSBAPI
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
parameters:
-
in: path
name: path
description: 'Optional parameter.'
required: true
schema:
type: string
examples:
omitted:
summary: 'When the value is omitted'
value: ''
present:
summary: 'When the value is present'
value: '|{+-0p'
'/api/osb-v2/{path}':
get:
summary: 'Proxy all requests to OSB API.'
operationId: proxyAllRequestsToOSBAPI
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- Endpoints
parameters:
-
in: path
name: path
description: 'Optional parameter.'
required: true
schema:
type: string
examples:
omitted:
summary: 'When the value is omitted'
value: ''
present:
summary: 'When the value is present'
value: '|{+-0p'
/api/electricity-labels/operators:
get:
summary: 'List operators with their latest electricity label.'
operationId: listOperatorsWithTheirLatestElectricityLabel
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
'/api/electricity-labels/operators/{chUid}':
get:
summary: 'Show all years of labels for a single operator (resolved via ch_uid).'
operationId: showAllYearsOfLabelsForASingleOperatorresolvedViaChUid
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
parameters:
-
in: path
name: chUid
description: ''
example: architecto
required: true
schema:
type: string
'/api/electricity-labels/operators/{chUid}/{year}':
get:
summary: 'One label (Lieferantenmix) for an operator + delivery year.'
operationId: oneLabelLieferantenmixForAnOperator+DeliveryYear
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
parameters:
-
in: path
name: chUid
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: year
description: ''
example: '564'
required: true
schema:
type: string
'/api/electricity-labels/operators/{chUid}/{year}/products/{product}':
get:
summary: 'Single product mix for an operator/year/product (phase 2 placeholder).'
operationId: singleProductMixForAnOperatoryearproductphase2Placeholder
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
parameters:
-
in: path
name: chUid
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: year
description: ''
example: '564'
required: true
schema:
type: string
-
in: path
name: product
description: 'The product.'
example: architecto
required: true
schema:
type: string
'/api/electricity-labels/by-egid/{egid}':
get:
summary: "Look up the label for the building's default supplier (= VNB)."
operationId: lookUpTheLabelForTheBuildingsDefaultSupplierVNB
description: "Resolves EGID -> NetworkTopology -> grid_operator_id -> latest label.\nReturns a disclaimer that this is the default supplier; customers with\nfree choice (> 100 MWh/year) may use a different supplier."
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
parameters:
-
in: path
name: egid
description: ''
example: architecto
required: true
schema:
type: string
'/api/electricity-labels/by-municipality/{bfsNumber}':
get:
summary: "Aggregate by municipality (BFS number) - returns labels for all suppliers\nwhose service area touches this municipality (resolved via network_topology)."
operationId: aggregateByMunicipalityBFSNumberReturnsLabelsForAllSuppliersWhoseServiceAreaTouchesThisMunicipalityresolvedViaNetworkTopology
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
parameters:
-
in: path
name: bfsNumber
description: ''
example: '564'
required: true
schema:
type: string
/api/electricity-labels/aggregate:
get:
summary: 'Weighted CH-wide or filtered aggregate.'
operationId: weightedCHWideOrFilteredAggregate
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'BFE Stromkennzeichnung'
/api/economic-catalog/products:
get:
summary: 'List catalog products.'
operationId: listCatalogProducts
description: ''
parameters:
-
in: query
name: supplier
description: 'Filter by supplier slug.'
example: solarmarkt
required: false
schema:
type: string
description: 'Filter by supplier slug.'
example: solarmarkt
-
in: query
name: kind
description: 'Filter by battery kind. Options: battery_module, bcu, inverter, accessory, dummy, unknown.'
example: battery_module
required: false
schema:
type: string
description: 'Filter by battery kind. Options: battery_module, bcu, inverter, accessory, dummy, unknown.'
example: battery_module
-
in: query
name: manufacturer
description: 'Filter by manufacturer name (exact match).'
example: BYD
required: false
schema:
type: string
description: 'Filter by manufacturer name (exact match).'
example: BYD
-
in: query
name: search
description: 'Search name or article number (LIKE).'
example: HVS
required: false
schema:
type: string
description: 'Search name or article number (LIKE).'
example: HVS
-
in: query
name: min_kwh
description: 'Minimum total kWh.'
example: 5.0
required: false
schema:
type: number
description: 'Minimum total kWh.'
example: 5.0
-
in: query
name: max_kwh
description: 'Maximum total kWh. Must be >= min_kwh.'
example: 20.0
required: false
schema:
type: number
description: 'Maximum total kWh. Must be >= min_kwh.'
example: 20.0
-
in: query
name: include_discontinued
description: 'Include discontinued products. Default: false.'
example: false
required: false
schema:
type: boolean
description: 'Include discontinued products. Default: false.'
example: false
-
in: query
name: per_page
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
required: false
schema:
type: integer
description: 'Number of items per page. Min: 1, Max: 1000. Default: 200.'
example: 200
-
in: query
name: page
description: 'Page number. Default: 1.'
example: 1
required: false
schema:
type: integer
description: 'Page number. Default: 1.'
example: 1
-
in: query
name: lang
description: 'Language for code labels. Options: de, fr, it. Default: de.'
example: de
required: false
schema:
type: string
description: 'Language for code labels. Options: de, fr, it. Default: de.'
example: de
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Economic Catalog'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
supplier:
type: string
description: 'Must contain only letters, numbers, dashes and underscores.'
example: bng-zmi_y
nullable: true
kind:
type: string
description: ''
example: battery_module
enum:
- battery_module
- bcu
- inverter
- accessory
- dummy
- unknown
nullable: true
manufacturer:
type: string
description: 'Must not be greater than 120 characters.'
example: v
nullable: true
search:
type: string
description: 'Must not be greater than 120 characters.'
example: d
nullable: true
min_kwh:
type: number
description: 'Must be at least 0.'
example: 37
nullable: true
max_kwh:
type: number
description: 'Must be at least 0.'
example: 9
nullable: true
include_discontinued:
type: boolean
description: ''
example: false
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 17
nullable: true
lang:
type: string
description: ''
example: de
enum:
- de
- fr
- it
nullable: true
'/api/economic-catalog/products/{id}':
get:
summary: 'Show a single catalog product with its full snapshot history.'
operationId: showASingleCatalogProductWithItsFullSnapshotHistory
description: ''
parameters:
-
in: query
name: lang
description: 'Language for code labels. Options: de, fr, it. Default: de.'
example: de
required: false
schema:
type: string
description: 'Language for code labels. Options: de, fr, it. Default: de.'
example: de
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Economic Catalog'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
lang:
type: string
description: ''
example: fr
enum:
- de
- fr
- it
nullable: true
parameters:
-
in: path
name: id
description: 'The ID of the product.'
example: 1
required: true
schema:
type: integer
-
in: path
name: product
description: 'integer The product ID.'
example: '42'
required: true
schema:
type: string
/api/economic-catalog/manufacturers:
get:
summary: 'List distinct manufacturers, optionally scoped by supplier.'
operationId: listDistinctManufacturersOptionallyScopedBySupplier
description: ''
parameters:
-
in: query
name: supplier
description: 'Filter by supplier slug.'
example: solarmarkt
required: false
schema:
type: string
description: 'Filter by supplier slug.'
example: solarmarkt
-
in: query
name: lang
description: 'Language. Default: de.'
example: de
required: false
schema:
type: string
description: 'Language. Default: de.'
example: de
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Economic Catalog'
/api/economic-catalog/suppliers:
get:
summary: 'List catalog suppliers.'
operationId: listCatalogSuppliers
description: ''
parameters:
-
in: query
name: lang
description: 'Language. Default: de.'
example: de
required: false
schema:
type: string
description: 'Language. Default: de.'
example: de
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Economic Catalog'
'/api/buildings/{egid}/electricity-plants':
get:
summary: 'Get combined building and electricity production plants data'
operationId: getCombinedBuildingAndElectricityProductionPlantsData
description: ''
parameters:
-
in: query
name: plant_type
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
required: false
schema:
type: string
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
parameters:
-
in: path
name: egid
description: 'Optional parameter. Building EGID.'
required: true
schema:
type: string
examples:
omitted:
summary: 'When the value is omitted'
value: ''
present:
summary: 'When the value is present'
value: '123456'
/api/electricity-plants:
get:
summary: 'Get electricity production plants for a building by EGID'
operationId: getElectricityProductionPlantsForABuildingByEGID
description: ''
parameters:
-
in: query
name: egid
description: 'Building EGID.'
example: '123456'
required: false
schema:
type: string
description: 'Building EGID.'
example: '123456'
-
in: query
name: plant_type
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
required: false
schema:
type: string
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
/api/electricity-plants/search:
get:
summary: 'Search electricity production plants by location'
operationId: searchElectricityProductionPlantsByLocation
description: ''
parameters:
-
in: query
name: municipality
description: 'Municipality name.'
example: Zürich
required: false
schema:
type: string
description: 'Municipality name.'
example: Zürich
-
in: query
name: post_code
description: 'Postal code.'
example: 8001
required: false
schema:
type: integer
description: 'Postal code.'
example: 8001
-
in: query
name: bfs_number
description: 'BFS municipality number.'
example: '261'
required: false
schema:
type: string
description: 'BFS municipality number.'
example: '261'
-
in: query
name: plant_type
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
required: false
schema:
type: string
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
/api/electricity-plants/by-municipality:
get:
summary: 'List all electricity production plants of a municipality with coordinates.'
operationId: listAllElectricityProductionPlantsOfAMunicipalityWithCoordinates
description: "Designed for map rendering: returns every plant of a municipality together\nwith CH1903+ and WGS84 coordinates (reconstructed from gwr_buildings via\nEGID when the BFE source is incomplete)."
parameters:
-
in: query
name: bfs_number
description: 'Municipality BFS number. Required.'
example: '2827'
required: false
schema:
type: string
description: 'Municipality BFS number. Required.'
example: '2827'
-
in: query
name: plant_type
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass).'
example: photovoltaic
required: false
schema:
type: string
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass).'
example: photovoltaic
-
in: query
name: only_with_coordinates
description: 'If true (default) only plants with WGS84 coordinates are returned.'
example: true
required: false
schema:
type: boolean
description: 'If true (default) only plants with WGS84 coordinates are returned.'
example: true
-
in: query
name: min_power_kw
description: 'Optional minimum total power in kW.'
example: 0.0
required: false
schema:
type: number
description: 'Optional minimum total power in kW.'
example: 0.0
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
'/api/electricity-plants/{xtf_id}':
get:
summary: 'Get specific electricity production plant by XTF-ID'
operationId: getSpecificElectricityProductionPlantByXTFID
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
parameters:
-
in: path
name: xtf_id
description: 'Optional parameter. XTF-ID of the plant.'
required: true
schema:
type: string
examples:
omitted:
summary: 'When the value is omitted'
value: ''
present:
summary: 'When the value is present'
value: ch.bfe.epa.123456
'/api/municipalities/{bfs_number}/electricity-plant-statistics':
get:
summary: 'Get electricity production plant statistics for a municipality'
operationId: getElectricityProductionPlantStatisticsForAMunicipality
description: ''
parameters:
-
in: query
name: plant_type
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
required: false
schema:
type: string
description: 'Optional filter by plant type (photovoltaic, hydro, wind, biomass, etc.).'
example: photovoltaic
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Electricity Production Plants'
parameters:
-
in: path
name: bfs_number
description: 'Optional parameter. BFS municipality number.'
required: true
schema:
type: string
examples:
omitted:
summary: 'When the value is omitted'
value: ''
present:
summary: 'When the value is present'
value: '261'
'/api/hkn-rates/operators/{chUid}':
get:
summary: 'List HKN compensation rates for a grid operator'
operationId: listHKNCompensationRatesForAGridOperator
description: "Returns the manually maintained HKN compensation rates for a single grid operator,\nfiltered by validity period (default: rates valid today). Use `include_history=true`\nto retrieve all historical entries."
parameters:
-
in: query
name: valid_at
description: 'date Filter rates valid on this date (ISO 8601). Default: today.'
example: '2026-01-01'
required: false
schema:
type: string
description: 'date Filter rates valid on this date (ISO 8601). Default: today.'
example: '2026-01-01'
-
in: query
name: energy_source
description: 'Filter by energy source. Options: photovoltaik, wasserkraft, wind, biomasse, bhkw, sonstige.'
example: photovoltaik
required: false
schema:
type: string
description: 'Filter by energy source. Options: photovoltaik, wasserkraft, wind, biomasse, bhkw, sonstige.'
example: photovoltaik
-
in: query
name: capacity_kva
description: 'Filter rates whose kVA range covers this plant capacity (min < capacity <= max).'
example: 25.0
required: false
schema:
type: number
description: 'Filter rates whose kVA range covers this plant capacity (min < capacity <= max).'
example: 25.0
-
in: query
name: plant_size
description: 'Legacy filter by plant size class (matches rates whose boundaries correspond to the 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
required: false
schema:
type: string
description: 'Legacy filter by plant size class (matches rates whose boundaries correspond to the 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
-
in: query
name: include_history
description: 'If true, returns all rates regardless of validity. Default: false.'
example: false
required: false
schema:
type: boolean
description: 'If true, returns all rates regardless of validity. Default: false.'
example: false
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'HKN Compensation Rates'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
valid_at:
type: string
description: 'Must be a valid date.'
example: '2026-08-21T12:50:53'
nullable: true
energy_source:
type: string
description: ''
example: biomasse
enum:
- photovoltaik
- wasserkraft
- wind
- biomasse
- bhkw
- sonstige
nullable: true
capacity_kva:
type: number
description: 'Must be at least 0.'
example: 27
nullable: true
plant_size:
type: string
description: ''
example: above_1000_kva
enum:
- alle
- up_to_30_kva
- from_30_to_100_kva
- from_100_to_1000_kva
- above_1000_kva
nullable: true
include_history:
type: boolean
description: ''
example: true
nullable: true
post:
summary: 'Create an HKN compensation rate for a grid operator'
operationId: createAnHKNCompensationRateForAGridOperator
description: ''
parameters: []
responses: { }
tags:
- 'HKN Compensation Rates'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
energy_source:
type: string
description: 'Energy source. Options: photovoltaik, wasserkraft, wind, biomasse, bhkw, sonstige.'
example: photovoltaik
plant_size_min_kva:
type: number
description: 'Lower kVA boundary (exclusive), null = unbounded.'
example: 2.0
nullable: true
plant_size_max_kva:
type: number
description: 'Upper kVA boundary (inclusive), null = unbounded.'
example: 30.0
nullable: true
plant_size:
type: string
description: 'Legacy plant size class, mapped to kVA boundaries when the boundary fields are absent. Options: alle, up_to_30_kva, from_30_to_100_kva, from_100_to_1000_kva, above_1000_kva.'
example: up_to_30_kva
nullable: true
rate_rappen_per_kwh:
type: number
description: 'Compensation in Rp/kWh.'
example: 4.5
valid_from:
type: date
description: 'Start of validity (ISO 8601).'
example: '2026-01-01'
valid_to:
type: date
description: 'End of validity, null = open-ended.'
example: '2026-12-31'
nullable: true
is_final:
type: boolean
description: 'Whether the rate is final (published); false marks a provisional value awaiting quarterly publication. Default: true.'
example: true
nullable: true
required:
- energy_source
- rate_rappen_per_kwh
- valid_from
parameters:
-
in: path
name: chUid
description: 'Swiss UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/hkn-rates/operators/{chUid}/rates/{id}':
put:
summary: 'Update an HKN compensation rate'
operationId: updateAnHKNCompensationRate
description: ''
parameters: []
responses: { }
tags:
- 'HKN Compensation Rates'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
energy_source:
type: string
description: ''
example: wind
enum:
- photovoltaik
- wasserkraft
- wind
- biomasse
- bhkw
- sonstige
plant_size_min_kva:
type: number
description: 'Must be at least 0. Must not be greater than 999999.99.'
example: 1
nullable: true
plant_size_max_kva:
type: number
description: 'Must be at least 0. Must not be greater than 999999.99.'
example: 22
nullable: true
plant_size:
type: string
description: ''
example: from_100_to_1000_kva
enum:
- alle
- up_to_30_kva
- from_30_to_100_kva
- from_100_to_1000_kva
- above_1000_kva
nullable: true
rate_rappen_per_kwh:
type: number
description: 'Must be at least 0. Must not be greater than 9999.9999.'
example: 7
valid_from:
type: string
description: 'Must be a valid date.'
example: '2026-08-21T12:50:53'
valid_to:
type: string
description: 'Must be a valid date.'
example: '2026-08-21T12:50:53'
nullable: true
is_final:
type: boolean
description: ''
example: true
delete:
summary: 'Delete an HKN compensation rate'
operationId: deleteAnHKNCompensationRate
description: ''
parameters: []
responses: { }
tags:
- 'HKN Compensation Rates'
parameters:
-
in: path
name: chUid
description: 'Swiss UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
-
in: path
name: id
description: 'ID of the HKN rate.'
example: 1
required: true
schema:
type: integer
'/api/hkn-rates/operators/{chUid}/settings':
put:
summary: 'Update HKN market settings for a grid operator'
operationId: updateHKNMarketSettingsForAGridOperator
description: "Maintains the operator-level HKN flags: whether the HKN compensation\nis market-dependent (set quarterly, provisional until published) and\nthe optional cap in Rp/kWh."
parameters: []
responses: { }
tags:
- 'HKN Compensation Rates'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
hkn_market_dependent:
type: boolean
description: 'Whether HKN compensation is set quarterly depending on market prices.'
example: true
hkn_cap_rappen_per_kwh:
type: number
description: 'Maximum HKN compensation in Rp/kWh, null = no cap.'
example: 2.0
nullable: true
parameters:
-
in: path
name: chUid
description: 'Swiss UID of the grid operator.'
example: CHE-108.954.688
required: true
schema:
type: string
'/api/municipalities/{bfs_number}/enrich':
post:
summary: 'Enrich all buildings in a municipality.'
operationId: enrichAllBuildingsInAMunicipality
description: "Triggers a background job that enriches building data including:\n- WGS84 coordinates (converted from CH1903+)\n- BDEW consumption profiles\n- Municipality names\n- Address data (via OSB API)"
parameters: []
responses: { }
tags:
- 'Municipality Enrichment'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
force:
type: boolean
description: 'Force re-enrichment even if already enriched. Default: false.'
example: false
parameters:
-
in: path
name: bfs_number
description: 'Municipality BFS number.'
example: 261
required: true
schema:
type: integer
'/api/municipalities/{bfs_number}/enrichment-status/{batch_id}':
get:
summary: 'Get the status of a municipality enrichment batch.'
operationId: getTheStatusOfAMunicipalityEnrichmentBatch
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Municipality Enrichment'
parameters:
-
in: path
name: bfs_number
description: 'Municipality BFS number.'
example: 261
required: true
schema:
type: integer
-
in: path
name: batch_id
description: 'Batch ID from enrich response.'
example: 9d4f8a3c-1b2e-4f5a-8c3d-9a7b6e4f2c1d
required: true
schema:
type: string
'/api/network-topology/hierarchy/{bfs_number}':
get:
summary: 'Get network topology hierarchy for a municipality.'
operationId: getNetworkTopologyHierarchyForAMunicipality
description: "Returns the full NE4 → NE6 → VK hierarchy with optional building data.\nDesigned for simulation seeder and external API consumers."
parameters:
-
in: query
name: include
description: 'Include additional data. Currently only "buildings" is supported.'
example: buildings
required: false
schema:
type: string
description: 'Include additional data. Currently only "buildings" is supported.'
example: buildings
-
in: query
name: ne4_id
description: 'Filter to a specific NE4 (substation) subtree.'
example: 1
required: false
schema:
type: integer
description: 'Filter to a specific NE4 (substation) subtree.'
example: 1
-
in: query
name: ne6_id
description: 'Filter to a specific NE6 (transformer) subtree.'
example: 5
required: false
schema:
type: integer
description: 'Filter to a specific NE6 (transformer) subtree.'
example: 5
-
in: query
name: cursor
description: 'Pagination cursor for buildings (base64 encoded).'
example: eyJlZ2lkIjoiMTIzNDU2In0=
required: false
schema:
type: string
description: 'Pagination cursor for buildings (base64 encoded).'
example: eyJlZ2lkIjoiMTIzNDU2In0=
-
in: query
name: limit
description: 'Number of buildings per page (1-500, default 100).'
example: 100
required: false
schema:
type: integer
description: 'Number of buildings per page (1-500, default 100).'
example: 100
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
include:
type: string
description: ''
example: buildings
enum:
- buildings
nullable: true
node_type:
type: string
description: ''
example: ne4
enum:
- ne4
- ne6
- vk
nullable: true
ne4_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne6_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
cursor:
type: string
description: ''
example: architecto
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 22
nullable: true
parameters:
-
in: path
name: bfs_number
description: 'int The municipality BFS number.'
example: 4241
required: true
schema:
type: integer
/api/network-topology/coverage-map:
get:
summary: 'Generate a coverage map image (SVG).'
operationId: generateACoverageMapImageSVG
description: "Returns an SVG image of the network topology coverage map.\nSupports three view modes: VK-centered (vZEV), NE6-centered (LEG 40%), or municipality."
parameters:
-
in: query
name: view_mode
description: 'string View mode: "vk", "ne6", or "municipality".'
example: vk
required: true
schema:
type: string
description: 'string View mode: "vk", "ne6", or "municipality".'
example: vk
-
in: query
name: vk_id
description: 'Required when view_mode is "vk". The VK node ID.'
example: 25
required: false
schema:
type: integer
description: 'Required when view_mode is "vk". The VK node ID.'
example: 25
-
in: query
name: ne6_id
description: 'Required when view_mode is "ne6". The NE6 node ID.'
example: 5
required: false
schema:
type: integer
description: 'Required when view_mode is "ne6". The NE6 node ID.'
example: 5
-
in: query
name: bfs_number
description: 'Required when view_mode is "municipality". The BFS number.'
example: 4241
required: false
schema:
type: integer
description: 'Required when view_mode is "municipality". The BFS number.'
example: 4241
-
in: query
name: width
description: 'Image width in pixels (400-4000, default 1200).'
example: 1200
required: false
schema:
type: integer
description: 'Image width in pixels (400-4000, default 1200).'
example: 1200
-
in: query
name: height
description: 'Image height in pixels (300-3000, default 800).'
example: 800
required: false
schema:
type: integer
description: 'Image height in pixels (300-3000, default 800).'
example: 800
-
in: query
name: show_ne4
description: 'Show NE4 polygons (default true).'
example: true
required: false
schema:
type: boolean
description: 'Show NE4 polygons (default true).'
example: true
-
in: query
name: show_ne6
description: 'Show NE6 polygons (default true).'
example: true
required: false
schema:
type: boolean
description: 'Show NE6 polygons (default true).'
example: true
-
in: query
name: show_vk
description: 'Show VK polygons (default true).'
example: true
required: false
schema:
type: boolean
description: 'Show VK polygons (default true).'
example: true
-
in: query
name: show_buildings
description: 'Show building markers (default true).'
example: true
required: false
schema:
type: boolean
description: 'Show building markers (default true).'
example: true
responses:
200:
description: ''
content:
text/plain:
schema:
type: string
example: 'SVG image data'
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Node not found'
properties:
message:
type: string
example: 'Node not found'
tags:
- 'Network Topology'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
view_mode:
type: string
description: ''
example: municipality
enum:
- vk
- ne6
- municipality
vk_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
ne6_id:
type: integer
description: 'Must match an existing stored value.'
example: 16
nullable: true
bfs_number:
type: number
description: ''
example: 4326.41688
nullable: true
width:
type: integer
description: 'Must be at least 400. Must not be greater than 4000.'
example: 17
nullable: true
height:
type: integer
description: 'Must be at least 300. Must not be greater than 3000.'
example: 15
nullable: true
show_ne4:
type: boolean
description: ''
example: false
nullable: true
show_ne6:
type: boolean
description: ''
example: true
nullable: true
show_vk:
type: boolean
description: ''
example: false
nullable: true
show_buildings:
type: boolean
description: ''
example: false
nullable: true
required:
- view_mode
/api/network-topology/lookup:
get:
summary: 'Look up topology data for a building by EGID.'
operationId: lookUpTopologyDataForABuildingByEGID
description: "Returns grid level, transformer info, power data, and LEG eligibility.\nSupports hybrid caching: checks local DB first, fetches from external API on miss.\n\nWhen the building's grid operator is known but its topology was never\nsynced, a background fetch is queued and HTTP 202 with\n`{\"status\": \"pending\", \"retry_after\": 15}` is returned; clients should\npoll the same endpoint until it resolves."
parameters:
-
in: query
name: egid
description: 'string The building EGID.'
example: '421158'
required: true
schema:
type: string
description: 'string The building EGID.'
example: '421158'
-
in: query
name: vnb
description: 'Optional VNB identifier (name or CH UID).'
example: ebl
required: false
schema:
type: string
description: 'Optional VNB identifier (name or CH UID).'
example: ebl
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
egid:
type: string
description: 'Must not be greater than 20 characters.'
example: bngzmiyvdljnikhw
vnb:
type: string
description: 'Must not be greater than 100 characters.'
example: a
nullable: true
required:
- egid
'/api/network-topology/transformer-peers/{egid}':
get:
summary: 'Get all buildings connected to the same transformer as the given EGID.'
operationId: getAllBuildingsConnectedToTheSameTransformerAsTheGivenEGID
description: "Returns buildings eligible for LEG 40% (same Trafokreis, no transformation needed).\nResults are filtered to the same municipality and limited for performance."
parameters:
-
in: query
name: vnb
description: 'Optional VNB identifier.'
example: ebl
required: false
schema:
type: string
description: 'Optional VNB identifier.'
example: ebl
-
in: query
name: limit
description: 'Max buildings to return (1-500, default 100). building_count remains the true total.'
example: 16
required: false
schema:
type: integer
description: 'Max buildings to return (1-500, default 100). building_count remains the true total.'
example: 16
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
vnb:
type: string
description: 'Must not be greater than 100 characters.'
example: b
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 22
nullable: true
parameters:
-
in: path
name: egid
description: 'string The building EGID.'
example: '421158'
required: true
schema:
type: string
'/api/network-topology/leg-area-peers/{egid}':
get:
summary: 'Get all buildings in the same LEG area as the given EGID.'
operationId: getAllBuildingsInTheSameLEGAreaAsTheGivenEGID
description: "Returns buildings eligible for LEG 20% (same substation area, with transformation).\nResults are filtered to the same municipality (Gemeinde-LEG scope) and limited."
parameters:
-
in: query
name: vnb
description: 'Optional VNB identifier.'
example: ebl
required: false
schema:
type: string
description: 'Optional VNB identifier.'
example: ebl
-
in: query
name: limit
description: 'Max buildings to return (1-500, default 100). building_count remains the true total.'
example: 16
required: false
schema:
type: integer
description: 'Max buildings to return (1-500, default 100). building_count remains the true total.'
example: 16
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
vnb:
type: string
description: 'Must not be greater than 100 characters.'
example: b
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 22
nullable: true
parameters:
-
in: path
name: egid
description: 'string The building EGID.'
example: '421158'
required: true
schema:
type: string
'/api/network-topology/leg-peers/{egid}':
get:
summary: 'Combined LEG-20 / LEG-40 / vZEV peer lookup for a single building.'
operationId: combinedLEG20LEG40VZEVPeerLookupForASingleBuilding
description: "Returns all three peer blocks in a single response so a client can\nscan a building with one HTTP roundtrip instead of three. The shape\nmirrors the individual endpoints; each block carries an explicit\n`leg_type` discriminator (`leg_20` / `leg_40` / `vzev`)."
parameters:
-
in: query
name: vnb
description: 'Optional VNB identifier.'
example: ebl
required: false
schema:
type: string
description: 'Optional VNB identifier.'
example: ebl
-
in: query
name: limit
description: 'Max buildings per block to return (1-500, default 100).'
example: 16
required: false
schema:
type: integer
description: 'Max buildings per block to return (1-500, default 100).'
example: 16
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
vnb:
type: string
description: 'Must not be greater than 100 characters.'
example: b
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 22
nullable: true
parameters:
-
in: path
name: egid
description: 'string The building EGID.'
example: '421158'
required: true
schema:
type: string
'/api/network-topology/vzev-lookup/{egid}':
get:
summary: 'Look up vZEV peers for a building by EGID.'
operationId: lookUpVZEVPeersForABuildingByEGID
description: "Returns buildings sharing the same distribution cabinet (Verteilkasten),\neligible for a virtual ZEV. Uses Cubera API (mode=vzev) for Cubera-based\nVNBs or DB-cached VK node data for Stromgemeinschaft VNBs."
parameters:
-
in: query
name: vnb
description: 'Optional VNB identifier.'
example: primeo
required: false
schema:
type: string
description: 'Optional VNB identifier.'
example: primeo
-
in: query
name: limit
description: 'Max peers to return (1-500, default 100).'
example: 16
required: false
schema:
type: integer
description: 'Max peers to return (1-500, default 100).'
example: 16
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
vnb:
type: string
description: 'Must not be greater than 100 characters.'
example: b
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 22
nullable: true
parameters:
-
in: path
name: egid
description: 'string The building EGID.'
example: '421158'
required: true
schema:
type: string
'/api/network-topology/quarter-legs/by-municipality/{bfs_number}':
get:
summary: 'Get aggregated Quartier-LEG groups (NE6) for a municipality.'
operationId: getAggregatedQuartierLEGGroupsNE6ForAMunicipality
description: ''
parameters:
-
in: query
name: limit
description: 'Max groups to return (1-500, default 100).'
example: 100
required: false
schema:
type: integer
description: 'Max groups to return (1-500, default 100).'
example: 100
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 500.'
example: 1
nullable: true
parameters:
-
in: path
name: bfs_number
description: 'int The municipality BFS number.'
example: 2822
required: true
schema:
type: integer
/api/network-topology/address-lookup:
get:
summary: 'Search address candidates for topology fallback flows.'
operationId: searchAddressCandidatesForTopologyFallbackFlows
description: ''
parameters:
-
in: query
name: query
description: 'string Search term (street, house number, zip, city, EGID).'
example: 'Hauptstrasse 12'
required: true
schema:
type: string
description: 'string Search term (street, house number, zip, city, EGID).'
example: 'Hauptstrasse 12'
-
in: query
name: bfs_number
description: 'Optional municipality BFS filter.'
example: 2822
required: false
schema:
type: integer
description: 'Optional municipality BFS filter.'
example: 2822
-
in: query
name: limit
description: 'Max candidates to return (1-25, default 10).'
example: 10
required: false
schema:
type: integer
description: 'Max candidates to return (1-25, default 10).'
example: 10
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'Network Topology'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
query:
type: string
description: 'Must be at least 3 characters. Must not be greater than 255 characters.'
example: b
bfs_number:
type: integer
description: 'Must be at least 1. Must not be greater than 9999.'
example: 22
nullable: true
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 25.'
example: 7
nullable: true
required:
- query
/api/network-topology/import-legacy-checks:
post:
summary: 'Import legacy vZEV check records from the LEG App.'
operationId: importLegacyVZEVCheckRecordsFromTheLEGApp
description: "Bulk imports historical vzev_site_checks data into the GWR DataHub\nnetwork_topology table. Used for one-time migration from LEG App."
parameters: []
responses: { }
tags:
- 'Network Topology'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
records:
type: array
description: 'Must have at least 1 items.'
example:
- []
items:
type: object
properties:
egid:
type: string
description: 'Must not be greater than 20 characters.'
example: bngzmiyvdljnikhw
status:
type: string
description: ''
example: muffennetz
enum:
- verteilkasten
- trafo
- muffennetz
- unknown
provider:
type: string
description: 'Must not be greater than 50 characters.'
example: a
vk_identifier:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
trafo_identifier:
type: string
description: 'Must not be greater than 255 characters.'
example: k
nullable: true
raw_response:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- egid
- status
- provider
required:
- records
'/api/buildings/{egid}/pv-roofs':
get:
summary: 'List available PV roof and facade surfaces for a building'
operationId: listAvailablePVRoofAndFacadeSurfacesForABuilding
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'PV Multi-Roof Configuration'
parameters:
-
in: path
name: egid
description: 'Building EGID.'
example: '123456'
required: true
schema:
type: string
'/api/buildings/{egid}/pv-multi-roof-configurations':
get:
summary: 'List all PV multi-roof configurations for a building'
operationId: listAllPVMultiRoofConfigurationsForABuilding
description: ''
parameters:
-
in: query
name: status
description: 'Filter by status (draft, calculating, completed, failed)'
example: architecto
required: false
schema:
type: string
description: 'Filter by status (draft, calculating, completed, failed)'
example: architecto
-
in: query
name: per_page
description: 'Number of items per page.'
example: 20
required: false
schema:
type: integer
description: 'Number of items per page.'
example: 20
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'PV Multi-Roof Configuration'
post:
summary: 'Create or update a PV multi-roof configuration'
operationId: createOrUpdateAPVMultiRoofConfiguration
description: ''
parameters: []
responses: { }
tags:
- 'PV Multi-Roof Configuration'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
id:
type: integer
description: 'Configuration ID (for updates).'
example: 1
nullable: true
name:
type: string
description: 'Configuration name.'
example: 'Main PV System'
nullable: true
description:
type: string
description: 'Configuration description'
example: 'Eius et animi quos velit et.'
nullable: true
status:
type: string
description: 'Status (draft, calculating, completed, failed).'
example: draft
nullable: true
surfaces:
type: array
description: 'Array of surface configurations'
example:
- architecto
items:
type: string
required:
- surfaces
parameters:
-
in: path
name: egid
description: 'Building EGID.'
example: '123456'
required: true
schema:
type: string
'/api/buildings/{egid}/pv-multi-roof-configurations/{configId}':
get:
summary: 'Get a specific PV multi-roof configuration'
operationId: getASpecificPVMultiRoofConfiguration
description: ''
parameters:
-
in: query
name: lang
description: 'Language code (de, fr, it).'
example: de
required: false
schema:
type: string
description: 'Language code (de, fr, it).'
example: de
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'PV Multi-Roof Configuration'
parameters:
-
in: path
name: egid
description: 'Building EGID.'
example: '123456'
required: true
schema:
type: string
-
in: path
name: configId
description: 'Configuration ID.'
example: '1'
required: true
schema:
type: string
'/api/buildings/{egid}/pv-multi-roof-configurations/{configId}/profiles/{year}':
get:
summary: 'Get production profile for a specific configuration and year'
operationId: getProductionProfileForASpecificConfigurationAndYear
description: "Supports both TMY (Typical Meteorological Year) profiles and year-specific profiles.\nFor TMY profiles, the data is mapped to the requested year's calendar."
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
code: unauthenticated
properties:
message:
type: string
example: Unauthenticated.
code:
type: string
example: unauthenticated
tags:
- 'PV Multi-Roof Configuration'
parameters:
-
in: path
name: egid
description: 'Building EGID.'
example: '123456'
required: true
schema:
type: string
-
in: path
name: configId
description: 'Configuration ID.'
example: '1'
required: true
schema:
type: string
-
in: path
name: year
description: Year.
example: '2025'
required: true
schema:
type: string