/api/v1/auth/whoamiSanity check. Returns the organization, scopes, rate limit, and allowed regions for your key.
The Housing Data API provides read-only access to Range Lab’s curated housing dataset. Use it to display rental and affordable-housing inventory inside your own product or workflow.
https://basecamp.rangelab.ioSend the API key on every request in the x-api-key header.
Each endpoint requires one of the partner scopes:
properties:read — rental property endpoints (/api/v1/properties*, /api/v1/metadata/*, and the rentals partner exports).sales:read — for-sale endpoints (/api/v1/sales* and the sales partner exports).housing-resources:read — community housing resources (/api/v1/housing-resources* and the matching partner exports). Read-only projection of the shared resources table.Scopes are independent — a key can hold any combination, and an admin can grant additional scopes to an existing key without forcing a reissue. Contact partners@rangelab.io to add a scope to a key you already have.
curl -H "x-api-key: rl_live_..." \
https://basecamp.rangelab.io/api/v1/auth/whoamiKeys are shown exactly once at issuance. Store them in a secret manager; never commit them to source control.
/api/v1/auth/whoamiSanity check. Returns the organization, scopes, rate limit, and allowed regions for your key.
/api/v1/healthAuthenticated heartbeat endpoint for partner monitoring and connection validation.
/api/v1/propertiesList properties with filters. Requires the `properties:read` scope. Region filters are additionally ANDed with the key's allowlist.
| Parameter | Type | Description |
|---|---|---|
| city | string | Exact city match. |
| state | string | Two-letter state code (uppercased). |
| zip_code | string | Exact ZIP match. |
| beds | number | Exact bed count. |
| baths | number | Exact bath count. |
| min_price | number | Minimum monthly price. |
| max_price | number | Maximum monthly price. |
| updated_since | ISO 8601 | Only rows updated at or after this time. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. Default json. |
| fields | "core" | "full" | Optional, CSV only. "full" adds description, images, fees, amenities, and other rich columns. Default core. |
/api/v1/properties/:idFetch a single property by ID. Returns 404 if the property is outside the key's region scope.
/api/v1/properties/countReturn count-only totals for a filter set (same filter parameters as /api/v1/properties).
| Parameter | Type | Description |
|---|---|---|
| city | string | Exact city match. |
| state | string | Two-letter state code (uppercased). |
| zip_code | string | Exact ZIP match. |
| beds | number | Exact bed count. |
| baths | number | Exact bath count. |
| min_price | number | Minimum monthly price. |
| max_price | number | Maximum monthly price. |
| updated_since | ISO 8601 | Only rows updated at or after this time. |
/api/v1/properties/changesIncremental sync feed ordered by updated_at ascending. Useful for pull-based mirrors. Requires `properties:read`.
| Parameter | Type | Description |
|---|---|---|
| updated_since | ISO 8601 | Recommended for incremental fetches. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. Default json. |
| fields | "core" | "full" | Optional, CSV only. Same column set as /properties. |
| city | string | Optional exact city match. |
| state | string | Optional two-letter state code. |
| zip_code | string | Optional exact ZIP match. |
/api/v1/salesList for-sale listings with filters. Requires the `sales:read` scope. Region filters are ANDed with the key's allowlist; the key may also carry a county allowlist.
| Parameter | Type | Description |
|---|---|---|
| city | string | Exact city match. |
| state | string | Two-letter state code (uppercased). |
| zip_code | string | Exact ZIP match. |
| county | string | Exact county match. |
| beds | number | Exact bed count. |
| baths | number | Exact bath count. |
| min_price | number | Minimum sale price. |
| max_price | number | Maximum sale price. |
| property_type | string | Optional exact match. |
| home_type | string | Optional exact match (e.g. single_family). |
| listing_status | string | Optional exact match. |
| market_status | string | Optional exact match. |
| updated_since | ISO 8601 | Only rows updated at or after this time. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. |
| fields | "core" | "full" | Optional, CSV only. "full" adds zpid, source, full_address, lot_size, description, images, broker_name, broker_phone. |
/api/v1/sales/changesSales incremental sync feed ordered by updated_at ascending. Same filter set as /sales. Requires `sales:read`.
| Parameter | Type | Description |
|---|---|---|
| updated_since | ISO 8601 | Recommended for incremental fetches. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. |
| fields | "core" | "full" | Optional, CSV only. Same column set as /sales. |
/api/v1/housing-resourcesCommunity housing resources — rental assistance, housing programs, and utility assistance. Read-only projection of the shared `resources` table, scoped to housing-related categories. Requires the `housing-resources:read` scope. Location columns are `service_state` / `service_city` / `service_county`; the key's allowlist is matched against these and accepts either 2-letter or full state names, and either bare or `"County"`-suffixed county names.
| Parameter | Type | Description |
|---|---|---|
| city | string | Exact service_city match. |
| state | string | Either 2-letter abbrev or full state name. |
| county | string | Bare county name; "County" suffix is added/stripped automatically. |
| category | string | Optional. Defaults to all housing-related categories (housing-assistance, housing, utilities). Pass a value within that set to narrow; values outside it return no rows. |
| subcategory | string | Optional. Specific program label, matched case-insensitively against the row's `subcategory` (e.g. "rental assistance", "weatherization", "utility assistance", "homebuyer education"). Each row in the resources table is one program; this filter narrows to a specific one. |
| updated_since | ISO 8601 | Only rows updated at or after this time. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. |
| fields | "core" | "full" | Optional, CSV only. "full" adds description, eligibility_summary, required_documents, hours_of_operation, and the structured_hours JSON blob. |
/api/v1/housing-resources/changesHousing-resources incremental sync feed ordered by updated_at ascending. Same baseline and filter set as /housing-resources. Requires `housing-resources:read`.
| Parameter | Type | Description |
|---|---|---|
| updated_since | ISO 8601 | Recommended for incremental fetches. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. |
| fields | "core" | "full" | Optional, CSV only. Same column set as /housing-resources. |
/api/v1/properties/searchText search on property name and address fields.
| Parameter | Type | Description |
|---|---|---|
| q | string | Required text query. |
| city | string | Optional exact city filter. |
| state | string | Optional two-letter state code. |
| zip_code | string | Optional ZIP filter. |
| min_price | number | Optional minimum monthly price. |
| max_price | number | Optional maximum monthly price. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. Default json. |
/api/v1/properties/nearbyGeo-radius query around a coordinate. Returns region-scoped active properties.
| Parameter | Type | Description |
|---|---|---|
| lat | number | Required latitude. |
| lng | number | Required longitude. |
| radius_miles | number | Optional radius. Default 10, max 200. |
| limit | number | Max 100 for JSON, 50,000 for CSV. Default 20. |
| offset | number | Pagination offset. Default 0. |
| format | "csv" | "json" | Optional. Pass format=csv to stream a CSV download instead of JSON. Default json. |
/api/v1/properties/:id/similarReturns a small set of similar properties in the same market area.
| Parameter | Type | Description |
|---|---|---|
| limit | number | Optional. Default 10, max 50. |
/api/v1/metadata/filtersDiscover available filter dimensions (cities/states/types) and numeric ranges.
/api/v1/metadata/citiesRegion-scoped city inventory with per-city property counts.
/api/partner/exports/propertiesCSV export of properties scoped to the partner's active keys carrying `properties:read`. Partner-portal session auth, not x-api-key. Same filter set as /api/v1/properties.
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional. "full" includes description, images, fees, amenities, etc. |
| limit | number | Max 50,000. |
| city | string | Optional exact city match. |
| state | string | Optional two-letter state code. |
| zip_code | string | Optional exact ZIP match. |
| beds | number | Optional exact bed count. |
| baths | number | Optional exact bath count. |
| min_price | number | Optional minimum price. |
| max_price | number | Optional maximum price. |
| updated_since | ISO 8601 | Optional cutoff. |
/api/partner/exports/changesCSV export of property changes, ascending by updated_at. Recommended for daily sync. Requires `properties:read`.
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional column set. |
| updated_since | ISO 8601 | Pass the previous run's cursor. |
| limit | number | Max 50,000. |
/api/partner/exports/citiesReference CSV of cities in scope (city, state, listing count). Requires `properties:read`.
/api/partner/exports/salesCSV export of sale listings scoped to the partner's active keys carrying `sales:read`. Honors `allowed_counties` on the key (the `property_sale_listings` table has the column; rentals does not).
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional column set; "full" adds zpid, source, broker contact, etc. |
| limit | number | Max 50,000. |
| city | string | Optional exact city match. |
| state | string | Optional two-letter state code. |
| county | string | Optional exact county match. |
| zip_code | string | Optional exact ZIP match. |
| min_price | number | Optional minimum sale price. |
| max_price | number | Optional maximum sale price. |
| home_type | string | Optional exact match. |
| updated_since | ISO 8601 | Optional cutoff. |
/api/partner/exports/sales/changesCSV export of sale-listing changes, ascending by updated_at. Requires `sales:read`.
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional column set. |
| updated_since | ISO 8601 | Pass the previous run's cursor. |
| limit | number | Max 50,000. |
/api/partner/exports/housing-resourcesCSV export of housing-related community resources (rental assistance, housing programs, utility assistance). Requires `housing-resources:read`. Scoped to the partner's allowlist against `service_state` / `service_city` / `service_county`.
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional. "full" includes description, eligibility, required documents, hours, structured_hours. |
| limit | number | Max 50,000. |
| city | string | Optional exact service_city match. |
| state | string | Optional state (2-letter or full name). |
| county | string | Optional bare county; "County" suffix handled automatically. |
| category | string | Optional, must be within the housing baseline set. |
| subcategory | string | Optional case-insensitive program label (e.g. "rental assistance"). |
| updated_since | ISO 8601 | Optional cutoff. |
/api/partner/exports/housing-resources/changesCSV export of housing-resources changes, ascending by updated_at. Requires `housing-resources:read`.
| Parameter | Type | Description |
|---|---|---|
| fields | "core" | "full" | Optional column set. |
| updated_since | ISO 8601 | Pass the previous run's cursor. |
| limit | number | Max 50,000. |
curl -G "https://basecamp.rangelab.io/api/v1/properties" \
-H "x-api-key: rl_live_..." \
--data-urlencode "city=Medford" \
--data-urlencode "state=OR" \
--data-urlencode "limit=20"const res = await fetch(
"https://basecamp.rangelab.io/api/v1/properties?city=Medford&state=OR&limit=20",
{ headers: { "x-api-key": process.env.RANGE_LAB_API_KEY } }
);
const { data, meta } = await res.json();{
"data": [
{
"id": "uuid",
"property_name": "Example Apartments",
"city": "Medford",
"state": "OR",
"price": 1450,
"beds": 2,
"baths": 1,
"availability": "available",
"images": [],
"detail_url": ""
}
],
"meta": {
"total": 120,
"limit": 20,
"offset": 0
}
}| Status | Error | Meaning |
|---|---|---|
| 400 | bad_request | Malformed request (e.g. missing id). |
| 401 | missing_header / invalid_key / key_inactive | Bad or missing x-api-key header. |
| 403 | client_inactive / forbidden | Client paused/revoked or missing scope. |
| 404 | not_found | Resource not found or outside your region scope. |
| 429 | rate_limited | Per-minute rate limit exceeded. Honor Retry-After. |
| 500 | internal_error | Unexpected server error. |
Each key has a per-minute quota (default 60). When exceeded, the response is 429 with a Retry-After header indicating seconds to wait.
Append ?format=csv to any list endpoint to receive a streaming CSV download instead of JSON. CSV requests may use a higher limit (up to 50,000) and return a Content-Disposition: attachment header so browsers prompt a save.
/properties, /properties/changes, /properties/search, /properties/nearby, /properties/:id/similar, /metadata/cities), the sales endpoints (/sales, /sales/changes), and the housing-resources endpoints (/housing-resources, /housing-resources/changes).x-api-key auth, same rate limit, same region scoping as JSON.fields=full swaps in an extended column set (description, images, structured fields). Default is a leaner core column set suited for ETL pipelines./changes variant of each endpoint with updated_since over repeating a full snapshot.50,000 rather than the PostgREST default of 1,000.curl -G "https://basecamp.rangelab.io/api/v1/properties?format=csv&limit=10000" \
-H "x-api-key: rl_live_..." \
-o rangelab-properties.csvThe Housing Data API is currently in limited partner preview. To request a key, email partners@rangelab.io with your organization name, intended use, and the regions you need to cover.