Desarrolladores

Referencia de la API

Proyecciones JSON de solo lectura del directorio publicado: las mismas estructuras con las que se genera el propio sitio web.

Esta página también está disponible en /api.

Todas las respuestas van envueltas

{
  "api_version": "1.0",
  "generated_at": "2026-08-03T09:35:00.000Z",
  "count": 8737,
  "data": [ … ]
}

count solo aparece en las colecciones. api_version se incrementa cuando un campo se elimina o cambia de significado; añadir uno no es un cambio incompatible, así que los clientes deben ignorar las propiedades desconocidas.

Endpoints

Las colecciones devuelven resúmenes; los registros individuales, la proyección completa.

EndpointTipoRegistrosDevuelve
/api/v1/index.jsonÍndice del servicioUtilidad—Cada colección, su tamaño y la plantilla de un registro individual. Empiece aquí: un cliente debería poder descubrir la API sin leer esta página.
/api/v1/properties.jsonPropiedadesColección8,737Todas las propiedades publicadas, en formato de resumen. Sin paginar: todo el directorio en una sola solicitud en lugar de las varias que haría un cliente paginado.
/api/v1/properties/{slug}.jsonUna propiedadRegistro individual—La proyección completa, más la comparación de valor derivada y propiedades similares: las mismas cifras que muestra la página, para que el cliente no tenga que repetir los cálculos.
/api/v1/buildings.jsonEdificiosColección274Todos los edificios publicados, con su disponibilidad actual y su precio de entrada.
/api/v1/buildings/{slug}.jsonUn edificioRegistro individual—La proyección completa, más todas las unidades que seguimos en ese edificio.
/api/v1/neighborhoods.jsonSectoresColección57Todos los sectores, con recuentos de edificios y propiedades que coinciden con las páginas del directorio.
/api/v1/neighborhoods/{slug}.jsonUn sectorRegistro individual—La proyección completa, más los edificios del sector y su inventario actual.
/api/v1/agents.jsonAsesoresColección3El equipo público. La remuneración, las licencias y la producción interna no forman parte del tipo proyectado.
/api/v1/agents/{slug}.jsonUn asesorRegistro individual—Perfil, cobertura y las propiedades que representa.
/api/v1/articles.jsonContenido editorialColección3Artículos y guías publicados, del más reciente al más antiguo.
/api/v1/articles/{slug}.jsonUn artículoRegistro individual—Incluye el cuerpo en markdown.
/api/v1/home.jsonComposición de la página de inicioUtilidad—Todo lo que muestra la página de inicio, en una sola respuesta: el carrusel destacado, la torre del mes con sus modelos, el sector de esa torre, las propiedades más recientes, los sectores destacados, los contadores y los promedios de mercado de la ciudad. Las reglas de selección son editoriales y residen en el servidor, así que un cliente no puede desviarse de ellas.
/api/v1/stats.jsonContadoresUtilidad—La misma función con la que se genera la barra de confianza, así que un panel basado en este endpoint no puede contradecir el pie del propio sitio.
/api/v1/search.jsonÍndice de búsquedaUtilidad—Una fila por registro de todos los tipos, con el texto de búsqueda ya en minúsculas para que el cliente no tenga que normalizarlo en cada pulsación.

Las rutas de registro individual usan el mismo slug que la página: /properties/{slug} en el sitio es /api/v1/properties/{slug}.json aquí. Cada página declara además sus propios datos con <link rel="alternate" type="application/json">.

Qué está garantizado

Sin datos internos

Se genera a partir de las mismas proyecciones que usa el sitio web. Los precios mínimos, los contactos de propietarios, las direcciones completas, las notas internas, los documentos privados y la remuneración de los asesores quedan fuera por diseño, y una auditoría busca los valores reales en el resultado compilado.

Las coordenadas son aproximadas

Se guardan con precisión de sector para proteger la privacidad del propietario. No las trate como una dirección exacta.

Los precios reservados son null

`price_visible: false` significa que el precio no es publicable, y `price` es null en lugar de un número que no debería mostrar. Respételo.

Los valores null son reales

Un campo de tipo `number | null` es null en algunos registros. No lo sustituya por cero: así es como un promedio pasa a ser incorrecto en lugar de simplemente faltar.

Errores

Detalles de problema según RFC 9457. Un solo manejador de errores, no uno por endpoint.

Cada error devuelve application/problem+json con un type, un title y un status. Compare por type: es una URI estable, y al abrirla en un navegador llega a la página que describe ese error. Los errores de validación añaden un arreglo errors con un JSON Pointer por campo, de modo que un 422 se convierte en un mensaje junto al campo correcto y no en una notificación genérica.

{
  "type": "https://casanova.realty/problems/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "1 field failed validation.",
  "instance": "/api/v1/properties/luxor-500-3402",
  "errors": [
    {
      "pointer": "/pricing/sale_price_cents",
      "detail": "must be an integer"
    }
  ]
}

Qué añade el servicio

Los archivos de aquí son estáticos. El servicio que los reemplaza hace lo que una compilación estática no puede; todo ello ya está desarrollado, aunque nada está activo todavía en este servidor:

  • Paginación por clave y filtrado: desarrollado. Los nombres de los parámetros coinciden con los de los filtros del sitio.
  • ?updated_since= para sincronización incremental: desarrollado. Cada registro incluye updated_at.
  • ETag e If-None-Match: desarrollado, con comparación débil según RFC 9110.
  • Endpoints de escritura con If-Match e Idempotency-Key: desarrollado.
  • Eliminación de datos privados en el servidor: desarrollado. Cada respuesta se proyecta mediante una lista de campos permitidos y se vuelve a comprobar al salir.
  • Límite de solicitudes: desarrollado. Cada respuesta incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset.

CORS y caché

Access-Control-Allow-Origin: *
El contenido es público por definición.
Cache-Control: public, max-age=0, must-revalidate
Igual que el HTML. El directorio cambia, y una propiedad desactualizada es peor que una petición adicional.
Fotografía
Las URL de las imágenes son relativas a la raíz. Cada fotografía tiene siete anchos derivados (160, 240, 320, 480, 640, 960 y 1280) mediante el sufijo @width antes de la extensión.