Skip to content

Buildings

Building endpoints provide access to building-level records in the Solar Lake Enterprise dataset.

Use these endpoints to:

  • Retrieve a single building by building_id
  • Resolve a building by a WGS84 coordinate
  • Fetch many buildings in one request (IDs or points)
  • Efficiently retrieve only the fields you need via projection (options.select)

Authentication: All requests require subscription_key as a query parameter.
See authentication for details.


API Base URL

https://api.sle.urbananalytica.de

Building object

A building record includes:

  • Address fields (street, house_number, postcode, locality, county, state)
  • Administrative identifiers (building_id, postcode, ags)
  • H3 references (h3_4h3_10)
  • Building characteristics (building_type, building_area, roof_type, roof_area, building_height, heritage_protection)
  • PV & solar metrics (pv, radiation, suitable_roof_area, building_kwh, building_kwp, building_panels, building_co2)
  • Economic indicators (earnings, costs, amortization, total_earnings)
  • Grid/neighborhood metrics (grid_count_buildings, grid_share_owned, grid_share_2020s, grid_population, …)
  • Roof-segment arrays (roof_ids, roof_areas, roof_directions, roof_geoms, …)
  • Geometry as GeoJSON
    • coordinates → Point
    • geometry → Polygon (building footprint)

For a detailed field-level specification, see the Building data model page.


1) Get building by ID

Retrieve the full building record for a given building_id.

Endpoint

GET /building

Query parameters

Parameter Type Required Description
subscription_key string 90-character API key
building_id string 24-character building ID

Example

curl "https://api.sle.urbananalytica.de/building?building_id=0009c4da348d4cc82f2d3448&subscription_key=YOUR_KEY"

Example response (simplified)

{
  "building_id": "0009c4da348d4cc82f2d3448",
  "street": "Hauptstraße",
  "house_number": "12",
  "postcode": "90461",
  "locality": "Nürnberg",
  "ags": "09564000",
  "pv": false,
  "roof_area": 120,
  "heritage_protection": false,
  "deal_size_class": "super",
  "coordinates": {
    "type": "Point",
    "coordinates": [11.42, 48.69]
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [[[...]]]
  }
}

2) Get building by coordinates

Resolve a building for a WGS84 point using containment-first matching with a limited nearest-building fallback.

Endpoint

GET /building-coordinates

Query parameters

Parameter Type Required Description
subscription_key string 90-character API key
lon number Longitude (WGS84)
lat number Latitude (WGS84)

Description

This endpoint applies a two-step strategy to match a building to the input coordinate:

  1. Try an exact match by checking whether the point lies inside a building footprint.
  2. If no building contains the point, search for buildings within 2 meters of the point.
  3. Return the fallback match only when exactly one building is found within that 2 meter radius.
  4. If no building is within 2 meters, or if multiple buildings are within 2 meters, return no match.

Response

The GET response model is unchanged. It returns the building object on success and does not expose a match_type field.

If no unambiguous match can be resolved, the endpoint returns 404 Not Found.

Typical use cases

  • User clicks on a map → resolve building
  • Backend enrichment from coordinates
  • QA/debugging

Examples

Exact match

The point lies inside a building footprint, so the building is returned immediately.

curl "https://api.sle.urbananalytica.de/building-coordinates?lon=7.1202&lat=51.481&subscription_key=YOUR_KEY"
{
  "building_id": "ef863e08dd25e9e571995158",
  "postcode": "90461",
  "ags": "09564000",
  "pv": false
}

Fallback match

The point is not inside any footprint, but exactly one building is within 2 meters, so that nearest building is returned.

{
  "building_id": "ef863e08dd25e9e571995158",
  "postcode": "90461",
  "ags": "09564000",
  "pv": false
}

No match

No building is returned when:

  • no building is within 2 meters, or
  • multiple buildings are within 2 meters and the fallback result would be ambiguous.

In these cases, GET /building-coordinates returns 404 Not Found.


3) Get buildings by IDs (batch)

Batch lookup of multiple buildings.

Endpoint

POST /buildings

Query parameters

Parameter Type Required
subscription_key string

Request body

Field Type Required Description
building_ids array[string] List of 24-character building IDs
options.select array[string] Fields to include (projection)

The API always includes building_id in the response, even if not listed in select.

Example

curl -X POST "https://api.sle.urbananalytica.de/buildings?subscription_key=YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "building_ids": [
          "00cbacac2e8d30e5579d3dc1",
          "0159c5881baa4c4037f58699"
        ],
        "options": {
          "select": ["building_id", "postcode", "roof_area", "pv"]
        }
      }'

Response shape

{
  "requested": 2,
  "returned": 2,
  "missing_ids": [],
  "items": [
    {
      "building_id": "00cbacac2e8d30e5579d3dc1",
      "postcode": "90461",
      "roof_area": 120,
      "pv": false
    }
  ]
}

4) Get buildings by coordinates (batch)

Resolve multiple WGS84 points in a single request.

Endpoint

POST /buildings-coordinates

Query parameters

Parameter Type Required
subscription_key string

Request body

Field Type Required Description
points array[object] List of WGS84 points
points[].lon number Longitude in WGS84
points[].lat number Latitude in WGS84
points[].address object Optional address information for validation
points[].address.street string Street
points[].address.house_number string House number
points[].address.postcode string Postcode
points[].address.locality string Locality
options.select array[string] Building fields to include

Address validation works independently of options.select. Address fields used internally for validation are not added to the returned building object unless explicitly selected.

Description

This endpoint uses the same coordinate resolution strategy as GET /building-coordinates, but applies it independently to each input point.

The response echoes the original request coordinates so clients can match every result back to the input data:

  • matched points are returned as items[].input_point
  • unresolved points are returned as missing_points

Use these echoed coordinates for client-side merging instead of relying on response order.

A point resolves to a nearby building when:

  • the point is not inside any building footprint,
  • the nearest building is within 2 meters, and
  • that fallback candidate is unambiguous because it is the only building within 2 meters.

Matching logic

For each input point, the API evaluates matches in this order:

  1. Return the building immediately if the point lies inside a building footprint.
  2. Otherwise search for buildings within 2 meters of the point.
  3. Return a fallback match only if exactly one building is found within 2 meters.
  4. Otherwise return no match for that point.

Points without a match are listed in missing_points.

Optional address validation

Each point may include an optional address object. All address fields are optional. The coordinates remain the only input used to resolve the building; the supplied address does not influence building selection. It is normalized and compared only after a building has been resolved from the coordinates, as a plausibility check rather than a geocoding or postal-address verification service.

Address validation is supported only by POST /buildings-coordinates; GET /building-coordinates remains a coordinate-only lookup. address_validation is returned only when usable address information was supplied.

{
  "points": [
    {
      "lon": 11.12625,
      "lat": 49.43996,
      "address": {
        "street": "Valznerweiherstr.",
        "house_number": "98",
        "postcode": "90480",
        "locality": "Nürnberg"
      }
    }
  ],
  "options": {
    "select": [
      "building_id",
      "pv",
      "roof_area"
    ]
  }
}

Response shape

{
  "requested": 1,
  "returned": 1,
  "missing_points": [],
  "items": [
    {
      "input_point": {
        "lon": 11.12625,
        "lat": 49.43996
      },
      "match_type": "inside",
      "address_validation": {
        "assessment": "exact",
        "street_match": true,
        "house_number_match": true,
        "postcode_match": true,
        "locality_match": true
      },
      "building": {
        "building_id": "8975053b459c1bffec6f021f",
        "pv": false,
        "roof_area": 72
      }
    }
  ]
}

Response

Each result item contains:

  • input_point → the original coordinate from the request
  • match_type → how the building was resolved:
    • inside
    • nearest_within_2m
  • address_validation → optional address plausibility result, returned only when usable address information was supplied
  • building → the matched building object

match_type is only available on POST /buildings-coordinates. It is not part of the GET endpoint response.

For address validation field results:

  • true → the supplied field matches after normalization
  • false → the supplied field does not match
  • null → the field was not supplied

The overall assessment can be:

  • exact → street and house number match, and all other supplied fields match
  • probable → street and house number match, but postcode or locality differs
  • different → street or house number differs
  • insufficient → street or house number was not supplied

Examples

Exact match case

The point lies inside a building footprint.

{
  "requested": 1,
  "returned": 1,
  "missing_points": [],
  "items": [
    {
      "input_point": {
        "lon": 7.1202,
        "lat": 51.481
      },
      "match_type": "inside",
      "building": {
        "building_id": "ef863e08dd25e9e571995158",
        "postcode": "90461",
        "ags": "09564000",
        "pv": false
      }
    }
  ]
}

Address validation case

The address is checked after the coordinate-based building match has been resolved.

{
  "requested": 1,
  "returned": 1,
  "missing_points": [],
  "items": [
    {
      "input_point": {
        "lon": 11.576,
        "lat": 48.137
      },
      "match_type": "inside",
      "address_validation": {
        "assessment": "probable",
        "street_match": true,
        "house_number_match": true,
        "postcode_match": false,
        "locality_match": true
      },
      "building": {
        "building_id": "00cbacac2e8d30e5579d3dc1",
        "pv": false,
        "roof_area": 124
      }
    }
  ]
}

Fallback match case

The point is outside all footprints, but exactly one building is within 2 meters.

{
  "requested": 1,
  "returned": 1,
  "missing_points": [],
  "items": [
    {
      "input_point": {
        "lon": 7.120215,
        "lat": 51.481012
      },
      "match_type": "nearest_within_2m",
      "building": {
        "building_id": "ef863e08dd25e9e571995158",
        "postcode": "90461",
        "ags": "09564000",
        "pv": false
      }
    }
  ]
}

No match case

No item is returned for a point when:

  • no building is within 2 meters, or
  • multiple buildings are within 2 meters and the fallback result would be ambiguous.
{
  "requested": 1,
  "returned": 0,
  "missing_points": [
    {
      "lon": 7.1203,
      "lat": 51.4812
    }
  ],
  "items": []
}

Notes

  • Each result item includes the original input_point for reliable client-side mapping back to the request.
  • missing_points contains the original request coordinates that could not be resolved.
  • match_type distinguishes direct containment matches from the nearest-building fallback.
  • The endpoint guarantees a response for all input points:
    • Points that cannot be resolved (including coordinates outside Germany) are returned in missing_points.

Error handling

422 – Validation Error

Returned when query parameters or request bodies are invalid.

403 – Access Denied

Returned when subscription_key is missing or invalid.

Empty results

Batch endpoints return:

  • returned = 0
  • A list of missing_ids or missing_points

This is not an error and should be handled as "not found".


  • Bounding-box building loading → see endpoints/bounding-boxes.md
  • Bulk extraction by region (POST /query/buildings) → see endpoints/queries.md
  • API conventions (WGS84, GeoJSON, projection, pagination) → see conventions.md