Auchindown · Rooftop Solar Inventory
API Reference
Reference spec for the rooftop solar detection product’s data API. Hosted at solar.auchindown.com.
Solar Inventory Map →
Pricing calculator →
Base URL
https://solar.auchindown.com/v1/solar/{country}/...
{country} is an ISO 3166-1 alpha-3 code, lowercase (e.g. jam for Jamaica).
Conventions
Auth
Every endpoint requires Authorization: Bearer <api_key>. Missing or invalid keys return 401.
Epochs
Imagery epochs are identified by strings like 2026-04, matching the April/October capture cadence. Any endpoint accepting an epoch query parameter defaults to the latest available epoch when omitted.
Response format
Spatial endpoints return raw GeoJSON: a valid
FeatureCollection or
Feature at the top level, so responses drop directly into GIS tooling (QGIS, MapLibre) without unwrapping. Pagination and link metadata are added as extra top-level members, following the
OGC API - Features convention:
{
"type": "FeatureCollection",
"features": [ /* ... */ ],
"numberMatched": 240,
"numberReturned": 50,
"links": [
{ "rel": "self", "href": "https://solar.auchindown.com/v1/solar/jam/tiles?limit=50" },
{ "rel": "next", "href": "https://solar.auchindown.com/v1/solar/jam/tiles?limit=50&cursor=..." }
]
}
Non-spatial endpoints (/epochs, /tiles/{id}/stats, /summary) return plain JSON.
Pagination
Spatial list endpoints accept limit (default 50, max 500) and cursor.
Errors
Every non-2xx response has the same body shape:
{ "error": { "code": "invalid_bbox", "message": "bbox must be minLon,minLat,maxLon,maxLat" } }
Endpoints
GET/tiles
List tile boundaries and available epochs for each tile.
Query parameters
| Param | Type | Notes |
| bbox | minLon,minLat,maxLon,maxLat | Optional spatial filter |
| limit | integer | Default 50, max 500 |
| cursor | string | Opaque pagination cursor |
Response
FeatureCollection of tile polygons (each tile is the fixed 2.5×2.5 km / 6.25 km² grid cell).
{
"grid_id": "311-257",
"available_epochs": ["2026-04", "2025-10"]
}
Errors: 400 invalid bbox or unknown epoch.
GET/tiles/{id}
Fetch a single tile. {id} is the tile’s grid_id.
Query parameters
| Param | Type | Notes |
| epoch | string | Optional, defaults to latest |
Response
A single GeoJSON Feature (the tile polygon), properties shaped exactly as in the /tiles list.
Errors: 404 unknown tile; 400 unknown epoch for that tile.
GET/epochs
List available imagery epochs for the country.
Response
Plain JSON array, no pagination:
[
{
"epoch": "2025-10",
"captured_start": "2025-08-21",
"captured_end": "2025-09-20",
"tile_coverage_count": 5,
"status": "complete"
},
{
"epoch": "2026-04",
"captured_start": "2025-12-17",
"captured_end": "2026-02-22",
"tile_coverage_count": 15,
"status": "complete"
}
]
GET/tiles/{id}/stats?epoch=
Full tile statistics: the same data rendered on the printable tile report sheet.
Response
Plain JSON object, field-for-field identical to the live product’s TileStats interface, plus epoch:
{
"grid_id": "311-257",
"parishes": "Kingston",
"settlement_class": "Class A",
"communities": "Harbour View",
"cell_area_m2": 6250000,
"land_area_m2": 5100000,
"urban_area_m2": 4300000,
"rural_area_m2": 800000,
"water_area_m2": 1150000,
"total_building_count": 971,
"number_of_buildings_with_solar": 42,
"total_residential_building_count": 890,
"total_non_residential_building_count": 81,
"number_of_residential_buildings_with_solar": 35,
"number_of_non_residential_buildings_with_solar": 7,
"residential_panel_area_m2": 980.5,
"non_residential_panel_area_m2": 486.2,
"total_panel_area_m2": 1466.7,
"installed_capacity_mw": 0.22,
"residential_capacity_mw": 0.147,
"non_residential_capacity_mw": 0.073,
"residential_penetration_pct": 3.9,
"non_residential_penetration_pct": 8.6,
"overall_utilisation_pct": 23.5,
"epoch": "2026-04"
}
Errors: 404 unknown tile; 400 unknown epoch.
GET/tiles/{id}/installations?epoch=
Individual detected installations within a tile.
Query parameters
| Param | Type | Notes |
| epoch | string | Defaults to latest |
| bbox | minLon,minLat,maxLon,maxLat | Sub-filter within the tile |
| building_class | residential | non_residential | Optional |
| limit | integer | Default 50, max 500 |
| cursor | string | Opaque pagination cursor |
Response
FeatureCollection. Each feature’s properties:
{
"installation_id": "inst_9f2a1c",
"building_id": "bldg_44210",
"panel_area_m2": 18.4,
"capacity_kw": 2.76,
"building_class": "residential",
"epoch": "2026-04"
}
capacity_kw is derived from panel area using the same watts/m² constant as the live product.
Errors: 404 unknown tile; 400 invalid bbox/epoch/confidence.
GET/tiles/{id}/changes?from=&to=
Change detection between two epochs for a tile.
Query parameters
| Param | Type | Notes |
| from | string | Required epoch identifier |
| to | string | Required; must postdate from |
| changed_only | boolean | Optional, default false. When true, excludes unchanged installations; only appeared, disappeared, expanded, and contracted are returned. |
Response
FeatureCollection of installations, each with change metadata added:
{
"installation_id": "inst_9f2a1c",
"building_id": "bldg_44210",
"change_type": "expanded",
"panel_area_m2_from": 12.0,
"panel_area_m2_to": 18.4,
"building_class": "residential"
}
change_type is one of appeared, disappeared, expanded, contracted, unchanged.
Errors: 400 if from/to are missing, unknown, or from does not predate to; 404 unknown tile.
GET/installations?bbox=&epoch=
Cross-tile installation query.
Query parameters
| Param | Type | Notes |
| bbox | minLon,minLat,maxLon,maxLat | Required |
| epoch | string | Defaults to latest |
| building_class | residential | non_residential | Optional |
| limit | integer | Default 50, max 500 |
| cursor | string | Opaque pagination cursor |
Response
Same shape as /tiles/{id}/installations, with a grid_id property added to each feature so results trace back to their tile.
Errors: 400 if bbox is missing or its area exceeds a maximum (e.g. 100 km²); this endpoint does not support unbounded, country-wide dumps; use /tiles + per-tile /installations for bulk export instead.
GET/summary?epoch=
National (or grouped) rollup.
Query parameters
| Param | Type | Notes |
| epoch | string | Defaults to latest |
| groupby | parish | settlement_class | Optional |
Response
Plain JSON. Without groupby, a single object in the same metric shape as /tiles/{id}/stats (minus tile-identifying fields), summed across all tiles. With groupby, an array of { group_key, ...same metrics }.