Overview
Returns a JSON array of every unit in a building that is flagged advertised_on_website: true. Use it to power a building's listings page, a unit picker on a tour-request form, or any frontend that needs an up-to-date catalog of what's available.
- One building per request, identified by its
token. - Narrow the results with optional query-parameter filters — beds, baths, rent, outdoor space, status, and more. See Filtering & search.
- Units that aren't advertised on the website are excluded from the response.
- Units whose price is marked private (
price_advertised: false) are still returned, but withmonthly_rent_grossandmonthly_rent_netset tonull.
Authentication
There is no API key or bearer token. Each building has its own opaque token, and you pass it as a query parameter to fetch that building's units.
- A SeeClickRent admin issues the token to you when your integration is set up.
- It's the same token you'd use with the Website Leads API — one token per building, used for both reading units and posting leads.
- Treat the token like a shared secret — anyone with it can read advertised inventory for that building.
Rate limits
- 300 requests per 5 minutes per source IP across the entire
/api/*namespace. - Excess requests get an HTTP
429 Too Many Requestswith aRetry-Afterheader (in seconds) and this body:
{
"error": {
"message": "throttled",
"human_message": "Too many requests. Please try again later."
}
}
If you're rendering a high-traffic listings page, cache the response on your end (a few minutes is usually plenty — inventory doesn't change second-to-second). Contact SeeClickRent if you need a higher limit.
Request
Headers
Accept: application/json
Query parameters
Only token is required. Every other parameter is an optional filter — combine as many as you like to narrow the results (see Filtering & search). Omitting all filters returns every advertised unit.
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
string | Required | Building token issued by SeeClickRent. Identifies which building's units to return. |
bed |
integer (comma-separated) | Optional | Exact bedroom count(s). 0 means studio. Accepts a list, e.g. bed=1 or bed=0,1. |
bath |
number | Optional | Minimum number of bathrooms (bath >= value). bath=1 returns units with 1 or more baths, including 1.5. |
min_rent |
number | Optional | Minimum gross monthly rent (monthly_rent_gross >= value). |
max_rent |
number | Optional | Maximum gross monthly rent (monthly_rent_gross <= value). |
min_square_feet |
integer | Optional | Minimum square footage (square_feet >= value). |
outdoor |
string (comma-separated) | Optional | Outdoor space type. Use any for "has any outdoor space", or one or more of balcony, terrace, patio, garden, rooftop, yard. e.g. outdoor=any or outdoor=balcony,terrace. |
status |
string (comma-separated) | Optional | Leasing status. One or more of available, rented, not_available. e.g. status=available. |
available_by |
string (date) | Optional | Only units available on or before this YYYY-MM-DD date (date_available <= value). |
Example
GET /api/v1/building_units?token=abc123def456 HTTP/1.1
Host: seeclickrent.com
Accept: application/json
Filtering & search
All filtering happens server-side via query parameters — there is no separate search endpoint. Each filter you add is combined with AND, so the response only contains units that match every filter. Parameters you leave off are simply not applied.
bedmatches exactly and accepts a comma-separated list (e.g.bed=0,1for studios and one-bedrooms).bath,min_rent,max_rent, andmin_square_feetare range bounds (greater-than-or-equal / less-than-or-equal), not exact matches.outdoorandstatusaccept a comma-separated list and match any of the listed values. Unrecognized values are ignored.- Filtering never overrides the base rules: units that aren't
advertised_on_websiteare always excluded, and private-price units still return withnullrent.
Common recipes
| You want… | Query string |
|---|---|
| Just the one-bedrooms | ?token=YOUR_TOKEN&bed=1 |
| Studios and one-bedrooms | ?token=YOUR_TOKEN&bed=0,1 |
| Two-beds with at least one bath | ?token=YOUR_TOKEN&bed=2&bath=1 |
| Anything with outdoor space | ?token=YOUR_TOKEN&outdoor=any |
| Only units with a balcony or terrace | ?token=YOUR_TOKEN&outdoor=balcony,terrace |
| One-beds under $4,000/mo that are available | ?token=YOUR_TOKEN&bed=1&max_rent=4000&status=available |
| Move-in ready by Sept 1, 2026 | ?token=YOUR_TOKEN&available_by=2026-09-01 |
--data-urlencode in cURL or URLSearchParams in JavaScript) so commas and other characters survive intact.
Response
200 OK — success
Returns a JSON array. Each element represents one advertised unit. The array is empty ([]) if the building has no units flagged for the website.
[
{
"id": 9821,
"building_id": 412,
"floor": 2,
"unit": "2A",
"bed": 1,
"bath": 1.0,
"exposure": "South",
"outdoor": "balcony",
"status": "available",
"monthly_rent_gross": 3200.0,
"monthly_rent_net": 2933.33,
"square_feet": 675,
"weeks_free": 4,
"months_free": 1,
"lease_term": 13,
"floor_plan": {
"original": "https://seeclickrent.com/rails/active_storage/blobs/.../floor-plan.pdf",
"thumbnail": "https://seeclickrent.com/rails/active_storage/representations/.../floor-plan.png"
},
"images": [
{
"original": "https://seeclickrent.com/rails/active_storage/blobs/.../living-room.jpg",
"thumbnail": "https://seeclickrent.com/rails/active_storage/representations/.../living-room.jpg"
}
],
"price_advertised": true,
"date_available": "2026-06-01",
"created_at": "2026-04-12T18:22:13.000Z",
"updated_at": "2026-05-02T10:14:55.000Z"
}
]
Field reference
Every object in the response array contains the following keys:
| Field | Type | Description |
|---|---|---|
id |
integer | SeeClickRent unit ID. Stable across requests; safe to persist as a foreign key on your side. |
building_id |
integer | SeeClickRent building ID. The same value for every unit in the response. |
floor |
integer | null | Floor number the unit is on. |
unit |
string | Unit label, e.g. "2A", "PHB". |
bed |
integer | Number of bedrooms. 0 represents a studio. |
bath |
number | Number of bathrooms. May be a half-step value, e.g. 1.5. |
exposure |
string | null | Window exposure, e.g. "North", "South/East". |
outdoor |
string | Outdoor space type: one of "none", "balcony", "terrace", "patio", "garden", "rooftop", "yard". Filterable via the outdoor query parameter. |
status |
string | Current leasing status of the unit (e.g. "available", "applied", "leased"). |
monthly_rent_gross |
number | null | Advertised monthly rent before concessions. null when price_advertised is false. |
monthly_rent_net |
number | null | Effective monthly rent after spreading concessions across the lease term. null when price_advertised is false. |
square_feet |
integer | string | Square footage when the building advertises it; otherwise the literal string "N/A". |
weeks_free |
integer | null | Number of free weeks offered as a concession. |
months_free |
number | null | The same concession expressed in months (derived from weeks_free). |
lease_term |
integer | null | Lease term in months that the concession is calculated against. |
floor_plan |
object | null | Floor plan attachment. See Images and floor plans. |
images |
array of objects | Unit photos in upload order. Empty array if the unit has no images. |
price_advertised |
boolean | Whether the building advertises this unit's price publicly. When false, the rent fields are blanked out (see above). |
date_available |
string (date) | null | Move-in date in YYYY-MM-DD format. |
created_at |
string (ISO 8601 datetime) | When the unit record was created in SeeClickRent. |
updated_at |
string (ISO 8601 datetime) | When the unit record was last modified. Useful for cache invalidation on your side. |
Images and floor plans
Both floor_plan and each entry in images use the same shape:
{
"original": "https://seeclickrent.com/rails/active_storage/blobs/.../photo.jpg",
"thumbnail": "https://seeclickrent.com/rails/active_storage/representations/.../photo.jpg"
}
originalis the full-resolution upload.thumbnailis a 400x400 contained variant, generated lazily on first request — the first hit may be slightly slower while it's processed; subsequent hits are served from cache.thumbnailmay benullfor non-image attachments (e.g. PDF floor plans without a renderable preview).floor_planitself isnullif no floor plan has been uploaded.- URLs are signed and long-lived but not guaranteed to be permanent — always re-fetch from this endpoint rather than caching URLs forever.
Code samples
# All advertised units for the building
curl -G https://seeclickrent.com/api/v1/building_units \
-H "Accept: application/json" \
--data-urlencode "token=abc123def456"
# Filtered: 2-bedrooms with at least 1 bath and outdoor space
curl -G https://seeclickrent.com/api/v1/building_units \
-H "Accept: application/json" \
--data-urlencode "token=abc123def456" \
--data-urlencode "bed=2" \
--data-urlencode "bath=1" \
--data-urlencode "outdoor=any"
const token = "abc123def456";
// Build a filtered query: just the one-bedrooms under $4,000/mo
const params = new URLSearchParams({
token,
bed: "1",
max_rent: "4000",
status: "available",
});
const url = `https://seeclickrent.com/api/v1/building_units?${params}`;
const response = await fetch(url, {
method: "GET",
headers: { "Accept": "application/json" },
});
if (response.ok) {
const units = await response.json();
console.log(`Loaded ${units.length} units`);
} else {
console.error("Failed to load units:", response.status);
}
import requests
# Studios and one-bedrooms with a balcony or terrace
resp = requests.get(
"https://seeclickrent.com/api/v1/building_units",
params={
"token": "abc123def456",
"bed": "0,1",
"outdoor": "balcony,terrace",
},
headers={"Accept": "application/json"},
timeout=10,
)
if resp.status_code == 200:
units = resp.json()
print(f"Loaded {len(units)} units")
elif resp.status_code == 429:
retry_after = int(resp.headers.get("Retry-After", "60"))
print(f"Throttled, retry in {retry_after}s")
else:
print(f"Failed: {resp.status_code} {resp.text}")
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Empty array [] returned for a building you know has units |
None of the units are flagged advertised_on_website: true in SeeClickRent, or an invalid token was supplied. |
Have your leasing team check the website-advertising flag on each unit, and confirm the token is correct. |
| A filter seems to have no effect | Unrecognized outdoor/status values are ignored, and filters AND together — an over-tight combination can return []. |
Check spelling against the allowed values in Filtering & search, and loosen filters one at a time. |
monthly_rent_gross and monthly_rent_net are null |
The unit is intentionally not advertising its price (price_advertised: false). |
If pricing should be public, flip the price-advertised toggle on the unit in SeeClickRent. |
| First load of a thumbnail is slow | Active Storage variants are generated lazily on first request. | Pre-warm by hitting the thumbnail URLs once after upload, or accept the one-time delay. |
square_feet comes back as the string "N/A" instead of a number |
The building chose not to advertise square footage for this unit. | Render "N/A" verbatim, or treat any non-numeric value as missing. |
429 Too Many Requests |
Hit the 300-per-5-minute IP throttle. | Honor the Retry-After header. Cache responses for a few minutes; contact SeeClickRent for a higher limit. |
5xx errors |
Transient server-side issue. | Retry with exponential backoff. The endpoint is read-only, so retries are safe. |
Support
For tokens, building setup, or rate-limit increases, reach out to your SeeClickRent point of contact or contact us.