API de consulta
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:
| Permiso | Qué permite |
|---|---|
webhooks:write | Enviar leads, tareas y citas (API de leads). |
leads:read | Leer leads, embudos, etapas e historial de etapas. |
inventory:read | Leer proyectos, inmuebles y unidades. |
appointments:read | Leer citas y visitas. |
leads:write | Crear y actualizar leads, moverlos de etapa, notas (API de escritura). |
tasks:write | Crear tareas. |
appointments:write | Agendar citas. |
Las claves que ya existen no cambian
Una clave creada antes de que existieran los permisos solo tienewebhooks: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 https://api.yavehome.com/api/v1/external/me \
-H "X-API-Key: yave_3f9a…c21e"{
"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.
limitnumbercursorstringnextCursor de la página anterior. Sin él, empieza desde el principio.Leads#
/external/leadsleads:readsort-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 8601pipelineId · stageIdstring/external/pipelines).phonestringemailstring{
"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…"
}/external/leads/{id}leads:readEl 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
- La primera vez, recorre
/external/leads?sort=updatedAthasta quenextCursorseanull. - Guarda el
updatedAtmás reciente que recibiste. - 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 porid.
Embudos y etapas#
/external/pipelinesleads:read{
"data": [
{
"id": "default",
"name": "Ventas",
"isDefault": true,
"stages": [
{ "id": "NEW", "name": "Nuevo" },
{ "id": "s-visita", "name": "Visita agendada" },
{ "id": "WON", "name": "Ganado" }
]
}
]
}Inventario#
/external/projectsinventory:readProyectos activos: nombre, ubicación, imágenes, enlaces (video, tour, brochure), fecha de entrega y moneda.
/external/propertiesinventory:readInmuebles 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.
projectIdstringstatusenumAVAILABLE, RESERVED, SOLD, RENTED, FROZEN, BLOCKED, INACTIVE.listingTypeSALE | RENTupdatedSinceISO 8601Citas#
/external/appointmentsappointments:readfrom · toISO 8601leadIdstringstatusenumSCHEDULED, 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, recibes429conRetry-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.