Ingesta de Leads
POST /v1/leads:ingest es la única llamada para enviar personas desde cualquier lugar: tus landing pages, herramientas de formularios, plataformas de anuncios, Zapier, un bot de WhatsApp. Sigue el mismo camino que una consulta en tu sitio web de letsrealty —deduplicación, la consulta, el responsable del Lead, la notificación al equipo y la calificación con IA— y agrega tu atribución.
Requiere leads:ingest (o leads:write) y tiene su propio límite de uso de 60 por minuto.
La solicitud
{
"source": "Facebook Lead Ads",
"campaign": "Lanzamiento Escazú",
"type": "inquiry",
"person": {
"name": "Ana Rojas",
"email": "ana@example.com",
"phone": "8888 1234"
},
"property_ref": "CASA-ESC-12",
"agent_email": "maria@agency.example",
"message": "¿Sigue disponible?",
"occurred_at": "2026-09-30T14:05:00Z"
}
source(obligatorio) ycampaign— texto libre que indica de dónde vino el Lead. Los primeros valores se guardan en el Lead comosource_detailycampaign; cada consulta conserva los suyos.type(obligatorio) —inquiry(una pregunta, el caso habitual),registration(se registró sin hacer una pregunta) onote(un mensaje para dejar en el Lead;messagees obligatorio y se guarda como una actividad de tipo nota).person.name(obligatorio) y al menos uno deperson.email/person.phone. Los teléfonos se interpretan con el país por defecto de tu agencia, así que los números locales funcionan.- La propiedad —
property_id, oproperty_ref: el slug de tu propiedad o tu propia referencia interna. Envía uno o ninguno. - El agente —
agent_id, oagent_email. Envía uno o ninguno. occurred_at— cuándo ocurrió realmente; por defecto, ahora. Consulta las cargas históricas más abajo.
Envía un header Idempotency-Key para que un reintento después de un timeout nunca registre la consulta dos veces; consulta Límites de uso e idempotencia.
La respuesta
201 cuando se creó un Lead nuevo, 200 cuando la persona coincidió con un Lead existente:
{
"lead": { "id": "6f1c…", "name": "Ana Rojas", "source": "api", "…": "…" },
"inquiry_id": "0b9e…",
"activity_id": null,
"warnings": [
{ "code": "property_ref_unmatched", "detail": "property_ref names no Property" }
]
}
Un Lead creado por ingesta tiene source api (o import en una carga histórica). inquiry_id viene en un inquiry o registration, y activity_id en un note.
Cómo se identifica a las personas
letsrealty busca coincidencias primero por email y luego por teléfono. Si el email coincide con un Lead y el teléfono con otro, gana el email y ambos se marcan como posibles duplicados para tu equipo; nunca se fusiona nada automáticamente. Una coincidencia por teléfono puede completar un email que falta, pero nunca sobrescribe uno existente.
Advertencias, no errores
Una referencia que no se puede resolver nunca hace perder el Lead. La consulta se registra sin ella y la respuesta incluye una advertencia:
property_ref_unmatched— ninguna propiedad tiene ese slug o referencia.property_ref_ambiguous— más de una lo tiene; no se vincula ninguna.property_not_found— ninguna propiedad tiene eseproperty_id.agent_unmatched— ningún agente activo tiene ese email; se aplican las reglas habituales de asignación.
Revisa warnings[] en tus logs y corrige tu mapeo; la llamada en sí fue exitosa.
Cargas históricas con occurred_at
Para traer el historial de otro sistema, envía cada registro con su occurred_at original. Todo lo que tenga más de 24 horas se registra en esa fecha en silencio: sin notificación, sin calificación con IA y sin cambio de responsable del Lead. Los registros recientes (de las últimas 24 horas) se comportan como una consulta en vivo. Un Lead creado por primera vez en una carga histórica tiene source import.
No hay llamada por lotes. A 60 por minuto, 5.000 registros tardan menos de 90 minutos; regula tu bucle con el header RateLimit y reintenta los 429 después de Retry-After. Usa el id del registro en tu sistema anterior como Idempotency-Key, así una importación reiniciada nunca duplica nada.