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.
| Endpoint | Tipo | Registros | Devuelve |
|---|---|---|---|
| /api/v1/index.jsonÍndice del servicio | Utilidad | — | 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.jsonPropiedades | Colección | 8,737 | Todas 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 propiedad | Registro 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.jsonEdificios | Colección | 274 | Todos los edificios publicados, con su disponibilidad actual y su precio de entrada. |
| /api/v1/buildings/{slug}.jsonUn edificio | Registro individual | — | La proyección completa, más todas las unidades que seguimos en ese edificio. |
| /api/v1/neighborhoods.jsonSectores | Colección | 57 | Todos los sectores, con recuentos de edificios y propiedades que coinciden con las páginas del directorio. |
| /api/v1/neighborhoods/{slug}.jsonUn sector | Registro individual | — | La proyección completa, más los edificios del sector y su inventario actual. |
| /api/v1/agents.jsonAsesores | Colección | 3 | El equipo público. La remuneración, las licencias y la producción interna no forman parte del tipo proyectado. |
| /api/v1/agents/{slug}.jsonUn asesor | Registro individual | — | Perfil, cobertura y las propiedades que representa. |
| /api/v1/articles.jsonContenido editorial | Colección | 3 | Artículos y guías publicados, del más reciente al más antiguo. |
| /api/v1/articles/{slug}.jsonUn artículo | Registro individual | — | Incluye el cuerpo en markdown. |
| /api/v1/home.jsonComposición de la página de inicio | Utilidad | — | 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.jsonContadores | Utilidad | — | 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úsqueda | Utilidad | — | 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
@widthantes de la extensión.