A REST API to read and write your business data, and signed webhooks that notify your system when a contact comes in, an appointment is booked or the assistant hands off to a person. Keys and webhooks are managed from your dashboard, under Integrations.
Go to your dashboard, menu Integrations, and create a key with a name (for example, the system that will use it). The full key is shown only once: store it in your system. If you lose it, revoke it and create a new one.
Every request carries the key in the header Authorization:
curl -H "Authorization: Bearer ap_k7f3m2x9q1_a1b2c3..." https://asistentepro.cl/api/v1/cuentaSuccessful responses include ok: true and the data in data; lists add paginacion. Errors include ok: false, a stable code in error and an explanation in 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 }
}Dates are in ISO 8601 (UTC). Phone numbers include the country code, with no symbols: 56912345678.
Base URL: https://asistentepro.cl/api/v1
/v1/cuentareadReturns the business and the key you signed in with. Useful for testing the connection.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/cuenta/v1/leadsreadLists the business's contacts (leads), newest first. Filters: desde, hasta (creation date, ISO 8601), estado (nuevo, calificado, contacto_comercial, ganado, perdido), canal (whatsapp, instagram, facebook, web). Paginated with pagina and porPagina (maximum 100).
curl -H "Authorization: Bearer TU_LLAVE" "https://asistentepro.cl/api/v1/leads?estado=nuevo&desde=2026-10-01&porPagina=50"/v1/leads/:idreadA contact with its full record and the ID of its latest conversation.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/leads/ID_DEL_LEAD/v1/leads/:idwriteChanges a contact's status and/or notes (its record). Fires the lead.actualizado event.
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/mensajesreadThe messages of a conversation in chronological order. Each message says whether it was written by the customer, the assistant or a team member. Paginated (porPagina up to 200).
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/conversaciones/ID_CONVERSACION/mensajes/v1/citasreadAppointments in a date range (desde, hasta; the next 30 days by default; maximum 92 days). Status filter (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/citaswriteCreates an appointment for the business with the same validation as the dashboard: titulo and inicio are required, correo must be valid if present, and it returns 409 horario_ocupado if it overlaps another appointment. Sends the calendar invite (if there's an email) and schedules the WhatsApp reminders (if there's a contact). Fires 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/catalogoreadAll the products or services in the catalog, with price, stock and category. The internal cost is never exposed.
curl -H "Authorization: Bearer TU_LLAVE" https://asistentepro.cl/api/v1/catalogo/v1/catalogowriteReplaces the catalog with the list you send (up to 500 products). Matches by name: existing ones are updated, new ones are created and those not included become inactive (they aren't deleted: they keep their photo, order and featured flag). Fields: nombre (required), 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/mensajeswriteSends a text on WhatsApp to a contact, ONLY if the 24-hour window is open (the customer wrote less than 24 hours ago). If it's closed, it returns 409 ventana_cerrada and sends nothing: WhatsApp only accepts template messages outside that window. With pausarAsistente: true the assistant stops replying in that thread until someone releases it from the dashboard.
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/mensajesIn Integrations add your system's https URL and choose the events. Every time one happens, we send a POST with JSON to that URL. Your server must respond with a 2xx code in under 8 seconds; do the heavy work after responding.
| Event | When it's sent |
|---|---|
lead.creado | A new contact wrote for the first time, or was created from the dashboard or the API. |
lead.actualizado | A contact's status or record changed (by the assistant, the dashboard or the API). |
cita.creada | An appointment was booked (by the assistant, the dashboard or the API). |
cita.cancelada | An appointment was canceled or deleted. |
derivacion.creada | The assistant handed a conversation off to a person: the customer asked to talk to someone, a complaint, a question it couldn't resolve, or the AI service couldn't respond. |
mensaje.recibido | A message from a customer arrived on WhatsApp or Instagram. |
The body includes id (unique per notification and repeated on retries: use it to avoid processing twice), evento, fecha, negocioId and datos with the same shape the API returns.
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 event and shows you what your server responded. The last 20 deliveries and their status stay visible.When you create the webhook we give you a secret (only once). Every notification includes X-AsistentePro-Timestamp (unix seconds) and X-AsistentePro-Firma: the HMAC-SHA256, using your secret, of the text <timestamp>.<cuerpo>, in hexadecimal. Compute the same over the raw body you received and compare. Discard notifications older than 5 minutes.
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)
}| Answer | What it means |
|---|---|
401 llave_invalida | The key doesn't exist, is mistyped or was revoked. |
403 permiso_insuficiente | The key is read-only and the endpoint modifies data. |
403 cuenta_pausada | The business account is paused. |
404 no_encontrado | The ID doesn't exist in this account (IDs from other businesses always return 404). |
400 fecha_invalida / estado_invalido / faltan_datos / correo_invalido | Check the body or the filters; the message field explains what's missing. |
409 horario_ocupado | There's already an appointment at that time (citaId is included). |
409 ventana_cerrada | Non-template text can't be sent to that contact until they write again. |
429 rate_limited | More than 120 requests per minute with the same key. Wait as long as Retry-After says. |
Limit: 120 requests per minute per key (headers X-RateLimit-Limit and X-RateLimit-Remaining). Up to 10 active keys and 10 webhooks per business.
Need an endpoint that isn't here? Write to us from your dashboard: this first version covers what an external system actually uses and grows with what businesses ask for.