Referencia de la API
Lo básico
- URL base: la que ves en Configuración → Integraciones → Referencia (termina en /api/v1).
- Autenticación: cabecera Authorization: Bearer np_… en todas las llamadas.
- Formato: se envía y se recibe JSON (Content-Type: application/json).
- Listas: responden { data, total, limit, offset }. Usa ?limit= (máximo 100; en propiedades, 50) y ?offset= para paginar.
- Errores: { "error": "mensaje" } con el código: 400 datos no válidos, 401 token inválido, 404 no existe, 409 no se puede en su estado actual, 422 el dato no corresponde (agente, etapa…), 500 error interno.
Contactos y leads
GET /contactos
Busca contactos. Parámetros: q (nombre sin importar acentos, correo o teléfono), phone (compara los últimos 10 dígitos, sin importar el formato), email, type (lead, cliente, propietario, inversionista, referidor, otro), ownerEmail.
GET /contactos?phone=809-555-1234
{ "data": [ { "id": "…", "name": "Ana Núñez", "phone": "+1 809 555 1234", "email": null,
"type": "lead", "source": "whatsapp", "tags": ["torre-alba"],
"owner": { "id": "…", "name": "Luis Pérez", "email": "luis@…" }, … } ],
"total": 1, "limit": 20, "offset": 0 }POST /contactos (crear lead)
Campos: name (obligatorio), phone y/o email (al menos uno), source (instagram, facebook, whatsapp, telegram, referido, portal, web, llamada, visita, otro), type (por defecto lead), tags, notes (queda en el historial), ownerEmail u ownerId, y deal para crear el negocio en el mismo paso.
No duplica: si ya hay un contacto con ese teléfono o correo, responde con ese contacto, isNew: false y código 200; le suma las etiquetas y, si no tenía agente, se lo asigna. Sin agente indicado se usa el reparto de leads de la empresa (Marketing → Reparto de leads) y el agente recibe un aviso.
POST /contactos
{ "name": "Ana Núñez", "phone": "+1 829 444 1122", "source": "whatsapp",
"notes": "Busca 2 hab en Piantini, hasta US$ 200 mil.",
"deal": { "title": "Ana Núñez - Torre Alba", "value": 185000, "currency": "USD",
"stageName": "Contactado" } }
201 { "contact": { … }, "isNew": true, "deal": { "id": "…", "stage": { "name": "Contactado" }, … } }GET /contactos/{id} · PATCH /contactos/{id} · POST /contactos/{id}/notas
La ficha devuelve el contacto y sus negocios. PATCH actualiza solo los campos enviados (name, phone, email, type, source, tags, notes, ownerId). Notas: { "content": "…" }.
Embudos y negocios
GET /embudos
Embudos con sus etapas en orden: { id, name, isPostSale, stages: [{ id, name, position, confirmsSale }] }. Usa el nombre o el id de la etapa para crear y mover negocios.
GET /negocios
Parámetros: contactId, pipelineId, stageId, status (open por defecto, won, lost o all), q (título o nombre del contacto) y ownerEmail. Cada negocio trae su embudo, etapa, contacto, agente, valor y moneda.
POST /negocios
{ "contactId", "title", "value"?, "currency"? (USD o DOP), "pipelineName"? o "pipelineId"?, "stageName"? o "stageId"?, "ownerEmail"? u "ownerId"?, "conversationId"? }. Por defecto va al embudo de ventas, primera etapa, con el agente del contacto. Con conversationId queda vinculado a esa conversación de la Bandeja.
GET /negocios/{id}
El negocio con sus últimas 20 notas y eventos.
POST /negocios/{id}/mover
{ "stageName": "Visita agendada" } o { "stageId": "…" }. La etapa debe ser del mismo embudo del negocio. El agente del negocio recibe un aviso.
POST /negocios/{id}/estado
{ "status": "lost", "lostReason": "Compró con otra inmobiliaria" } o { "status": "open" } para reabrir. Ganado no se marca por la API, y los negocios que ya tienen un cierre en Mis ventas se cambian desde el CRM.
POST /negocios/{id}/notas
{ "content": "…" }.
Propiedades y proyectos
GET /propiedades
Parámetros: q (nombre, sector, ciudad, provincia, etiqueta o código), kind (propiedad o proyecto), category (apartamento, penthouse, casa, villa, townhouse, terreno, finca, local, oficina, edificio, nave), operation (venta, alquiler, ambos), city, sector, province, minPrice, maxPrice, currency (USD o DOP), bedrooms (mínimo) y status (por defecto publicada y reservada; all para todas).
En los proyectos, el precio y las habitaciones se comparan con sus unidades disponibles, y cada resultado trae el resumen: total, disponibles, precio desde/hasta, metros y habitaciones.
GET /propiedades?kind=proyecto§or=piantini&bedrooms=2&maxPrice=250000
{ "data": [ { "id": "…", "code": 2001, "kind": "proyecto", "name": "Torre Alba",
"price": { "sale": { "amount": 185000, "currency": "USD" }, "rent": null },
"location": { "sector": "Piantini", "city": "Santo Domingo", … },
"deliveryDate": "2028-06-30",
"units": { "total": 40, "available": 12, "minPrice": 185000, "maxPrice": 265000,
"currency": "USD", "minM2": 95, "maxM2": 130, "bedrooms": [2, 3] },
"coverPhoto": "https://…/api/sitio/img/p-…" } ], "total": 1, … }GET /propiedades/{id o código}
La ficha completa: descripción, precios, mantenimiento, monto de reserva, amenidades, ubicación, entrega, video, recorrido virtual, fotos y el agente a cargo. En los proyectos, unitList con las unidades disponibles; usa ?unidades=all (o reservado, vendido, bloqueado) para ver otras.
Bandeja
- GET /canales · GET /usuarios
- GET /conversaciones/{id}: la conversación y sus últimos 50 mensajes.
- POST /conversaciones/{id}/mensajes: { "content": "…" } responde al cliente; con "private": true deja una nota interna.
- POST /conversaciones/{id}/asignar: { "assigneeEmail": "…" } o { "assigneeId": null }.
- POST /conversaciones/{id}/estado: open (pasa a una persona), bot, snoozed (con snoozeHours) o resolved.