Una API REST para leer y escribir los datos de tu negocio y webhooks firmados que avisan a tu sistema cuando llega un contacto, se agenda una cita o el asistente deriva a una persona. Las llaves y los webhooks se administran desde tu panel, en Integraciones.
Entra a tu panel, menú Integraciones, y crea una llave con un nombre (por ejemplo, el sistema que la va a usar). La llave completa se muestra una sola vez: guárdala en tu sistema. Si la pierdes, revócala y crea otra.
Cada solicitud lleva la llave en la cabecera Authorization:
curl -H "Authorization: Bearer ap_k7f3m2x9q1_a1b2c3..." https://asistentepro.cl/api/v1/cuentaLas respuestas correctas traen ok: true y los datos en data; las listas agregan paginacion. Los errores traen ok: false, un código estable en error y una explicación en message.
{
"ok": true,
"data": [
{
"id": "clx1...",
"nombre": "Ana Pérez",
"contacto": "56912345678",
"correo": "[email protected]",
"canal": "whatsapp",
"estado": "calificado",
"etapa": "seguimiento",
"notas": "Quiere cotizar 3 servicios para noviembre.",
"conversacionId": "clx9...",
"creadoEl": "2026-10-20T14:03:11.000Z",
"actualizadoEl": "2026-10-20T14:09:40.000Z"
}
],
"paginacion": { "pagina": 1, "porPagina": 50, "total": 1 }
}Las fechas van en ISO 8601 (UTC). Los teléfonos, con código de país y sin signos: 56912345678.
Dirección base: https://asistentepro.cl/api/v1
/v1/cuentalecturaDevuelve el negocio y la llave con la que entraste. Sirve para probar la conexión.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/cuenta/v1/leadslecturaLista los contactos (leads) del negocio, del más nuevo al más antiguo. Filtros: desde, hasta (fecha de creación, ISO 8601), estado (nuevo, calificado, contacto_comercial, ganado, perdido), canal (whatsapp, instagram, facebook, web). Paginado con pagina y porPagina (máximo 100).
curl -H "Authorization: Bearer TU_LLAVE" "https://asistentepro.cl/api/v1/leads?estado=nuevo&desde=2026-10-01&porPagina=50"/v1/leads/:idlecturaUn contacto con su ficha completa y el id de su última conversación.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/leads/ID_DEL_LEAD/v1/leads/:idescrituraCambia el estado y/o las notas (la ficha) de un contacto. Dispara el evento lead.actualizado.
curl -X PATCH -H "Authorization: Bearer TU_LLAVE" -H "Content-Type: application/json" \
-d '{"estado":"ganado","notas":"Cerró plan anual, factura 1234"}' https://asistentepro.cl/api/v1/leads/ID_DEL_LEAD/v1/conversaciones/:id/mensajeslecturaLos mensajes de una conversación en orden cronológico. Cada mensaje dice si lo escribió el cliente, el asistente o una persona del equipo. Paginado (porPagina hasta 200).
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/conversaciones/ID_CONVERSACION/mensajes/v1/citaslecturaCitas en un rango de fechas (desde, hasta; por defecto los próximos 30 días; máximo 92 días). Filtro estado: agendada, hecha, cancelada.
curl -H "Authorization: Bearer TU_LLAVE" "https://asistentepro.cl/api/v1/citas?desde=2026-10-20&hasta=2026-11-20"/v1/citasescrituraCrea una cita del negocio con la misma validación que el panel: titulo e inicio obligatorios, correo válido si viene, y 409 horario_ocupado si choca con otra cita. Manda la invitación de calendario (si hay correo) y programa los recordatorios por WhatsApp (si hay contacto). Dispara cita.creada.
curl -X POST -H "Authorization: Bearer TU_LLAVE" -H "Content-Type: application/json" \
-d '{"titulo":"Visita técnica","inicio":"2026-10-22T15:00:00-03:00","duracionMin":45,"contacto":"56912345678","nombre":"Ana Pérez","correo":"[email protected]","notas":"Revisión anual"}' \
https://asistentepro.cl/api/v1/citas/v1/catalogolecturaTodos los productos o servicios del catálogo, con precio, stock y categoría. El costo interno nunca sale.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/catalogo/v1/catalogoescrituraReemplaza el catálogo con la lista que mandas (hasta 500 productos). Empareja por nombre: los que existen se actualizan, los nuevos se crean y los que no vienen quedan inactivos (no se borran: conservan foto, orden y destacado). Campos: nombre (obligatorio), precio, stock, categoria, descripcion, precioTexto, activo.
curl -X PUT -H "Authorization: Bearer TU_LLAVE" -H "Content-Type: application/json" \
-d '{"productos":[{"nombre":"Queso mantecoso 1 kg","precio":8990,"stock":24,"categoria":"Quesos"},{"nombre":"Jamón serrano 250 g","precio":6490,"stock":0,"categoria":"Cecinas"}]}' \
https://asistentepro.cl/api/v1/catalogo/v1/mensajesescrituraEnvía un texto por WhatsApp a un contacto, SOLO si la ventana de 24 horas está abierta (el cliente escribió hace menos de 24 h). Si está cerrada responde 409 ventana_cerrada y no envía nada: WhatsApp no acepta texto libre fuera de esa ventana. Con pausarAsistente: true el asistente deja de responder en ese hilo hasta que alguien lo libere desde el panel.
curl -X POST -H "Authorization: Bearer TU_LLAVE" -H "Content-Type: application/json" \
-d '{"contacto":"56912345678","texto":"Tu pedido #482 ya está listo para retiro."}' https://asistentepro.cl/api/v1/mensajesEn Integraciones agrega la dirección https de tu sistema y elige los eventos. Cada vez que ocurra uno, hacemos un POST con JSON a esa dirección. Tu servidor debe responder un código 2xx en menos de 8 segundos; haz el trabajo pesado después de responder.
| Evento | Cuándo se envía |
|---|---|
lead.creado | Un contacto nuevo escribió por primera vez, o lo creó el panel o la API. |
lead.actualizado | Cambió el estado o la ficha de un contacto (por el asistente, el panel o la API). |
cita.creada | Se agendó una cita (por el asistente, el panel o la API). |
cita.cancelada | Se canceló o eliminó una cita. |
derivacion.creada | El asistente derivó una conversación a una persona: pidió hablar con alguien, reclamo, duda que no pudo resolver, o el servicio de IA no pudo responder. |
mensaje.recibido | Llegó un mensaje de un cliente por WhatsApp o Instagram. |
El cuerpo lleva id (único por aviso, se repite en los reintentos: úsalo para no procesar dos veces), evento, fecha, negocioId y datos con la misma forma que devuelve la API.
POST https://misistema.cl/webhooks/asistentepro
Content-Type: application/json
X-AsistentePro-Evento: cita.creada
X-AsistentePro-Entrega: wh_8f2c...
X-AsistentePro-Timestamp: 1760990000
X-AsistentePro-Firma: 3b1f9c... (HMAC-SHA256 en hexadecimal)
{
"id": "wh_8f2c...",
"evento": "cita.creada",
"fecha": "2026-10-20T18:00:00.000Z",
"negocioId": "clorg...",
"datos": {
"id": "clx5...",
"titulo": "Visita técnica",
"contacto": "56912345678",
"inicio": "2026-10-22T18:00:00.000Z",
"duracionMin": 45,
"estado": "agendada"
}
}prueba y te muestra qué respondió tu servidor. Las últimas 20 entregas y su estado quedan a la vista.Al crear el webhook te damos un secreto (una sola vez). Cada aviso trae X-AsistentePro-Timestamp (segundos unix) y X-AsistentePro-Firma: el HMAC-SHA256, con tu secreto, del texto <timestamp>.<cuerpo>, en hexadecimal. Calcula lo mismo sobre el cuerpo crudo que recibiste y compara. Descarta avisos con más de 5 minutos.
import crypto from 'node:crypto'
// cuerpoCrudo: el cuerpo EXACTO que llegó (string o Buffer), no el JSON ya parseado y vuelto a serializar.
function firmaValida(secreto, cabeceras, cuerpoCrudo) {
const ts = Number(cabeceras['x-asistentepro-timestamp'])
const firma = String(cabeceras['x-asistentepro-firma'] || '')
if (!ts || Math.abs(Date.now() / 1000 - ts) > 300) return false // más de 5 minutos: se descarta
const esperada = crypto.createHmac('sha256', secreto).update(`${ts}.${cuerpoCrudo}`).digest('hex')
const a = Buffer.from(esperada, 'hex'); const b = Buffer.from(firma, 'hex')
return a.length === b.length && crypto.timingSafeEqual(a, b)
}| Respuesta | Qué significa |
|---|---|
401 llave_invalida | La llave no existe, está mal escrita o fue revocada. |
403 permiso_insuficiente | La llave es de solo lectura y la ruta modifica datos. |
403 cuenta_pausada | La cuenta del negocio está en pausa. |
404 no_encontrado | El id no existe en esta cuenta (los ids de otros negocios siempre dan 404). |
400 fecha_invalida / estado_invalido / faltan_datos / correo_invalido | Revisa el cuerpo o los filtros; el campo message explica qué falta. |
409 horario_ocupado | Ya hay una cita en ese horario (viene citaId). |
409 ventana_cerrada | No se puede enviar texto libre a ese contacto hasta que vuelva a escribir. |
429 rate_limited | Más de 120 solicitudes por minuto con la misma llave. Espera lo que dice Retry-After. |
Límite: 120 solicitudes por minuto por llave (cabeceras X-RateLimit-Limit y X-RateLimit-Remaining). Hasta 10 llaves activas y 10 webhooks por negocio.
¿Necesitas una ruta que no está? Escríbenos desde tu panel: esta primera versión cubre lo que un sistema externo usa de verdad y crece con lo que los negocios piden.