Building property listings
Source-reviewed draft; deployment and release verification pending.
Draft — source-reviewed on 22 October 2026. Deployment, enabled capabilities and live data have not been verified. All examples are synthetic.
Purpose and data flow
Build listing cards from POST /api/v1/public/properties/search. First load GET /api/v1/public/property-reference?destination=TENERIFE for supported coverage and controlled values. Search requires a destination, one geometry area and filters.operation; a card grid without a visible map must still supply valid geometry, such as the reviewed destination extent. See Implementing map search.
A search response contains items, total, page, page_size and total_pages. Each item requires public_id, operation, view_types, catalogs and a public location. These are the literal response fields; the card title is supplied by optional name, not a title field.
Card fields and fallbacks
| Card element | Public field | UI behavior |
|---|---|---|
| Identity/link | public_id, operation | Keep the public identifier unchanged and preserve the operation when opening detail. |
| Heading | name | Use a product-approved fallback such as “Property P9001” if absent or null. |
| Price | price | Display amount, EUR currency, kind and period together; show “Price unavailable” if unknown. |
| Image | thumbnail | Use its public url; use a neutral placeholder if absent or unavailable. |
| Measurements | bedrooms, bathrooms, total_area_m2 | Render only known values; retain valid zero values. |
| Location label | city, region, ubicacion.label | Display supplied labels; do not invent an address from the map point. |
| Classification/badges | Classification tuple, catalogs, view_types | Use reviewed labels and reference metadata; memberships are independent of physical type. |
Optional fields may be omitted; their schemas also permit null. Do not replace unknown counts with zero or absent booleans with false. Empty arrays are valid. Search summaries have no agent object, description, availability calendar, rental_type, free-text area, complex_name or publication status.
The following is a complete synthetic minimal summary with optional display data:
{
"public_id": "P9001",
"name": "Example coastal apartment",
"operation": "SALES",
"price": {"amount": "425000.00", "currency": "EUR", "kind": "SALE", "period": "ONE_OFF"},
"bedrooms": 2,
"view_types": [],
"catalogs": [],
"location": {"lat": 28.15, "lng": -16.6, "precision": "APPROXIMATE"}
}Financial amounts are decimal strings. SALE and TRANSFER use ONE_OFF; RENT uses DAY, MONTH or YEAR. Never label a transfer price as a sale price or assume rental prices are monthly. Formatting belongs in a decimal-aware presentation adapter; do not change the API contract into floating-point money.
A card component may use a smaller proposed UI model, distinct from the response schema:
type PropertyCardView = {
key: string;
heading: string;
priceLabel: string;
imageUrl?: string;
};
// Adapt reviewed/generated public response types into this presentation model.
// Do not use PropertyCardView as an API response declaration.Interaction, states and privacy
Reset to page 1 when filters or geometry change. Only PUBLIC_ID_ASC sorting is supported. Use returned pagination metadata rather than guessing a total from the current page. A successful empty page can have a nonzero total when the requested page is beyond the last page. Separate requests are not one frozen catalog snapshot.
Show skeleton cards while initially loading, an explicit empty state for successful zero results, field guidance for 422, and bounded retry for temporary failures. Respect Retry-After for 429. Disabled API capability returns 404; show an unavailable state. Cancel or ignore obsolete searches. Do not retain a stale result as if it matched a newly selected filter.
Use only public URLs and projected data. An approximate point is not a private address. Follow Cache-Control: no-store; do not persist listings or images in an offline catalog. Private financial fields and investment notes must never be supplied to card components.
Related operations and guides
Search: POST /api/v1/public/properties/search; controlled metadata: GET /api/v1/public/property-reference; navigation target: GET /api/v1/public/properties/{public_id}. Card images use GET /api/v1/public/properties/{public_id}/images/{asset_id} via the supplied URL. Agent images belong to detail contact cards and use GET /api/v1/public/agent-images/{asset_id}; search does not supply them. See Rendering property details and Errors and pagination.
Updated 1 day ago