Queries¶
Query endpoints are designed for bulk workflows such as:
- Campaign exports
- Lead generation
- CRM enrichment
- Regional analytics pipelines
- Data downloads / batch processing
Compared to viewport (/bbox/*) endpoints, query endpoints are optimized for large-scale extraction and support:
- Region selectors (exactly one required)
- Mongo-like filters
- Field projection (
options.select) - Cursor-based pagination via
options.after_building_id(recommended)
Authentication: All requests require
subscription_keyas a query parameter.
See authentication for details.
API Base URL¶
https://ua-api-solar-lake-enterprise.azurewebsites.net
POST /query/buildings — Extract buildings by region and filters¶
This endpoint returns buildings matching a region selector and optional filters.
It is the recommended endpoint for bulk extraction workflows.
Endpoint¶
POST /query/buildings
Authentication via:
?subscription_key=YOUR_KEY
Request body structure¶
{
"region": { ... }, // required: exactly one selector
"filter": { ... }, // optional
"options": { ... } // optional (projection + paging)
}
region (required)¶
Exactly one region selector must be provided.
Supported selectors:
| Selector | Description | Value type |
|---|---|---|
postcode_in |
List of German postcodes | array[string] |
ags_in |
List of municipality AGS codes | array[string] |
h3_4_in … h3_10_in |
List of H3 IDs at a fixed resolution | array[string] |
Notes:
- H3 IDs may be provided as decimal or hex.
- Choose the selector that best matches your workflow:
- Campaign by postcode →
postcode_in - Municipality export →
ags_in - Grid/cell workflows →
h3_*_in(fixed resolution)
- Campaign by postcode →
filter (optional)¶
Filters use a Mongo-like syntax.
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 } }
{
"roof_area": { "$gt": 80 },
"building_type": { "$in": ["single-family house", "terraced house"] }
}
Only allowlisted, documented fields are filterable. Invalid fields/operators return 422.
options (optional)¶
options controls projection and pagination.
| Field | Type | Description |
|---|---|---|
select |
array[string] | Fields to include in the response (projection) |
skip |
integer | Offset pagination (allowed, but not recommended for large exports) |
limit |
integer | Page size (default 5000, max may apply) |
after_building_id |
string | Cursor paging token (recommended) |
Projection is strongly recommended for bulk exports:
- It reduces payload size
- It speeds up queries
- It avoids unnecessary geometry / roof arrays unless needed
The API always includes
building_idautomatically, even if not listed inselect.
Response structure¶
{
"returned": 5000,
"next_after_building_id": "01c02e568d94065d29c7fd9e",
"items": [
{ "building_id": "..." },
{ "building_id": "..." }
]
}
returned= number of items in this pageitems= list of buildings (projection-friendly; always includesbuilding_id)next_after_building_id:- present if another page is available
- omit / null when you reached the end
Examples¶
1) Postcode campaign export (with filter + projection)¶
curl -X POST "https://ua-api-solar-lake-enterprise.azurewebsites.net/query/buildings?subscription_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"region": { "postcode_in": ["90461", "90471"] },
"filter": {
"pv": false,
"roof_area": { "$gte": 80 },
"building_type": { "$in": ["single-family house", "terraced house"] }
},
"options": {
"select": ["building_id", "postcode", "roof_area", "pv", "sales_opportunity_score"],
"limit": 5000
}
}'
2) Municipality export (AGS selector)¶
{
"region": { "ags_in": ["09564000"] },
"options": {
"select": ["building_id", "ags", "postcode", "roof_area", "pv"],
"limit": 5000
}
}
3) H3-based export at a fixed resolution¶
{
"region": {
"h3_7_in": ["608532992465305599", "608532995971743743"]
},
"filter": {
"pv": false,
"roof_area": { "$gte": 80 }
},
"options": {
"select": ["building_id", "h3_7", "postcode", "roof_area", "pv"],
"limit": 5000
}
}
Cursor pagination (recommended)¶
Cursor pagination avoids large skip offsets and is the preferred method for exporting many records.
First page¶
{
"region": { "postcode_in": ["90461"] },
"filter": { "pv": false },
"options": {
"select": ["building_id", "postcode", "roof_area"],
"limit": 5000
}
}
Example response:
{
"returned": 5000,
"next_after_building_id": "41d36aa651cea1ea53641e6b",
"items": [...]
}
Next page¶
Use the cursor from the previous response:
{
"region": { "postcode_in": ["90461"] },
"filter": { "pv": false },
"options": {
"select": ["building_id", "postcode", "roof_area"],
"limit": 5000,
"after_building_id": "41d36aa651cea1ea53641e6b"
}
}
Continue until:
next_after_building_idis missing, orreturnedbecomes0
Practical guidance & limits¶
Keep region selectors reasonable in size¶
Very large region lists may be rejected or slowed down by server-side safeguards.
If you need to export a huge area:
- Split the request by postcode batches (e.g., 1–5 at a time)
- Or use H3 selectors at a coarser resolution to reduce partition fan-out
Always use projection for bulk exports¶
Avoid requesting full building documents unless you truly need:
- Roof segment arrays (
roof_*) - Detailed economics fields
- Geometry for every record
A typical campaign export often needs only:
building_id,postcoderoof_area,pv,sales_opportunity_score- maybe a few other fields
Errors¶
422 — Validation Error¶
Common causes:
- Missing
region - More than one selector provided in
region - Invalid filter operator / filter type
- Non-allowlisted filter field
- Invalid
after_building_idformat
403 — Access Denied¶
Missing or invalid subscription_key