Public Property model

Source-reviewed draft; deployment and release verification pending.

Draft — source-reviewed on 22 October 2026. These are implemented DTOs, not a verified live deployment contract.

The public DTOs are allowlists. Do not use an internal CRM property type as the website TypeScript model.

Required summary fields

FieldWire type and meaning
public_idString public identifier, such as synthetic P9001; use it unchanged in detail/image URLs. It is not a database UUID.
operationSALES or RENTAL, matching the search context.
view_typesArray of supported view values; can be empty.
catalogsArray of active catalog membership keys; can be empty.
locationObject with numeric lat, lng and precision (EXACT or APPROXIMATE). Required on search summaries.

Optional summary fields

FieldsType and use
nameNullable string when present. Use an intentional UI fallback if absent. There is no title field.
priceNullable object with amount, currency, kind and period. See pricing below.
asking_price_per_m2Nullable decimal string for qualifying sales.
property_type, features_type, property_detail_typeNullable controlled classification strings.
bedrooms, bathroomsNullable integer counts.
total_area_m2Nullable number, in square metres.
city, regionNullable strings.
ubicacionNullable {key,label,city} LocalArea object.
location_factsNullable object of public contextual facts.
thumbnailNullable {asset_id,url,caption?} object.

The schemas allow null for these optional fields, but the current projection normally omits unpopulated fields rather than inserting null. Responses exclude unset values. A client should accept both missing and allowed-null values; neither means zero or false. Populated false, 0 and empty arrays must remain distinct from unknown values.

The public response does not include free-text area, complex_name, rental_type, updated_at or publication status, even though some of these concepts are accepted as search filters or used internally.

Detail fields

Detail requires public_id, operation, operations, prices, view_types, catalogs, characteristics and gallery. operations contains the supported contexts; prices contains available valid prices, each with an additional operation field. Arrays may be empty and characteristics may be {}.

Detail supports the optional summary fields except thumbnail. Its location is optional and nullable. It also supports:

  • description: nullable string.
  • description_translations: nullable language-to-string map; current projection accepts keys such as en or en-GB and drops invalid keys/non-string values.
  • characteristics: public characteristic object; see Marketing and characteristics.
  • gallery: up to 100 public images, each with asset_id, url, is_primary, display_order and optional nullable caption.
  • agent: optional nullable public agent card.
  • address_line: optional nullable string, supplied only when full address visibility permits a populated street/house-number line.

Detail selects SALES first when available if no operation query is supplied; otherwise it selects the supported context. Supplying an unsupported context returns 422. Preserve the selected context when navigating from cards.

Pricing rules

amount and asking_price_per_m2 are JSON strings, rounded to two decimal places; do not model them as floating-point financial values. Currency is EUR. A missing/invalid price omits price, and its context is absent from prices; it is not returned as zero.

Contextkindperiod
SaleSALEONE_OFF
Transfer, when sale is not selectedTRANSFERONE_OFF
RENTAL with SHORT_TERM source typeRENTDAY
RENTAL with TEMPORAL source typeRENTMONTH
RENTAL with LONG_TERM source typeRENTYEAR

If both sale and transfer are enabled, sale pricing takes precedence. asking_price_per_m2 appears only for a positive sale amount and positive total area; it uses source sale precision divided by area, rounded half up to cents. It is not a rental or investment return metric.

Rental period must be displayed explicitly. Do not convert an annual value to monthly without a separately approved UI calculation, or claim booking-date availability from operation eligibility. There is no availability calendar or availability field here.

Synthetic summary example

{
  "public_id": "P9001",
  "name": "Example coastal apartment",
  "operation": "SALES",
  "price": {"amount": "310000.00", "currency": "EUR", "kind": "SALE", "period": "ONE_OFF"},
  "property_type": "HOMES",
  "features_type": "FLAT",
  "property_detail_type": "PENTHOUSE_DUPLEX",
  "bedrooms": 2,
  "bathrooms": 2,
  "total_area_m2": 95,
  "city": "Example municipality",
  "view_types": ["SEA_AND_COAST"],
  "catalogs": [],
  "location": {"lat": 28.2, "lng": -16.6, "precision": "APPROXIMATE"}
}

This invented fixture is for design only; the location is not a derivation claim about a real property. Do not add private coordinates or investment values to examples.

Related operations

POST /api/v1/public/properties/search returns summary items. GET /api/v1/public/properties/{public_id} returns detail. Read Location and LocalAreas and Publication and privacy before displaying addresses or persistence controls.


Did this page help you?