Skip to main content
Version: v1.0

Property Schema

Complete reference for the JSON format your API must return for each property. This document is the data contract between your CRM and Spot2 Ingestion.


Conventions

  • Field names in snake_case.
  • Dates in ISO 8601 format with timezone (e.g. 2026-06-29T14:30:00Z).
  • Text in UTF-8.
  • Numeric fields: decimal point, no thousands separator.
  • Empty arrays: [], not null.
  • Null fields (null): treated as absent.
  • Unknown fields: ignored. Only fields documented in this schema are processed.

JSON structure

Each property is represented as a JSON object with this structure:

{
"external_id": "prop-12345",
"property_type": "oficina",
"modality": "rent",
"title": "Oficina ejecutiva en Polanco",
"description": "Amplia oficina con vista panorámica...",
"updated_at": "2026-06-29T14:30:00Z",
"surface_m2": 120.5,
"land_m2": null,
"bedrooms": 0,
"bathrooms": 2.0,
"parking_spots": 3,
"photos": [
"https://cdn.your-crm.com/01.jpg",
"https://cdn.your-crm.com/02.jpg"
],
"price": {
"rent_price": 45000.00,
"sale_price": null,
"currency": "MXN"
},
"location": {
"latitude": 19.4326,
"longitude": -99.1332,
"street": "Av. Presidente Masaryk",
"ext_number": "123",
"int_number": "4A",
"neighborhood": "Polanco",
"city": "Ciudad de México",
"state": "Ciudad de México",
"postal_code": "11560"
},
"agent": {
"name": "Juan Pérez",
"email": "juan@broker.com",
"phone": "+525512345678"
},
"amenities": ["aire acondicionado", "elevador", "estacionamiento"],
"office": {
"floor_level": 5,
"floor_level_number": "Piso 5"
}
}

price object structure

FieldTypeDescription
rent_pricenumber or nullMonthly rent price. Required if modality is rent or rent_and_sale.
sale_pricenumber or nullSale price. Required if modality is sale or rent_and_sale.
currencystringISO 4217 code. Default MXN. See currency catalog.

location object structure

FieldTypeDescription
latitudenumber or nullDecimal latitude. Recommended.
longitudenumber or nullDecimal longitude. Recommended.
streetstringStreet. Required if sending coordinates.
ext_numberstringStreet number. Max 6 characters.
int_numberstringUnit or apartment number.
neighborhoodstringNeighborhood or district.
citystringCity. Required.
statestringState. Required.
postal_codestringPostal code.

agent object structure

FieldTypeDescription
namestringAgent or broker name.
emailstringEmail address. Recommended.
phonestringPhone number. Recommended.

Properties with rent and sale

When a property is available for both operations, send both prices and set modality to rent_and_sale:

{
"external_id": "prop-67890",
"property_type": "local",
"modality": "rent_and_sale",
"price": {
"rent_price": 35000.00,
"sale_price": 4500000.00,
"currency": "MXN"
},
"location": {
"city": "Monterrey",
"state": "Nuevo León"
},
"updated_at": "2026-06-29T10:00:00Z"
}

If you don't specify modality, it is determined automatically: only rent_price → rent, only sale_price → sale, both → rent_and_sale.


Required fields

Without these fields, the property will not be published.

FieldLocationTypeDescription
external_idrootstringUnique, immutable identifier. Max 255 characters.
property_typerootstringOne of the 7 canonical values. See catalog.
location.citylocationstringCity. Not empty.
location.statelocationstringState. Not empty.
price.rent_price or price.sale_pricepricenumberAt least one must be greater than 0.
updated_atrootstringLast modified in ISO 8601.

Catalog of property_type

Only these 7 values are accepted. Variants are recognized (e.g. "oficina virtual" is classified as office), but we recommend using the exact values.

ValueDescription
oficinaOffice, corporate suite
localRetail space, shop
bodegaStorage warehouse
nave_industrialIndustrial building, factory
terrenoLand, lot
edificioFull building
local_en_centro_comercialShopping center unit

Residential properties (house, apartment, home) are automatically rejected.


Catalog of modality

ValueMeaning
rentRent only
saleSale only
rent_and_saleBoth operations

Catalog of currency

ISO 4217 codes. Default MXN. Prices are converted to MXN using the day's exchange rate.

CodeCurrency
MXNMexican Peso
USDUS Dollar

If you send prices in a currency other than MXN and the exchange rate is unavailable, the property will not be published. We recommend sending prices in MXN.


If missing, the property is published but with reduced visibility.

FieldLocationTypeDescription
photosrootstring[]Photo URLs. Minimum 1 for public visibility.
location.latitude + location.longitudelocationnumberCoordinates. Without them the property doesn't appear on the map.
agent.email or agent.phoneagentstringAt least one contact method.

Optional fields

Identity

FieldLocationTypeDescription
titlerootstringListing title.
descriptionrootstringFree-form description.

Physical characteristics

FieldLocationTypeValidation
surface_m2rootnumber or nullBuilt area in m². If > 0, minimum 3 m².
land_m2rootnumber or nullLand area in m².
bedroomsrootinteger or nullBedrooms. Max 20.
bathroomsrootnumber or nullBathrooms. Decimals accepted (e.g. 1.5).
parking_spotsrootinteger or nullParking spaces.

Catalog of amenities

List of amenities we recognize. Each string you send is matched by keyword against this table (ignoring articles like "de", "la", "el"). Non-matching strings are ignored.

AmenityTerms that trigger it
Bañosbaño, baños, bathroom
Wifiwifi, internet
A/Caire acondicionado, climatización
Estacionamientoestacionamiento, parking, cochera
Bodegabodega, almacén
Accesibilidadaccesibilidad, rampa
Luzluz, electricidad
Sistema de seguridadseguridad, vigilancia, cámaras
Montacargasmontacargas
Pizarrónpizarrón, whiteboard
Elevadorelevador, ascensor
Terrazaterraza
Zona de limpiezalimpieza, cleaning
Divisibledivisible
Mezzaninemezzanine, entrepiso
Cocina equipadacocina equipada, kitchenette
Planta de luzplanta de luz, generador
Cocinacocina
Loftloft

Examples:

  • "aire acondicionado" → A/C
  • "estacionamiento para visitas" → Estacionamiento
  • "vigilancia 24/7" → Sistema de seguridad
  • "jardín" → ignored (no match)

Fields by property type

Some types require additional fields within an object named after the type.

Office ("property_type": "oficina" or "edificio")

The office object is optional but its fields are validated if sent.

FieldLocationTypeValidation
floor_levelofficeintegerFloor number (1 = ground floor). If 6, floor_level_number is required.
floor_level_numberofficestringFloor label (e.g. "Piso 5"). Required if floor_level is 6.

Example:

{
"property_type": "oficina",
"office": {
"floor_level": 5,
"floor_level_number": "Piso 5"
}
}

Industrial ("property_type": "nave_industrial" or "bodega")

FieldLocationTypeValidation
max_height_mindustrialnumberMaximum interior height. Max 30 meters.
min_area_divisible_m2industrialnumberMinimum divisible area. Must be ≤ max_area_divisible_m2.
max_area_divisible_m2industrialnumberMaximum divisible area. Must be ≥ min_area_divisible_m2.
luminariesindustrialintegerNumber of light fixtures. If > 0, luminary_specs is required.
luminary_specsindustrialstringLight fixture specifications. Required if luminaries > 0.

Example:

{
"property_type": "nave_industrial",
"industrial": {
"max_height_m": 12,
"min_area_divisible_m2": 200,
"max_area_divisible_m2": 2000,
"luminaries": 20,
"luminary_specs": "LED industrial 200W"
}
}

Retail ("property_type": "local" or "local_en_centro_comercial")

FieldLocationTypeValidation
price_per_sqm_minretailnumberMinimum price per m². Must be ≤ price_per_sqm_max.
price_per_sqm_maxretailnumberMaximum price per m². Must be ≥ price_per_sqm_min.

Example:

{
"property_type": "local",
"retail": {
"price_per_sqm_min": 200,
"price_per_sqm_max": 500
}
}

Land ("property_type": "terreno")

FieldLocationTypeValidation
land_useterrainstringLand use (e.g. comercial, industrial, mixto). Required for land.

Example:

{
"property_type": "terreno",
"terrain": {
"land_use": "industrial"
}
}

Price validations

  • Minimum price: monthly rent ≥ $10,000 MXN. Sale ≥ $100,000 MXN. Lower prices are rejected.
  • Price per m²: validated against statistical ranges by property type and modality. Out of range → reduced visibility.
  • Surface area: validated against statistical ranges by property type. Out of range → reduced visibility.

Currency conversion

If you send prices in a currency other than MXN:

  1. The day's exchange rate is queried.
  2. The price is converted to MXN.
  3. Validations are applied on the converted value.
  4. If the exchange rate is unavailable, the property is rejected.

The price shown on Spot2 is always in MXN. We recommend converting prices to MXN on your CRM side before sending.

Canonical schema vs CRM schema

The schema documented here is the canonical format Spot2 ingests after mapping. Your CRM may use different field names. Spot2 adapts via configuration during integration.

Example: Tokko → Spot2

Spot2 (canonical)Tokko (native)
property_typeoperation_category (mapped via TokkoOperationType)
price.rent_priceoperation_amount when operation_type = "Alquiler"
price.sale_priceoperation_amount when operation_type = "Venta"
price.currencyoperation_currency
location.cityDerived from operation_full_location
location.latitudegeo_lat
location.longitudegeo_long
photosphotos[].url
modalityDerived from operation_type values of the publication_ids_map