← Estatefy

API para conectar otros programas

Para conectar con tu oficina agentes de voz, de chat o de correo, un calendario o una automatización (n8n, Make, Zapier…): buscar quién llama, ver su vivienda y su historial, apuntar la llamada, dar una valoración o una visita y consultar la agenda del equipo.

1. La clave

La crea el administrador en Gestión → Empresa → Conexiones con otros programas. Al crearla se elige:

La clave se enseña una sola vez. Guárdala en el programa que se conecta; si se pierde o se filtra, se anula en el mismo sitio y se hace otra.

Se manda en cada petición, en la cabecera:

Authorization: Bearer est_…
La clave da acceso a datos de personas. No la pongas en una página web ni en el navegador: úsala solo desde el servidor del programa que se conecta. Todo va por https://estatefy.es/api/v1/….

2. Cómo contesta

3. Las rutas

Quién soy

GET /api/v1/yo

La empresa, la persona en cuyo nombre actúa la clave, lo que puede hacer y sus permisos. Sirve para comprobar que la clave funciona.

GET /api/v1/equipo leer

Las personas del equipo con acceso: id, nombre, perfil, letra y oficina (y el teléfono, con propietarios).

GET /api/v1/catalogo

Los valores que valen: estados de una vivienda, tipos de cita y de actividad, canales e intereses de un contacto, y los avisos que se pueden recibir.

Viviendas

GET /api/v1/viviendas leer

Buscar. Todo es opcional y se combina:

qTexto: calle, municipio, nota… y, con propietarios, nombre, teléfono (escrito como sea: «+34 600 11 22 33» encuentra «600112233») o correo del propietario.
telefonoLo mismo que q, para reconocer a quien llama.
calle, numero, escalera, planta, puertaLa dirección en trozos, como la dice una persona («3º», «bajo», «izq.»).
cpCódigo postal.
estadono_contesta, no_interesado, interesado, cita, captado… o con_ficha, sin_tocar, toca_volver.
hojacontactados o encargos.
limite, desdePágina: hasta 100 (25 si no se dice) y desde qué posición.

Devuelve viviendas (dirección, estado, cuándo volver, quién la lleva, el propietario si hay permiso y el resto de la ficha en ficha) y el total.

curl -H "Authorization: Bearer est_…" \
  "https://estatefy.es/api/v1/viviendas?telefono=600112233"
GET /api/v1/viviendas/{id} leer

Una vivienda con su historial entero (llamadas, notas, visitas, cambios de estado, con quién y cuándo) y el ultimoContacto.

POST /api/v1/viviendas/{id}/actividades escribir

Apuntar lo hablado: {"tipo": "llamada", "texto": "Llama el propietario, quiere saber cuánto vale. Prefiere tardes."}. Tipos: llamada, whatsapp, correo, visita, nota. Un agente de correo apunta cada correo como correo; uno de chat, como whatsapp o nota.

POST /api/v1/viviendas/{id}/apuntes escribir

Cambiar el estado, como un apunte desde el mapa. Todo opcional menos el estado (si la vivienda ya tiene uno, se puede omitir y se queda):

{
  "estado": "interesado",
  "nota": "Vendería en primavera",
  "volverEl": "2026-10-15", "volverHora": "18:00",
  "propietario": { "nombre": "Pilar", "telefono": "600112233" },
  "consentimientoLlamar": true
}

propietario y consentimientoLlamar piden además propietarios. Lo que no se manda se queda como estaba.

Agenda y citas

GET /api/v1/agenda/huecos leer

Antes de proponer una hora: los huecos libres de cada persona y día, y horas propuestas listas para ofrecer («te puedo dar el martes a las 10:00 o a las 12:30»).

fecha, hastaLos días (hoy si no se dice; como mucho dos semanas).
personaSolo esa persona (su id). Si no, todo el equipo (quien lo lleva) o solo la de la clave.
duracionMinutos que dura la cita (60).
inicio, finEntre qué horas se dan citas (09:00 a 20:00).
POST /api/v1/citas escribir

Dar una cita. Sale al momento en la agenda del equipo y avisa al móvil de quien va.

{ "tipo": "valoracion", "vivienda": "4397-18250", "fecha": "2026-10-02", "hora": "17:30",
  "horaFin": "18:30", "persona": 12, "nota": "La atiende la hija" }

{ "tipo": "valoracion", "direccion": "Calle Olivo 7, 3ºA, Villaviciosa", "fecha": "2026-10-02",
  "hora": "10:00", "contacto": { "nombre": "Marta", "telefono": "611223344" }, "lead": 41 }
GET /api/v1/citas/{id} · PATCH /api/v1/citas/{id} · DELETE /api/v1/citas/{id} leer / escribir

Ver una cita, moverla (fecha, hora, horaFin), pasarla a otra persona, cambiar el titulo o la nota, darla por "estado": "hecha" o "cancelada", o quitarla.

GET /api/v1/agenda leer

Lo que hay entre dos días (desde y hasta; si no se dicen, de hoy a 30 días): valoraciones, casas a las que volver, visitas, reuniones, firmas y citas propias, con hora, dirección, quién va y el contacto (con propietarios). persona=ID filtra por una persona. Quien no lleva el equipo solo ve lo suyo, como en su panel.

GET /api/v1/agenda.ics leer

La misma agenda como calendario (iCalendar), para importarla o sincronizarla con cualquier programa de calendario o automatización.

Contactos que entran

POST /api/v1/leads escribir + propietarios

Quien escribe o llama a la oficina y no es una vivienda que ya se conozca. Llega al panel de todo el equipo (y al móvil de quien tenga los avisos), para que alguien se lo quede y le dé cita.

{ "nombre": "Marta Gil", "telefono": "611223344", "email": "marta@…",
  "canal": "voz", "interes": "vender", "direccion": "Calle Olivo 7, 3ºA",
  "mensaje": "Quiere vender el piso de su madre. Mejor por las tardes." }

canal: voz, telefono, chat, whatsapp, email, web, otro. interes: vender, valorar, comprar, alquilar, otro. Si habla de una casa del mapa, se puede enlazar con vivienda.

GET /api/v1/leads · PATCH /api/v1/leads/{id} leer / escribir

Los abiertos (o ?estado=todos, nuevo, en_curso, hecho, descartado). Cambiar su estado, quién lo lleva (persona), la vivienda o añadir una nota.

Compradores

GET /api/v1/compradores leer

La lista de compradores con lo que buscan y cuántas casas en encargo les encajan. Filtros: q (nombre, notas, zonas), telefono, estado (buscando, pausado, comprado).

POST /api/v1/compradores escribir

Apuntar a alguien que busca casa: nombre (obligatorio), telefono y email (con propietarios), precio_max, zonas, dormitorios_min, banos_min, metros_min, tipos, requisitos, notas, usuarioId (quién lo lleva).

PATCH /api/v1/compradores/{id} escribir

Cambiar un comprador: solo lo que se manda.

Para agentes de voz y de chat

GET /api/v1/quien-llama?telefono=… leer + propietarios

Entra una llamada: con el número (con o sin +34), todo lo que la oficina sabe de esa persona en una sola respuesta: su nombre, si es propietaria de alguna casa y cómo está, si busca casa, si alquila, si ya fue cliente. Para saludarla por su nombre y saber de qué va.

GET /api/v1/estimar · POST /api/v1/estimar leer

Los municipios de la oficina y, con municipio y superficie, una horquilla de precio con las ventas y los precios reales de la oficina. Si no hay datos bastantes, hay: false: ofrece una valoración en persona.

GET /api/v1/alquileres/atrasados leer (+ propietarios para el teléfono)

Los alquileres con recibos sin pagar: cuántos, cuánto debe, la renta y el día de pago; con propietarios, el teléfono del inquilino. Para que un agente de voz o de WhatsApp se lo recuerde con buenas maneras.

GET /api/v1/cartera leer

Las casas en venta con su nota de 0 a 100 y lo que toca con cada una: para un agente que prepara la reunión del lunes o avisa al propietario.

El conector para agentes de voz y chat (SignalCore y otros)

Lo más fácil, y lo que se recomienda: en Gestión → Empresa → Conectar un agente de voz o de chat salen las direcciones ya hechas y un botón para probar. Por detrás son dos cosas:

POST /api/v1/eventos?clave=est_… escribir + propietarios

La dirección de «Enviar eventos» de la plataforma. Acepta el formato de SignalCore tal cual (event.channel, event.data.summary, appointments, lead_contact…) y el de otras (los campos se buscan por su nombre, en español o en inglés). Busca a la persona por su teléfono y rellena solo su contacto (sin duplicarlo), el historial de su casa si es propietaria, su ficha de comprador si busca casa (presupuesto, zona, dormitorios) y la agenda con las citas. Cada evento se procesa una vez. Con &prueba=1 dice lo que ha entendido sin apuntar nada. La clave va en la URL porque hay plataformas que no dejan poner cabeceras; solo vale ahí y en las herramientas.

POST o GET /api/v1/herramientas/{quien-llama | buscar-casas | huecos | reservar-cita | apuntar | estimar} leer (+ lo que pida cada una)

Para usar en mitad de la conversación (SignalCore: Herramientas → HTTP personalizado). URL fija, parámetros planos en el cuerpo (o en la dirección, con GET), y la respuesta trae respuesta: una frase lista para que el agente la diga. Las fechas y horas valen como las diga la persona (2026-10-05, 05/10, el lunes; 10:30, 10h, 5 de la tarde); si la hora pedida está ocupada, la respuesta propone las libres más cercanas. Los parámetros de cada una, con su modo (Variable o Dinámico), están en la guía de Gestión y en openapi.json.

Desde cualquier automatización (Make, Zapier, n8n, las automatizaciones de SignalCore…)

La misma dirección de eventos vale para cualquier paso «HTTP / Webhook» de una automatización. Se puede mandar en JSON o como formulario (lo que Zapier manda por defecto), con los campos sueltos y con estos nombres (en español o en inglés; mayúsculas, tildes y guiones dan igual):

telefono / phone, email, nombre / name (o first_name y last_name)Quién es. Hace falta el teléfono o el correo: con eso se le reconoce la próxima vez.
resumen / summary, mensaje / messageLo hablado. Va a su contacto y, si es propietario de una casa del CRM, al historial de la casa.
interes / intentvender, comprar, alquilar o valorar. Si no viene, se deduce del resumen.
presupuesto, zona, dormitoriosSi busca casa: su ficha de comprador, creada o completada (el presupuesto vale como «250.000 €», «250k» o «entre 180 y 220 mil»).
direccion, metros, precio_ventaSi vende: la casa y lo que pide por ella.
fecha_cita (y hora_cita, si va aparte)Una cita a la agenda: «2026-10-05 10:00», «05/10/2026 a las 18:30», «mañana a las 11»… Sin zona horaria, es la hora de Madrid.
event_id o call_idOpcional: si llega dos veces el mismo, la segunda no se repite.
POST https://estatefy.es/api/v1/eventos?clave=est_…
Content-Type: application/json

{ "telefono": "611 222 333", "nombre": "Ana García", "interes": "vender",
  "direccion": "Calle Mayor 5, Móstoles", "resumen": "Quiere vender su piso de 90 m²",
  "fecha_cita": "2026-10-06 17:00" }

4. Avisos a otros programas

Para no estar preguntando cada minuto: el administrador da de alta en Gestión → Empresa → Conexiones la dirección https:// de su programa y qué quiere que se le avise. Cuando pasa, se le manda un POST:

POST https://tu-programa/…
Content-Type: application/json
X-Estatefy-Evento: cita.creada
X-Estatefy-Entrega: 5f0c…            (el mismo en los reintentos: sirve para no repetir)
X-Estatefy-Firma: t=1790000000,v1=…

{ "id": "…", "evento": "cita.creada", "fecha": "2026-09-26T10:00:00Z",
  "empresa": { "id": 3, "nombre": "…" }, "datos": { …la cita, el contacto, el apunte… } }
apunte.creadoSe apunta un estado en una vivienda (en la calle, el CRM o la API).
actividad.creadaUna visita de comprador, una reunión o una firma de una casa en venta.
cita.creada, cita.cambiada, cita.borradaLo que pasa en la agenda.
lead.creado, lead.cambiadoUn contacto que entra, o que cambia de estado o de persona.
operacion.creada, operacion.cambiadaUna reserva, unas arras, una escritura o un cobro: para llevar la contabilidad o avisar a la gestoría.
oferta.recibidaSe firma una propuesta de compra: para avisar al propietario o preparar la respuesta.
precio.bajadoBaja el precio de una casa en venta: para avisar a los compradores que ahora encajan por WhatsApp o correo.
recibo.atrasado, recibo.cobradoEl recibo de un alquiler que lleva tres días sin pagar, o que se cobra: para que un agente de voz o de WhatsApp se lo recuerde al inquilino, y darle las gracias.

Comprobar que viene de Estatefy: con el secreto que se enseña al crear el aviso (whsec_…), calcula HMAC-SHA256(secreto, t + "." + cuerpo) en hexadecimal y compáralo con v1; descarta los que tengan un t de hace más de 5 minutos. En Node:

const [t, v1] = firma.split(',').map((p) => p.split('=')[1]);
const esperado = crypto.createHmac('sha256', secreto).update(`${t}.${cuerpoTalCual}`).digest('hex');
const vale = crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(v1))
  && Math.abs(Date.now() / 1000 - Number(t)) < 300;

Contesta con un 2xx en menos de 8 segundos. Si no, se reintenta a los 30 s, 2 min y 10 min; tras 50 fallos seguidos el aviso se pausa solo (se ve en Gestión). Los avisos nunca llevan la ubicación de nadie.

5. Agentes de voz, chat y correo, paso a paso

  1. Entra una llamada o un mensaje: GET /api/v1/quien-llama?telefono=… lo dice todo de una vez. O, por partes: GET /api/v1/viviendas?telefono=…; si sale una vivienda, GET /api/v1/viviendas/{id} para saber de qué se habló la última vez. Si no, puede ser un comprador: GET /api/v1/compradores?telefono=….
  2. Si no se le conoce, al acabar se registra: POST /api/v1/leads con lo que quiere y lo que contó.
  3. Si quiere una cita: GET /api/v1/agenda/huecos?fecha=…, se le ofrecen dos o tres de las horas propuestas y, con la que elija, POST /api/v1/citas (con Idempotency-Key). Sale al momento en la agenda y a quien va le llega el aviso al móvil.
  4. Al colgar o al contestar el correo: POST /api/v1/viviendas/{id}/actividades con el resumen.
  5. Para que otro programa reaccione (un correo de confirmación, un recordatorio por WhatsApp el día antes): un aviso de cita.creada a su dirección.

6. Lo que no hace, a propósito

Todo lo que escribe la API queda en el historial de cada vivienda con el nombre de la persona de la clave, como cualquier otro apunte; las citas dicen además qué conexión las dio.