Overview
Borough caches data in a D1 database and refreshes it on a schedule. Every API response includes freshness metadata so you always know how old the data is and whether a refresh has been triggered.Response metadata
Every response includes these fields inmeta:
| Field | Type | Description |
|---|---|---|
dataAge | string | When the data was last refreshed (ISO 8601 timestamp) |
source | string | How the data was served: cached, stale, or live |
freshnessThreshold | integer | Max allowed age in minutes before refresh triggers |
refreshTriggered | boolean | Whether this request triggered a background refresh |
Response headers
Two headers are included on every response:Source values
| Value | Meaning |
|---|---|
cached | Data is within the freshness threshold for your tier |
stale | Data exceeds the threshold — a background refresh has been queued |
live | Fetched live from the source just now (Business/Internal tiers on property and building detail) |
source is stale, the API still returns the data immediately. The refresh happens asynchronously — your next request will get fresh data.
Freshness thresholds by tier
Paid tiers trigger automatic background refreshes when data exceeds these age thresholds:Search results
| Tier | Threshold |
|---|---|
| Starter | 2 hours |
| Pro | 1 hour |
| Business | 30 minutes |
Listing details
| Tier | Threshold |
|---|---|
| Starter | 30 minutes |
| Pro | 15 minutes |
| Business | 10 minutes |
Building details
| Tier | Threshold |
|---|---|
| Starter | 6 hours |
| Pro | 3 hours |
| Business | 2 hours |
Free tier behavior
Free-tier requests always serve cached data and never trigger background refreshes. ThefreshnessThreshold and refreshTriggered fields are null for free-tier responses.
Cached data is refreshed on a fixed schedule regardless of API traffic:
| Data type | Schedule |
|---|---|
| Search index | Every 6 hours |
| Listing details | Daily |
| Building details | Every 2 days |
| Area boundaries | Weekly |
| Market snapshots | Daily |
How async refresh works
When a paid-tier request hits stale data:- The API returns the stale data immediately with
"source": "stale" - A background job is triggered to fetch fresh data from the source
- The fresh data is written to the database
- Your next request returns the updated data with
"source": "cached"
Live-first data (Business / Internal)
Business and Internal tier requests for property detail and building detail endpoints get live data automatically:- If cached data is older than 5 minutes (listings) or 30 minutes (buildings), the API fetches fresh data from the source synchronously
- The live data is returned immediately with
"source": "live" - The fresh data is also written back to the cache, keeping it warm for all tiers
- If the live fetch fails or times out (8-10 seconds), the API falls back to cached data with the standard async refresh behavior
GET /v1/property/{id}GET /v1/property/by-urlGET /v1/building/{id}
Best practices
- Check
meta.sourceto know if you’re reading stale data - For time-sensitive applications, use Pro or Business tier for tighter freshness thresholds
- Business tier gets live data on property and building detail — no need for SSE streams for single lookups
- If you need guaranteed-fresh data on Pro, use the listing stream endpoint for live SSE delivery