API reference · v1.0.0
baseray API
The same building records you see in the app, as JSON: buildings in an area ranked by size, one building’s full record, the businesses registered at its address, and the buildings at a point.
Working in ChatGPT, Claude or Cursor? Connect the baseray MCP server instead: no code, no key.
Base URL
https://api.baseray.ai/v1 Responses are JSON with snake_case fields, metric units and ISO 8601 dates. Unknown values are null; estimates say so in a basis field.
curl "https://api.baseray.ai/v1/buildings?bbox=25.55,45.60,25.68,45.70&sort=volume&limit=25&offset=0&category=residential_house&building_type=&roof_shape=gabled&address_corroboration=corroborated&measured_height_only=false&existing_solar_panels=detected&has_solar_potential=false&has_3d_model=false&has_registered_business=false®istered_business_turnover_currency=RON&has_annual_heating_estimate=false&has_thermal_assessment=false&has_peak_heat_load=false&has_recent_climate_trend=false&has_recent_temperature_extremes=false&has_recent_precipitation=false" \
-H "Authorization: Bearer $BASERAY_API_KEY"const response = await fetch("https://api.baseray.ai/v1/buildings?bbox=25.55,45.60,25.68,45.70&sort=volume&limit=25&offset=0&category=residential_house&building_type=&roof_shape=gabled&address_corroboration=corroborated&measured_height_only=false&existing_solar_panels=detected&has_solar_potential=false&has_3d_model=false&has_registered_business=false®istered_business_turnover_currency=RON&has_annual_heating_estimate=false&has_thermal_assessment=false&has_peak_heat_load=false&has_recent_climate_trend=false&has_recent_temperature_extremes=false&has_recent_precipitation=false", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BASERAY_API_KEY}` },
});
const result = await response.json();import os
import requests
response = requests.get(
"https://api.baseray.ai/v1/buildings",
params={"bbox": "25.55,45.60,25.68,45.70", "sort": "volume", "limit": "25", "offset": "0", "category": "residential_house", "building_type": "", "roof_shape": "gabled", "address_corroboration": "corroborated", "measured_height_only": "false", "existing_solar_panels": "detected", "has_solar_potential": "false", "has_3d_model": "false", "has_registered_business": "false", "registered_business_turnover_currency": "RON", "has_annual_heating_estimate": "false", "has_thermal_assessment": "false", "has_peak_heat_load": "false", "has_recent_climate_trend": "false", "has_recent_temperature_extremes": "false", "has_recent_precipitation": "false"},
headers={"Authorization": f"Bearer {os.environ['BASERAY_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
result = response.json() Authentication
Every request needs a workspace API key. Create one in the app under Settings → API keys; the key is shown once, so store it in your secret manager.
Send the key in the Authorization header as a bearer token. Keys belong to the workspace: anyone in the workspace can create one, and the creator or a workspace owner can revoke it. A key stops working when it is revoked, when it expires, or when its creator leaves the workspace.
Authorization: Bearer br_live_… Rate limits and quotas
Each key can make 60 requests a minute. Each workspace can make 5,000 requests a day, counted per UTC day across all its keys.
Every response tells you where you stand: RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset for the minute, X-Daily-Quota-Limit and X-Daily-Quota-Remaining for the day. Over a limit you get 429 with a Retry-After header; wait that many seconds before retrying.
Errors
Errors use the HTTP status and one JSON shape, so you can branch on error.code:
{
"error": {
"code": "invalid_parameter",
"message": "bbox must be minLon,minLat,maxLon,maxLat.",
"parameter": "bbox"
}
} | Status | Code | Meaning |
|---|---|---|
| 400 | invalid_parameter | A parameter is missing or invalid. error.parameter names it. |
| 401 | missing_api_key | No Authorization: Bearer header was sent. |
| 401 | invalid_api_key | The key does not exist. |
| 401 | revoked_api_key | The key was revoked. |
| 401 | expired_api_key | The key has expired. Create a new one. |
| 403 | insufficient_scope | The key may not call this endpoint. |
| 403 | workspace_access_revoked | The key’s creator no longer belongs to the workspace. |
| 404 | not_found | No building has this id. |
| 429 | rate_limited | Over 60 requests this minute for this key. Retry after Retry-After seconds. |
| 429 | quota_exceeded | The workspace used its daily requests. The quota resets at midnight UTC. |
| 503 | upstream_unavailable | The data service is temporarily unavailable. Retry with exponential backoff. |
Pagination
List endpoints take limit and offset and return meta.total with links.next, the URL of the next page or null on the last one. offset + limit may not exceed 10,000.
Counting stops at 10,000 buildings. When meta.total_is_capped is true, the area holds more than that: narrow the box or add filters rather than paging further.
Endpoints
Buildings
Search, look up and read buildings.
Registered businesses
Businesses whose registered office is a building's address. A registered office is never ownership or occupancy.
Meta
This document.