Properties
Property cards for search and listing pages, the property page in one call, and its neighborhood, reviews and Instagram feed.
Listing properties
GET /properties — the website's enabled properties as cards, in the website's own order unless sorted. On a property website this is the one property. Tags: site, plus property:{id} and inventory:{id} per property on the page.
| Parameter | |
|---|---|
q | Name contains |
group | A group id; includes descendants. Unknown id is a 404 |
city, state | Exact, case-insensitive. Values come from GET /facets |
available | Has (true) or lacks (false) an available unit |
beds | Bedroom counts, comma-separated; matches a property with an enabled floor plan of that size |
min_rent, max_rent | Budget bounds, matched against available units |
near, radius | near=30.2672,-97.7431, radius in kilometres (default 25). A bounding box, not a great-circle distance |
sort | name, order |
page, per_page | Default 50, ceiling 200 |
The card
{
"id": "01000000-0000-4000-8000-000000000002",
"slug": "contract-property",
"name": "Contract Property",
"path": "/property/contract-property",
"address": { "street": "100 Contract Way", "street_2": null, "city": "Austin", "county": "Travis", "state": "TX", "postal_code": "78701", "country": "US", "formatted": "100 Contract Way, Austin, TX, 78701, US" },
"location": { "lat": 30.2672, "lng": -97.7431 },
"timezone": "America/Chicago",
"image": null,
"phone": "+1 555 0100",
"rating": { "average": 4.5, "count": 2 },
"tags": [],
"units_count": 1,
"available_units_count": 1,
"floor_plans_count": 1,
"rent": { "min": 1500, "max": 1500, "base_min": 1500, "base_max": 1500 },
"pricing_display": {
"mode": "BASE_AND_TOTAL",
"hidden_price_label": "Call for Pricing",
"no_availability_price_label": "Call for Availability",
"no_price_label": "Call for Pricing",
"total_price_label": "Total Monthly Leasing Price"
}
}- Counts and rent bounds come from enabled, unhidden units; rent from the available ones.
imageis the property's own image; when it has none, an image from its first enabled image gallery (one taggedexteriorif there is one, else the first).ratingis the overall{ average, count }. Between them a listing page needs no galleries or reviews request per property.locationisnullwhen a coordinate is missing — never0,0.timezoneis the property's IANA timezone. Use it for office hours, "open now" and tour times;nullwhen the property has no address.rentvalues arenullwhen the property's pricing display settings hide them, or when no rent is known. Show a label frompricing_displayinstead:hidden_price_labelwhen the property hides all pricing,no_availability_price_labelwhen it hides prices with nothing available andavailable_units_countis 0,no_price_labelotherwise. See Inventory & pricing.
Rent filters never reveal a hidden price. When min_rent or max_rent is used, a property that hides its pricing is left out of the results rather than matched silently.
One property
GET /properties/{property} — the card, the property's details, and whichever sections the page renders, in one call. Tags: property:{id}, inventory:{id}.
| Parameter | |
|---|---|
include | Comma-separated: amenities, announcements, buildings, content, faqs, fees, galleries, groups, media, office_hours. Unknown is a 422 |
content_keys | With include=content: the block keys to return, comma-separated |
Always present, beyond the card:
| Key | Holds |
|---|---|
description | The property's marketing description |
contact | phones[], emails[], socials[] |
urls | website, resident_portal, application, tour_booking |
leasing | applicant_hold_period_days, availability_window_days |
pet_policy | description, restrictions |
pricing | The property's pricing display settings: pricing_display_mode, hide_all_pricing, hide_price_when_no_availability, hidden_price_label, no_availability_price_label, no_price_label, tmlp_label, show_fee_breakdown, fee_breakdown_behavior (EXPANDED or COLLAPSED), pricing_disclaimer_text. The API has already applied them to every price it returns. See Inventory & pricing |
has | Which sections hold anything |
has: skip what is empty
"has": { "amenities": true, "announcements": true, "buildings": true, "content": true, "faqs": true, "galleries": true, "neighborhood": true, "reviews": true, "instagram": true, "floor_plans": true, "available_units": true }has is always filled in, whatever you include. Read it to decide which sections to render, and which sub-resources are worth a request.
Included sections
Every includable key is always in the payload, and is null when not requested, so the shape never depends on the query string.
include | Returns |
|---|---|
amenities | id, name, code, description, type, is_marketable, tags, images[], videos[], virtual_tours[] |
announcements | Those current now: key (the identifier a template places it by), title, meta, text, disclaimer, image, links[], starts_at, ends_at |
buildings | number, code, name, type, description, image, images[], available_units_count, tags, groups[] |
content | Content blocks: key, type, media_type, title, subtitle, description, links[], images[], background_image, videos[], virtual_tours[], and items[] for multi-item blocks |
faqs | question, answer, tags, sort_order, and topic (id, title, description, sort_order, or null) — group by topic.id, order topics and questions by their sort_order |
fees | The property-wide fee schedule: lines[], monthly_total, monthly_total_max, upfront_total. Empty lines and null totals when pricing is hidden |
galleries | key (the identifier a template places it by), type (image, video, panorama, virtual_tour), title, text, images[], panoramas[], videos[], virtual_tours[] |
groups | The groups the property belongs to, each with its set |
media | The property's own media, apart from its galleries: property_images[] (the card's image is the first), images[], background_image, videos[], virtual_tours[] |
office_hours | The property's office hours settings: hours[] (day, time, both free text as entered, such as Monday - Friday and 9:00 AM - 5:00 PM), display_heading, disclaimer |
curl "$RESI_DELIVERY_API_URL/properties/contract-property?include=amenities,content,faqs&content_keys=hero,highlights" \
-H "Authorization: Bearer $RESI_DELIVERY_TOKEN" -H "X-Resi-Website: $RESI_WEBSITE_ID"An image anywhere in the API is { id, url, thumb_url, title, caption, alt_text, tags }. tags are the image's media-library tags ([] when none), for filtering a gallery to, say, exterior or pool. panoramas[] holds images in the same shape, meant for a 360° viewer; an image can appear in both images and panoramas.
Neighborhood
GET /properties/{property}/neighborhood?limit=100 — tag property:{id}. limit is 1–500, default 100, by name; meta.places gives { total, listed }.
origin— the property's name, address andlocation, for centring a map.categories[]— the account's categories:id,label,color,types, andin_use(whether any place below uses it).places[]—name,address,location,category_id,category,color,rating,website,google_maps_url,place_id,tags,images[], andtravel_times(drive,walk,bike,transit, in minutes,nullwhen unknown).
Reviews
GET /properties/{property}/reviews — published reviews, newest first. Tag property:{id}.
| Parameter | |
|---|---|
source | Review sources, comma-separated (for example google_business_profile) |
rating[gte] | Range operators gte, lte, gt, lt |
sort | date, rating |
page, per_page | Default 20, ceiling 100 |
Each review carries reply — { text, replied_at } for the property's published response, or null.
meta.rating always carries the property's overall { average, count }, regardless of the filters applied, so a "4.5 from 212 reviews" badge needs no second request.
GET /properties/{property}/instagram?limit=12 — the most recent posts (limit 1–50). An empty list, not an error, when the property has no enabled Instagram connection. Each post: type, caption, hashtags[], permalink, posted_at, and media[] of { type, url, thumbnail_url }.
Last updated on