Listings

A key with properties:read reads your listings and the Agents, Places, Areas and amenities they refer to. To create and edit them through the API too, see Writing listings.

Reading listings

  • GET /v1/properties — a cursor page of listings in change order. Pass updated_since to fetch only what changed and include_archived=true to see archived (delisted) listings too.
  • GET /v1/properties/{property_id} — one listing by id.
  • GET /v1/properties/by-slug/{slug} — one listing by its slug. A retired slug still finds the listing; its slug is the current one, so redirect when they differ.
curl "https://api.letsrealty.io/v1/properties?limit=200&listing_type=sale" \
  -H "Authorization: Bearer $LETSREALTY_API_KEY"

The list also takes listing_type, place (a Place code: listings there or beneath it), area (an Area id), is_featured and q (the title or your internal reference).

Paging and syncing

Page with limit (up to 200) and the next_cursor of the previous page until it is null. To keep a copy in sync, page everything once, then poll with updated_since set a minute before the newest updated_at you have seen, and upsert by id. An archived listing comes back with archived: true when you pass include_archived=true. See Pagination.

Languages

A listing's title, description and highlights come in one of your Site Languages per response:

  • ?lang=es picks an enabled Site Language. Without it, the first enabled language in your Accept-Language header is used, and then your Default Language.
  • A lang that isn't enabled is a 422 that names the enabled ones.
  • lang in the response is the language the text is in, and available_langs lists every language the listing has text in. A listing without text in the language you asked for comes in your Default Language, or in the language it was written in when it has none in that either.
curl "https://api.letsrealty.io/v1/properties/by-slug/casa-tamarindo?lang=en" \
  -H "Authorization: Bearer $LETSREALTY_API_KEY"

A listing's place and areas names follow the language you asked for, too.

The gallery

images is the listing's gallery in order, each with its id, CDN url, is_primary and sort_order. primary_image_url is the hero image's URL, or null when none is marked.

The fields

  • Identity: id, slug, internal_ref (your own reference), title, description, highlights, lang, available_langs.
  • Price: listing_type, price, currency, rent_price (a sale listing also offered for rent), price_reduced_at, price_reduced_from.
  • The property: property_type, bedrooms, bathrooms, area, lot_area, parking_spaces, year_built, floor, hoa_fee, amenities.
  • Location: address, latitude, longitude, location_precision, place_code, place (its path and display strings), areas (slug and name), needs_location (no Place yet, so it isn't on your website).
  • Presentation: agent_id, is_featured, primary_image_url, images, video_url, tour_url.
  • State: archived, created_at, updated_at.

Private notes, import details and console statistics are never part of the API. The API reference has every field's type.

Agents, Places, Areas and amenities

The same key reads what a listing refers to:

  • GET /v1/agents — a cursor page of your Agents' public profiles (name, slug, photo, job title, bio, phone, email, social links, language and is_active), with updated_since. Deactivated Agents are left out unless you pass include_inactive=true, which a sync job should, to see them turn is_active: false. GET /v1/agents/{agent_id} reads one; a listing's agent_id names it. Logins are never part of it.
  • GET /v1/places — every Place your listings are on and every Place above them, shallowest first, each with its parent_code. A listing's place_code is one of them.
  • GET /v1/areas — a cursor page of your Areas with their slug and name in lang, with updated_since.
  • GET /v1/amenities — every key a listing's amenities can hold, with its group and its label in lang.

Places and amenities come as a single page: next_cursor is always null.