Skip to content

Bounding Boxes (Viewport Endpoints)

Bounding box endpoints are optimized for interactive map applications.

They are designed to quickly load data for the current viewport (a WGS84 bounding box), for example when:

  • The user pans/zooms a web map
  • You need incremental loading while avoiding duplicates
  • You want fast filters + projection for map layers

This API provides two variants for each bbox endpoint:

  • Simple GET: easy to use, lightweight, optional top (and resolution for H3)
  • Advanced POST: supports filters, projection, pagination, and incremental loading via exclude

Important: Bounding box queries are optimized for performance.
Results may include a small number of objects slightly outside the requested bounding box.

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


API Base URL

https://ua-api-solar-lake-enterprise.azurewebsites.net

Common concepts

1) BBox format (WGS84)

Bounding boxes are always in WGS84 (longitude/latitude):

{
  "min_lon": 11.50,
  "min_lat": 48.10,
  "max_lon": 11.51,
  "max_lat": 48.11
}

For GET endpoints, these are sent as query parameters.


2) Response metadata

All bbox endpoints return the same meta fields:

  • h3_resolution: resolution used internally for the viewport polyfill
  • cells: number of H3 cells used to cover the bbox (polyfill size)
  • returned: number of documents returned
  • items: list of returned objects (projection-friendly)

Example:

{
  "h3_resolution": 9,
  "cells": 187,
  "cells_truncated": false,
  "returned": 5000,
  "items": [...]
}

3) Advanced POST: filters, projection, pagination, exclusion

All advanced bbox POST endpoints support:

filter (optional)

Mongo-like filter syntax (allowlisted fields per endpoint category).

Supported operators:

  • Equality: $eq, $ne (shorthand { "pv": false } is allowed)
  • Comparisons: $gt, $gte, $lt, $lte
  • Set membership: $in, $nin (value must be a list)

Examples:

{ "pv": false }
{ "roof_area": { "$gte": 100 } }
{
  "count_buildings": { "$gte": 30 },
  "share_owned": { "$gte": 0.6 }
}

Invalid fields/operators return 422.

options (optional)

Controls projection and pagination:

  • options.select: fields to include (projection)
  • options.skip: offset pagination (default 0)
  • options.limit: page size (default 5000)

The endpoint-specific ID field is always included automatically:

  • buildings: building_id
  • h3: h3_id (+ h3_resolution)
  • postcodes: postcode
  • municipalities: ags

exclude (optional)

Avoid sending data the client already has:

{
  "exclude": {
    "exclude_ids": ["..."],
    "exclude_bboxes": [{ "min_lon": ..., "min_lat": ..., "max_lon": ..., "max_lat": ... }]
  }
}
  • exclude.exclude_ids: exclude specific IDs (meaning depends on endpoint)
  • exclude.exclude_bboxes: subtract previously loaded areas (useful for incremental loading)

Endpoint overview

Data type Simple GET Advanced POST
Buildings GET /bbox/buildings POST /bbox/buildings
H3 aggregates GET /bbox/h3s POST /bbox/h3s
Postcode aggregates GET /bbox/postcodes POST /bbox/postcodes
Municipality aggregates GET /bbox/municipalities POST /bbox/municipalities

1) Buildings in bounding box

Simple (GET) — /bbox/buildings

Endpoint

GET /bbox/buildings

Query parameters

Parameter Type Required Notes
subscription_key string 90-character API key
min_lon number -180..180
min_lat number -90..90
max_lon number -180..180
max_lat number -90..90
top integer Max buildings to return (default 5000, max 10000)

Example

curl "https://ua-api-solar-lake-enterprise.azurewebsites.net/bbox/buildings?min_lon=11.50&min_lat=48.10&max_lon=11.51&max_lat=48.11&top=100&subscription_key=YOUR_KEY"

Response (shape)

{
  "h3_resolution": 10,
  "cells": 56,
  "cells_truncated": false,
  "returned": 100,
  "items": [
    { "building_id": "..." }
  ]
}

GET endpoints return a full object list.

For filtering/projection, use the POST endpoint.


Advanced (POST) — /bbox/buildings

Endpoint

POST /bbox/buildings

Body

{
  "bbox": { "min_lon": 11.5, "min_lat": 48.1, "max_lon": 11.51, "max_lat": 48.11 },
  "filter": { "pv": false, "roof_area": { "$gte": 80 } },
  "exclude": {
    "exclude_bboxes": [
      { "min_lon": 11.505, "min_lat": 48.105, "max_lon": 11.506, "max_lat": 48.106 }
    ]
  },
  "options": {
    "select": ["building_id", "roof_area", "pv", "sales_opportunity_score"],
    "skip": 0,
    "limit": 5000
  }
}

Example (curl)

curl -X POST "https://ua-api-solar-lake-enterprise.azurewebsites.net/bbox/buildings?subscription_key=YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "bbox": { "min_lon": 11.5, "min_lat": 48.1, "max_lon": 11.51, "max_lat": 48.11 },
        "filter": { "pv": false, "roof_area": { "$gte": 80 } },
        "options": {
          "select": ["building_id", "roof_area", "pv", "sales_opportunity_score"],
          "limit": 5000
        }
      }'

2) H3 aggregates in bounding box

H3 bbox endpoints are ideal for heatmaps and zoom-dependent displays.

Simple (GET) — /bbox/h3s

Endpoint

GET /bbox/h3s

Query parameters

Parameter Type Required Notes
subscription_key string 90-character API key
min_lon number -180..180
min_lat number -90..90
max_lon number -180..180
max_lat number -90..90
top integer Max H3 docs (default 5000, max 100000)
resolution integer Optional fixed H3 resolution (4..10)

Example

curl "https://ua-api-solar-lake-enterprise.azurewebsites.net/bbox/h3s?min_lon=11.50&min_lat=48.10&max_lon=11.51&max_lat=48.11&resolution=6&top=5000&subscription_key=YOUR_KEY"

Advanced (POST) — /bbox/h3s

Endpoint

POST /bbox/h3s

Notes

  • If resolution is omitted, the API selects a suitable resolution for the viewport.
  • Use projection (options.select) for performance.

Body example (auto resolution + filter)

{
  "bbox": { "min_lon": 11.5, "min_lat": 48.1, "max_lon": 11.51, "max_lat": 48.11 },
  "filter": { "count_buildings": { "$gte": 5 }, "share_owned": { "$gte": 0.6 } },
  "options": {
    "select": ["h3_id", "h3_resolution", "count_buildings", "sales_opportunity_score", "share_owned"],
    "limit": 5000
  }
}

Body example (fixed resolution)

{
  "bbox": { "min_lon": 9.9, "min_lat": 53.5, "max_lon": 9.91, "max_lat": 53.51 },
  "resolution": 8,
  "options": {
    "select": ["h3_id", "h3_resolution", "count_buildings", "sales_opportunity_score"],
    "limit": 5000
  }
}

Optional: Returning Empty H3 Cells

By default, the API only returns H3 cells that contain data.

Clients may optionally request information about empty H3 cells within the bounding box using the include_empty_cells option.

Example request:

{
  "bbox": {
    "min_lon": 11.0,
    "min_lat": 49.3,
    "max_lon": 11.3,
    "max_lat": 49.6
  },
  "include_empty_cells": "geometries",
  "options": {
    "limit": 5000
  }
}

Supported values:

Value Behavior
no (default) Only H3 cells with data are returned
ids IDs of empty H3 cells are returned
geometries Empty H3 cells are returned with full geometry

When enabled, the response may contain additional fields:

Field Description
empty_h3_ids IDs of H3 cells without data
empty_items Empty H3 cells including geometry
empty_cells_suppressed Indicates empty cells were not returned due to pagination

Empty cells never contain aggregated metrics such as count_buildings.

This feature is mainly intended for map applications that want to render a complete H3 grid, for example with faint outlines or background shading.


3) Postcodes in bounding box

Postcode bbox endpoints return postcode-area aggregates for the viewport.

Simple (GET) — /bbox/postcodes

Endpoint

GET /bbox/postcodes

Query parameters

Parameter Type Required Notes
subscription_key string 90-character API key
min_lon number -180..180
min_lat number -90..90
max_lon number -180..180
max_lat number -90..90
top integer Max docs (default 5000, max 100000)

Example

curl "https://ua-api-solar-lake-enterprise.azurewebsites.net/bbox/postcodes?min_lon=11.50&min_lat=48.10&max_lon=11.51&max_lat=48.11&top=100&subscription_key=YOUR_KEY"

Advanced (POST) — /bbox/postcodes

Endpoint

POST /bbox/postcodes

Body example (filter + projection)

{
  "bbox": { "min_lon": 11.5, "min_lat": 48.1, "max_lon": 11.51, "max_lat": 48.11 },
  "filter": { "count_buildings": { "$gte": 2000 }, "share_owned": { "$gte": 0.6 } },
  "options": {
    "select": ["postcode", "count_buildings", "sales_opportunity_score", "share_owned"],
    "limit": 100
  }
}

4) Municipalities in bounding box

Municipality bbox endpoints return municipality (AGS) aggregates for the viewport.

Simple (GET) — /bbox/municipalities

Endpoint

GET /bbox/municipalities

Query parameters

Parameter Type Required Notes
subscription_key string 90-character API key
min_lon number -180..180
min_lat number -90..90
max_lon number -180..180
max_lat number -90..90
top integer Max docs (default 5000, max 100000)

Example

curl "https://ua-api-solar-lake-enterprise.azurewebsites.net/bbox/municipalities?min_lon=8.40&min_lat=49.90&max_lon=8.41&max_lat=49.91&top=100&subscription_key=YOUR_KEY"

Advanced (POST) — /bbox/municipalities

Endpoint

POST /bbox/municipalities

Body example (filter + projection)

{
  "bbox": { "min_lon": 8.4, "min_lat": 49.9, "max_lon": 8.41, "max_lat": 49.91 },
  "filter": { "count_buildings": { "$gte": 5000 }, "sales_opportunity_score": { "$gte": 5 } },
  "options": {
    "select": ["ags", "count_buildings", "sales_opportunity_score", "share_owned"],
    "limit": 200
  }
}

Practical guidance

Use GET for “quick map plotting”

  • fastest integration
  • no filters/projection control
  • be aware of potentially large data returned

Use POST for “real map products”

  • projection via options.select
  • filter by PV, roof area, score, etc.
  • incremental loading via exclude.exclude_bboxes
  • stable UX with predictable paging (options.limit)

Prefer projection

If you plot on a map, you often only need a few fields:

  • Buildings: building_id + 1–3 metrics (e.g., roof_area, pv, sales_opportunity_score, building_type)
  • H3: h3_id, h3_resolution, count_buildings, sales_opportunity_score
  • Postcodes: postcode, count_buildings, sales_opportunity_score
  • Municipalities: ags, count_buildings, sales_opportunity_score

Errors

422 — Validation Error

Common causes:

  • bbox values missing or wrong types
  • invalid filter operators or invalid filter types
  • invalid resolution (H3) range
  • invalid options (e.g., limit outside allowed range)

403 — Access Denied

Missing or invalid subscription_key