Skip to content

Filters

Many POST endpoints support advanced filtering using a Mongo-like JSON syntax.

Filtering allows you to restrict results based on building attributes, aggregate metrics, or other documented fields.

Supported endpoints include:

  • POST /bbox/buildings
  • POST /bbox/h3s
  • POST /bbox/postcodes
  • POST /bbox/municipalities
  • POST /query/buildings

Filter Structure

Filters are provided inside the request body:

{
  "filter": {
    "roof_area": { "$gte": 100 },
    "pv": false
  }
}

The filter object contains:

  • Field names as keys
  • Conditions as values
  • Multiple fields are combined using logical AND

Supported Operators

The following operators are supported:

Operator Meaning Example
$eq Equals { "pv": { "$eq": false } }
$ne Not equals { "pv": { "$ne": true } }
$gt Greater than { "roof_area": { "$gt": 80 } }
$gte Greater than or equal { "roof_area": { "$gte": 80 } }
$lt Less than { "roof_area": { "$lt": 200 } }
$lte Less than or equal { "roof_area": { "$lte": 200 } }
$in Value is in list { "building_type": { "$in": ["single-family house", "terraced house"] } }
$nin Value is not in list { "postcode": { "$nin": ["90461"] } }

Equality Shorthand

For simple equality, you may use shorthand syntax:

{
  "filter": {
    "pv": false
  }
}

This is equivalent to:

{
  "filter": {
    "pv": { "$eq": false }
  }
}

Combining Conditions

Multiple conditions are combined using logical AND.

Example:

{
  "filter": {
    "roof_area": { "$gte": 80 },
    "pv": false,
    "building_type": { "$in": ["single-family house", "terraced house"] }
  }
}

This means:

  • Roof area ≥ 80
  • No existing PV installation
  • Building type is either "single-family house" or "terraced house"

Range Filters

You can define range-like conditions by combining operators:

{
  "filter": {
    "sales_opportunity_score": {
      "$gte": 5,
      "$lte": 9
    }
  }
}

This filters values between 0.25 and 0.60.


List-Based Filters

Use $in or $nin when filtering against multiple values:

{
  "filter": {
    "postcode": { "$in": ["90461", "90471"] }
  }
}

The value for $in and $nin must be a list.


Filtering in Bounding Box Requests

Example: Buildings in a viewport without PV and large roof area:

{
  "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"]
  }
}

Filtering in Bulk Extraction

Example: Campaign extraction using region selector:

{
  "region": {
    "postcode_in": ["90461", "90471"]
  },
  "filter": {
    "pv": false,
    "building_type": { "$in": ["single-family house", "terraced house"] }
  },
  "options": {
    "select": ["building_id", "postcode", "roof_area", "pv"],
    "limit": 5000
  }
}

Important Notes

  • Only documented fields are filterable.
  • Unsupported fields will result in validation errors.
  • Filtering is always combined using logical AND.
  • OR-style logic is not supported.

Performance Considerations

For best performance:

  • Combine filtering with options.select to reduce payload size.
  • Avoid unnecessary wide-range filters in large bounding boxes.
  • Use cursor pagination (after_building_id) for large filtered exports.

Common Mistakes

Incorrect Operator Format

Incorrect:

{ "roof_area": "$gte: 80" }

Correct:

{ "roof_area": { "$gte": 80 } }

$in Without List

Incorrect:

{ "building_type": { "$in": "single-family house" } }

Correct:

{ "building_type": { "$in": ["single-family house"] } }

Summary

Filters allow you to:

  • Narrow down building or aggregate results
  • Build campaign target lists
  • Restrict viewport results
  • Implement precise data selection

They are powerful but intentionally limited to safe, predictable operations.