API de valuación

Un valor de referencia reproducible para cualquier propiedad de la Ciudad de Buenos Aires, con rango de confianza, comparables y una explicación en lenguaje claro. Base URL: https://api.zavaluo.com/v1. Todas las respuestas son JSON en UTF-8.

Mercado disponible: CABA (venta y alquiler). Costa del Sol (España) más adelante; el campo country de cada request lo anticipa.
Estado: calibración. Las estadísticas por barrio y el catálogo de barrios ya se sirven. El modelo de valuación se está calibrando con los primeros comparables: POST /valuations valida el request y responde 503 hasta que esté activo. Avisamos por email a las claves emitidas.

Autenticación

Cada request lleva tu clave en el header Authorization. Guardamos solo el hash de la clave: si la perdés, emitimos una nueva.

Authorization: Bearer zv_live_9f3c…

Pedí una clave en Acceso a la API. El plan Explorar incluye 100 requests por mes; los demás planes, su cuota correspondiente.

Primer request

# curl
curl -X POST https://api.zavaluo.com/v1/valuations \
  -H "Authorization: Bearer $ZAVALUO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"Gorriti 4800, Palermo, CABA","kind":"apartment","m2_total":68,"rooms":3,"floor":2}'

// JavaScript (fetch)
const r = await fetch("https://api.zavaluo.com/v1/valuations", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.ZAVALUO_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ address: "Gorriti 4800, Palermo, CABA", kind: "apartment", m2_total: 68, rooms: 3, floor: 2 })
});
const v = await r.json();

# Python (requests)
r = requests.post("https://api.zavaluo.com/v1/valuations",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"address": "Gorriti 4800, Palermo, CABA", "kind": "apartment", "m2_total": 68, "rooms": 3, "floor": 2})

Crear una valuación

POST /v1/valuations

Devuelve el valor estimado para una propiedad. Con la dirección sola alcanza; cada atributo adicional reduce el rango.

Body

CampoTipoDescripción
addressstringDirección con barrio o ciudad. Geocodificamos y devolvemos la precisión. Requerido salvo que envíes lat/lng
lat, lngnumberCoordenadas WGS84. Si las enviás, ignoramos address.
countryenumAR (default) · ES
operationenumsale (default) · rent · temporary_rent
kindenumapartment (default) · house · ph · land · office · retail · garage · other
m2_total, m2_coverednumberMetros totales y cubiertos.
rooms, bedrooms, bathroomsintegerAmbientes, dormitorios, baños.
floor, year_builtintegerPiso (0 = planta baja) y año de construcción.
parking_spacesintegerCocheras incluidas.
has_balcony, has_terrace, has_pool, has_elevatorbooleanAmenities que más pesan en CABA.
monthly_feesnumberExpensas mensuales en moneda local.
localestringes-AR (default) · es-ES · en. Idioma de la explicación.

Respuesta

{
  "id": "7a1e…", "model_version": "ar-caba-sale-2026.09.1", "operation": "sale",
  "estimate_usd": 231000, "low_usd": 212000, "high_usd": 248000,
  "estimate_local": 312000000, "local_currency": "ARS",
  "likely_asking_usd": 244000, "likely_closing_usd": 231000, "asking_vs_closing_adj": -0.053,
  "confidence": 0.86, "comps_count": 23, "comps_radius_m": 500,
  "comps": [ { "listing_id": "…", "distance_m": 120, "price_usd": 239000, "usd_m2": 3414, "m2_total": 70,
             "rooms": 3, "days_on_market": 46, "price_cut_pct": -4.0, "source_url": "https://…" }, … ],
  "calibrating": true,
  "explanation": "Valuado 2% por debajo de la mediana de Palermo por estar en 2º piso al contrafrente…",
  "created_at": "2026-09-12T15:04:11-03:00"
}
El mismo input con el mismo model_version devuelve el mismo número. Guardá model_version junto al resultado si necesitás auditar una valuación más adelante. Mientras calibrating sea true, tratá el rango como la señal principal y no el punto.

Recuperar una valuación

GET /v1/valuations/{id}

Devuelve una valuación previa emitida con tu clave, sin volver a calcular ni consumir cuota.

Índice de avisos

GET /v1/listings?city=CABA&neighborhood=Palermo&operation=sale&max_price_usd=200000&sort=delta

Todos los avisos activos que monitoreamos (portales y dueños directos), paginados, con su URL canónica en Zavaluo y, en venta, el USD/m² contra el valor de referencia del barrio (delta_vs_reference, null mientras el barrio calibra). Los filtros son los mismos que la búsqueda del sitio.

citystringCABA (default).
neighborhoodstringBarrio oficial o texto libre. Sin él, toda la ciudad.
operationenumsale (default) · rent · temporary_rent
kindenumapartment · house · ph · …
min_price_usd, max_price_usdnumberRango de precio en USD.
min_rooms, min_m2numberAmbientes y metros mínimos.
updated_sinceISO 8601Solo avisos vistos después de ese instante: ideal para sincronizar cada hora.
vibelistEtiquetas leídas del texto del aviso, separadas por coma (luminoso,con_terraza,a_reciclar); devuelve los avisos que tengan alguna. Cada ítem trae vibe, style, summary_lead y la superficie desglosada (m2_covered, m2_semi, m2_uncovered).
sortenumrecent (default) · price · delta (mejor precio vs. referencia primero).
page, page_sizeintegerPágina desde 1 y tamaño hasta 100 (default 50). next trae la URL de la siguiente.
{ "total": 224, "page": 1, "page_size": 50, "next": "https://api.zavaluo.com/v1/listings?…&page=2", "reference_as_of": "2026-09-18",
  "items": [ { "ref": 1863, "url": "https://www.zavaluo.com/propiedad/belgrano/ZV-1863-ph-3-ambientes-…",
             "title": "PH 3 ambientes con patio y terraza", "price_usd": 200000, "m2_total": 192, "usd_m2": 1042,
             "neighborhood": "Belgrano", "lat": -34.5612, "lng": -58.4587, "rooms": 3,
             "reference_usd_m2": 2815, "delta_vs_reference": -0.63, "entorno_score": 76, "days_on_market": 0, "cover_url": "https://…/01.jpg" }, … ] }

entorno_score (0–100) describe la cuadra con datos abiertos del GCBA: distancia al subte, hechos denunciados a 500 m, escuelas a 800 m, espacios verdes y hospitales. No es una valuación; el detalle trae cada componente y el dato del que sale en context. Es null cuando el aviso no publica la dirección exacta.

predicted_usd_m2, value_delta y deal_score vienen del modelo hedónico vigente (model_version en la respuesta): la referencia de publicación para ese aviso dadas su superficie, ambientes, antigüedad, cochera y entorno, cuánto pide por encima o por debajo, y un 0–100 donde 50 es “en el modelo”. Una value_delta más allá de ±0,45 casi siempre es un error de superficie o precio en la fuente, no una oportunidad. quality_score (0–100) mide qué tan completo es el registro; con sort=delta el índice ordena por value_delta cuando existe.

Un aviso

GET /v1/listings/{ref}

El detalle completo por ref (1863 o ZV-1863) o por uuid: descripción, resumen, superficies, piso, amenities, fotos, historial de precios, la extracción estructurada del texto con su versión y context (entorno: puntajes de transporte, seguridad, escuelas, verde y salud con las distancias y conteos detrás de cada uno). Nunca incluye datos de contacto del publicador.

Comparables

GET /v1/comparables?lat=-34.5889&lng=-58.4306&kind=apartment&m2_total=70&rooms=3&year_built=1995&parking=true
GET /v1/listings/{ref}/comparables

Los avisos activos más parecidos alrededor de un punto (500 m, y se amplía a 1 km y 2,5 km si hay menos de cinco), cada uno con su similarity (distancia, superficie, ambientes, baños, antigüedad, antigüedad del aviso) y su USD/m² adjusted_usd_m2: el precio del comparable ajustado a la propiedad consultada con los coeficientes del modelo hedónico vigente (model_version). La mediana ponderada de los ajustados es la referencia y el rango es el p25–p75. confidence A–D resume cantidad, similitud y dispersión. Con asking_usd devuelve asking_vs_reference. La variante por ref arma el sujeto con el aviso y lo excluye de sus propios comparables.

Es una referencia de precios de publicación, no una valuación: reference.basis lo dice en cada respuesta. Los ajustes salen de un modelo log-lineal estimado sobre los avisos activos de CABA (superficie, ambientes, baños, antigüedad, cochera, dueño directo, distancia al subte, seguridad y verde del entorno, tipo y barrio); drivers trae los ajustes que más pesaron, en palabras.

{ "reference": { "usd_m2": 3180, "low_usd_m2": 2910, "high_usd_m2": 3460, "total_usd": 222600,
                 "confidence": "B", "n_comps": 9, "radius_used_m": 500, "model_usd_m2": 3097, "barrio_median_usd_m2": 3136,
                 "basis": "asking prices of active listings" },
  "comps": [ { "ref": 660, "distance_m": 140, "usd_m2": 2311, "adjusted_usd_m2": 2402, "similarity": 81, "adjustments": { "log_m2": 0.031, "has_parking": 0.145 } }, … ],
  "drivers": [ { "factor": "has_parking", "impact": 0.145, "label": "cochera" } ], "model_version": "hedonic-caba-2026-09-18" }

Índice de barrio

GET /v1/neighborhoods
GET /v1/neighborhoods/{slug}

Por barrio y día: inventario activo, avisos nuevos y dados de baja en 30 días, proporción con baja de precio, días en mercado, USD/m² de venta y de alquiler mensual, rentabilidad bruta, entorno promedio y los componentes del puntaje de mercado (momentum, liquidity, rental, entorno, affordability). market_score es null y calibrating true hasta que haya 30 días de historial para momentum y liquidez: preferimos no publicar un puntaje que solo diga “barato”.

CABA Market Score

GET /v1/market/caba
GET /v1/market/caba/history?from=2020-01&to=2026-08

Contexto mensual del mercado de la Ciudad: un puntaje 0–100 con cinco componentes (actividad de compraventa 30 %, crédito hipotecario 25 %, condiciones de financiamiento 15 %, estabilidad macro 15 %, riesgo soberano y cambiario 15 %), el régimen (very_weak … very_strong), las métricas crudas detrás de cada uno (escrituras e hipotecas del Colegio de Escribanos, dólar A3500, TAMAR/BADLAR, tasa de política, UVA y stock hipotecario del BCRA, IPC del INDEC, riesgo país), data_quality_score, is_provisional y calculation_version. Cada componente es un percentil sobre su propia historia desde 2016.

Es contexto, no un insumo de valuación: ninguna referencia ni rango de comparables se ajusta con este puntaje (basis lo repite en cada respuesta). La serie histórica sirve para graficar y para leer en qué mercado se está vendiendo. Se recalcula a diario y cuando el Colegio publica un mes nuevo.

{ "period": "2026-07", "caba_market_score": 58.4, "regime": "neutral", "score_change_3m": 3.1,
  "components": { "transaction": 61.2, "credit": 71.0, "financing": 44.5, "macro": 66.3, "risk": 40.9 },
  "metrics": { "total_deeds": 6051, "mortgage_share": 0.158, "deeds_yoy_pct": -9.0, "cpi_mom_pct": 2.1, "country_risk": 690, … },
  "data_quality_score": 100, "is_provisional": false, "calculation_version": "caba-market-score-v1" }

Estadísticas de mercado

GET /v1/market-stats?city=CABA&neighborhood=Palermo&kind=apartment&operation=sale

Agregados por barrio, recalculados cada noche: mediana y cuartiles de USD/m², avisos activos, días en mercado, baja de precio mediana y la relación publicación/cierre cuando hay cierres reportados. Sin neighborhood devuelve todos los barrios de la ciudad; el resultado trae hasta 100 filas, las más recientes primero.

{ "stats": [ { "country": "AR", "city": "CABA", "neighborhood": "Palermo", "kind": "apartment", "operation": "sale",
             "as_of": "2026-09-11", "n_active": 4812,
             "p25_usd_m2": 2980, "median_usd_m2": 3410, "p75_usd_m2": 3890,
             "median_days_on_market": 58, "median_price_cut_pct": -4.1, "asking_to_closed_ratio": null } ] }

Barrios

GET /v1/barrios?include=geometry

Los 48 barrios de CABA con slug, nombre, comuna y centroide, y con include=geometry el polígono oficial del GCBA en GeoJSON (WGS84). Es información pública: no requiere clave ni consume cuota. Usalo para mapas y para resolver el barrio de una coordenada del lado del cliente.

{ "barrios": [ { "slug": "palermo", "name": "Palermo", "comuna": 14, "centroid": { "lng": -58.4245, "lat": -34.5788 } }, … ] }

Confianza y rangos

low_usd y high_usd son los cuantiles 10 y 90 del modelo. confidence (0–1) combina la densidad de comparables en el radio, la dispersión de sus precios y cuántos cierres reales reportados tenemos en la zona. Con confianza baja el rango se ensancha hacia la mediana del barrio; no inventamos precisión. Mientras el historial de precios sea corto, calibrating es true.

Publicación vs. cierre

En CABA el precio publicado y el de escritura difieren, y la brecha varía por barrio y por momento del ciclo. estimate_usd y likely_closing_usd son el cierre probable. likely_asking_usd es el precio de publicación que hoy lleva a ese cierre, y asking_vs_closing_adj la brecha aplicada. La brecha se calibra con cierres reportados por dueños y con agregados públicos.

Monedas y tipo de cambio

El mercado de CABA opera en USD; todos los valores del modelo son en USD. estimate_local y local_currency convierten al tipo de cambio MEP del día. Guardamos las series oficial, mep y blue por fecha, así la conversión es auditable.

Errores

CódigoMotivo
400 Validation failedFalta address o lat/lng, o un campo tiene un valor fuera de rango. El body incluye issues con el campo y el detalle.
401 Invalid or revoked API keyClave ausente, inválida o revocada.
404 Not foundLa valuación no existe o no fue emitida con tu clave.
429 Monthly quota exceededCuota mensual de la clave superada. Se reinicia el día 1 (UTC).
503 CalibrandoEl modelo de valuación todavía no está activo. Las estadísticas y los barrios siguen disponibles.

Límites y versiones

La cuota es mensual por clave y cada request consumido cuenta, incluidos los que devuelven 400. La versión de la API va en la URL (/v1); cambios incompatibles salen como /v2 con al menos 6 meses de convivencia. El modelo se reentrena y su model_version cambia sin afectar el contrato; avisamos por email y en el changelog antes de cada versión mayor.

Changelog

2026-09 · /v1 en calibración para CABA. GET /market-stats y GET /barrios (con geometría oficial) activos; POST /valuations valida y responde 503 hasta que el modelo esté calibrado.

Documentación de la API — Zavaluo · Zavaluo