Datos y eventos

API de consulta

Lee los datos de la organización desde tu propio sistema: un tablero de BI, tu ERP, el sitio web o un informe a la medida. Para crear o actualizar datos está la API de escritura, y para solo enviar leads, la API de leads.

Permisos de la API key#

Usa la misma API key de la organización, pero cada clave solo puede hacer lo que un administrador le haya permitido en Configuración → Integraciones → API Key → Permisos:

PermisoQué permite
webhooks:writeEnviar leads, tareas y citas (API de leads).
leads:readLeer leads, embudos, etapas e historial de etapas.
inventory:readLeer proyectos, inmuebles y unidades.
appointments:readLeer citas y visitas.
leads:writeCrear y actualizar leads, moverlos de etapa, notas (API de escritura).
tasks:writeCrear tareas.
appointments:writeAgendar citas.

Las claves que ya existen no cambian

Una clave creada antes de que existieran los permisos solo tiene webhooks:write: sigue enviando leads igual que siempre y no puede leer nada hasta que un administrador le active un permiso de lectura. Lo más seguro es crear una clave aparte para cada sistema que lee.

La clave va en el encabezado X-API-Key o como Authorization: Bearer yave_…. Si le falta un permiso, la respuesta es 403 y el mensaje dice cuál.

cURL
curl https://api.yavehome.com/api/v1/external/me \
  -H "X-API-Key: yave_3f9a…c21e"
200
{
  "organization": {
    "id": "cm1…",
    "name": "Constructora Ejemplo",
    "slug": "constructora-ejemplo",
    "countryCode": "CO",
    "currency": "COP",
    "timezone": "America/Bogota"
  },
  "apiKey": {
    "id": "cm8…",
    "name": "Tablero de BI",
    "scopes": ["leads:read", "inventory:read"]
  }
}

Paginación#

Los listados devuelven { "data": [...], "nextCursor": "…" }. Para la página siguiente, repite la petición con cursor=<nextCursor>. Cuando nextCursor es null, no hay más. El cursor no se salta ni repite registros aunque entren leads nuevos mientras recorres las páginas.

limitnumber
Resultados por página, de 1 a 100. Por defecto 50.
cursorstring
El nextCursor de la página anterior. Sin él, empieza desde el principio.

Leads#

GET/external/leadsleads:read
sort-createdAt | updatedAt
-createdAt (por defecto): los más nuevos primero. updatedAt: del cambio más viejo al más reciente, para sincronizar (ver abajo).
createdSince · updatedSinceISO 8601
Solo leads creados o modificados desde esa fecha.
pipelineId · stageIdstring
Filtra por embudo o por etapa (ids de /external/pipelines).
phonestring
Busca por teléfono en cualquier formato; se normaliza igual que al crear el lead.
emailstring
Busca por correo.
200
{
  "data": [
    {
      "id": "cm9k2…",
      "name": "Laura Gómez",
      "email": "[email protected]",
      "phone": "+573001234567",
      "source": "LANDING",
      "channel": "WEB",
      "pipeline": { "id": "default", "name": "Ventas" },
      "stage": { "id": "s-visita", "name": "Visita agendada" },
      "opportunityStatus": "ACTIVE",
      "lostReason": null,
      "score": 72,
      "budget": 350000000,
      "projectId": "cm4p…",
      "assignedTo": { "id": "cm2u…", "name": "Carlos Ruiz", "email": "[email protected]" },
      "utmSource": "facebook",
      "utmMedium": "paid",
      "utmCampaign": "torre-2-preventa",
      "utmContent": null,
      "utmTerm": null,
      "tags": ["Torre 2", "Preventa"],
      "createdAt": "2026-09-28T15:04:12.511Z",
      "updatedAt": "2026-09-29T10:22:40.100Z",
      "lastContactAt": "2026-09-29T10:20:00.000Z",
      "convertedAt": null
    }
  ],
  "nextCursor": "MjAyNi0wOS0yOFQxNTowNDoxMi41MTFafGNtOWsy…"
}
GET/external/leads/{id}leads:read

El mismo lead, más stageHistory: sus últimos 100 cambios de etapa (from, to, by y at), el más reciente primero. by dice quién lo movió: USER, AI, WORKFLOW, WEBHOOK, etc.

Sincronizar sin traer todo cada vez

  1. La primera vez, recorre /external/leads?sort=updatedAt hasta que nextCursor sea null.
  2. Guarda el updatedAt más reciente que recibiste.
  3. En las siguientes corridas pide ?sort=updatedAt&updatedSince=<ese valor>: llegan solo los leads nuevos o modificados. Un lead puede repetirse en el borde; actualízalo por id.

Embudos y etapas#

GET/external/pipelinesleads:read
200
{
  "data": [
    {
      "id": "default",
      "name": "Ventas",
      "isDefault": true,
      "stages": [
        { "id": "NEW", "name": "Nuevo" },
        { "id": "s-visita", "name": "Visita agendada" },
        { "id": "WON", "name": "Ganado" }
      ]
    }
  ]
}

Inventario#

GET/external/projectsinventory:read

Proyectos activos: nombre, ubicación, imágenes, enlaces (video, tour, brochure), fecha de entrega y moneda.

GET/external/propertiesinventory:read

Inmuebles y unidades en todos sus estados (a diferencia del catálogo público, que solo muestra lo disponible). Ordenados por updatedAt ascendente, así sirven para sincronizar la disponibilidad.

projectIdstring
Unidades de un proyecto.
statusenum
AVAILABLE, RESERVED, SOLD, RENTED, FROZEN, BLOCKED, INACTIVE.
listingTypeSALE | RENT
Venta o arriendo.
updatedSinceISO 8601
Solo lo que cambió desde esa fecha.

Citas#

GET/external/appointmentsappointments:read
from · toISO 8601
Rango por fecha de inicio. Por defecto, los próximos 30 días. Máximo 92 días por consulta.
leadIdstring
Citas de un lead.
statusenum
SCHEDULED, CONFIRMED, COMPLETED, CANCELLED, NO_SHOW.

Límites y privacidad#

  • 120 peticiones por minuto por clave, además de los límites por IP. Cada respuesta trae X-RateLimit-Remaining; si te pasas, recibes 429 con Retry-After.
  • Todo está limitado a la organización de la clave: un id de otra organización responde 404.
  • La API expone datos de contacto de personas. Guárdala en tu servidor, nunca en un navegador ni en una app, y dale a cada sistema solo los permisos que necesita.